#loops #do-loops #rexx #oorexx
#циклы #циклы выполнения #rexx #oorexx
Вопрос:
По какой-то причине мой цикл Rexx прерывается, и я не знаю почему. Я пытаюсь выполнить поиск в базе данных телефонных номеров по ICCID (идентификационный номер для sim-карт) и получить номер телефона. Вот цикл, который у меня есть, немного упрощенный:
(t) is the tab hex code, ICCIDlist.txt contains a list of ICCIDs I'm trying to gather info on
and phonenumberinfo.txt an exhaustive list of ICCIDs and Phone Numbers, looking something like this:
89298374987 409-392-2434
89298765345 409-365-2132
89298334745 409-967-2863
----------------------------------------------
streamICCID=.stream~new('iccidList.txt')
lni = streamICCID~lines
DO i = 1 to lni
ICCID.i = streamICCID~linein(i)
END
soFile=.stream~new('phonenumberinfo.txt')
lno = soFile~lines
DO line = 1 to lno
lnInfo = soFile~linein(line)
lnFind = POS(ICCID.i,lnInfo)
IF lnFind==1 THEN DO
PARSE VAR lnInfo ICCID (t) ownNum.i
i = i 1; ITERATE
END
ELSE ITERATE
END
DO n = 1 to i
SAY ownNum.n
END
Это работает для первого, но как только он извлекает номер телефона из первого ICCID, он ломается. Мне нужно, чтобы это продолжалось, пока не будут выполнены все ICCID. кто-нибудь может мне помочь?
Комментарии:
1. Я предлагаю вам сделать: I = 1 для lni, а не i = 1 для lno и где ваш вывод трассировки? Вы запустили его с трассировкой?
Ответ №1:
Вы правы, это будет работать только при поиске одного ICCID — последнего. Как говорит NicC, вы, вероятно, поймете это, если поставите Trace Intermediate
(или просто Trace I
) инструкцию прямо перед своим do line = ...
циклом. Это покажет вам, что вы входите в этот цикл с i
установленным номером последнего прочитанного ICCID, и вы начинаете отсчет оттуда ( i=i 1; ITERATE
).
В других языках такого рода проблема поиска обычно решается с помощью двух вложенных циклов. После загрузки первого набора данных вы выполняете итерацию по второму, и для каждой записи вы выполняете итерацию по всему первому набору данных, проверяя совпадение. Вы этого не делаете, вы вручную пишете внутренний цикл и используете его переменную index ( i
) для двух разных и противоречивых целей (перебор первого набора данных и создание выходного набора данных).
В Rexx мы бы этого не сделали (хотя могли). Вместо этого мы решили бы эту проблему, загрузив первый набор данных в ассоциативный массив, а затем напрямую обратившись к нему во время итерации по второму набору данных. Это превращает алгоритм порядка N в квадрат порядка N для получения большого выигрыша.
/* Load the ICCIDs into the "ICCID.*" associative array. The value of
each element we load is TRUE, and the value of anything else is FALSE.
*/
ICCIDlist. = 0 /* Set all the elements to FALSE */
streamICCID=.stream~new('iccidList.txt')
DO i = 1 to streamICCID~lines
item = streamICCID~linein(i)
ICCIDlist.item = 1 /* Set this element to TRUE */
END
/* Search the phone number file for ICCIDs we loaded above and record their presence. */
soFile=.stream~new('phonenumberinfo.txt')
lno = 0
DO line = 1 to soFile~lines
lnInfo = soFile~linein(line)
PARSE VAR lnInfo ICCID (t) phoneNumber
IF ICCIDlist.ICCID THEN DO /* If the ICCIDlist element is TRUE, it was in the first dataset */
lno = lno 1
ownNum.lno = phoneNumber
END
END
/* Write out the phone numbers for the ICCIDs that we found in both datasets. */
DO n = 1 to lno
SAY ownNum.n
END
Комментарии:
1. Большое спасибо, Росс, это не только работает, я это понимаю, и это намного проще.
2. Добро пожаловать в StackOverflow! Не пытайтесь принимать ответы, которые являются лучшими.