Остановить завершение цикла Rexx Do

#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! Не пытайтесь принимать ответы, которые являются лучшими.