2013-05-01 2 views
1

Я пытаюсь понять взаимосвязь между итерацией и рекурсией, пытаясь смоделировать упрощенное выполнение тела операторов в пределах области {} на старом домашнем задании, которое у меня было. Предположим, у меня есть два типа операторов: while и оператор присваивания.«Выполнение» тела операторов без рекурсии

В настоящее время я предполагаю, что условие while while всегда верно. EDIT: Кроме того, предположим, что оператор пока только выполняет один раз (то есть, я бы назвал это, если заявление)

В рекурсии, это было бы просто:

executeBody(body) 
{ 
    for each stmt in body 
    { 
    switch (stmt) 
    { 
     case ASSIGNMENT: 
     // work 
     break; 

     case WHILE-STMT: 
     executeBody(whileStmt->body) 
     break; 
    } 
    } 
} 

Но я имея проблемы с этим для итерации. Я знаю, что мне нужно смоделировать стек, но я просто не могу концептуализировать, как выполнять все инструкции в инструкции while, прежде чем перейти к следующему утверждению. Вот модель того, что у меня есть:

executeBody(body) 
{ 
    for each stmt in body 
    { 
    case ASSIGNMENT: 
     // work 
     break; 

    case WHILE-STMT: 
    { 
     stack<body> stack; 
     stack.push(whileStmt->body);  
     while (stack isNotEmpty) 
     { 
      for each stmt (in each body) in stack 
      { 
      case ASSIGNMENT: 
       // work; 
       break; 

      case WHILE-STMT: 
       //stack.push(this_whileStmt->body); 
       // ???? 
       break; 
      } 
     } 
    } 
    } 
} 

EDIT: Изменен пример рекурсии, чтобы показать, что тело представляет собой последовательность операторов.

+0

- это итерационный psudo-код, который вы разместили правильно, или это ваш собственный код. –

+0

Его собственный код - это неверно, так как он не закончен. – Vance

+0

Я бы начал с 'while (cond) cmd', где cmd может быть выражением или блоком. Затем вы сохраняете стек кортежей cmd/cond/exec. Когда вы нажмете некоторое время, если cond, нажмите тройку. Стандартные блоки подталкивают ложный cond. Внешняя петля состоит в том, чтобы продвинуть состояние exec сверху на стек, получить cmd, handle. Если выполняется самое верхнее, проверьте состояние cond и pop или reset exec. – Yakk

ответ

2

Во-первых, я бы выбрал внешний контур. Это избыточно.

stack<body> stack; 
    stack.push(body);  
    while (stack isNotEmpty) 
    { 
     for each stmt (in stack.pop()) // pop the top statement off of your stack 
     { 
     case ASSIGNMENT: 
      // work; 
      stmt.Remove() 
      /*you don't need to break here. just go onto the next operation*/ 

     case WHILE-STMT: 
      stack.push(stmt->body); 
      stmt.Remove() 
      stack.push(stmt); 
      break; 
     } 

, как только вы попали в WHILE-STMT: случай, код будет перерыв и продолжить верхний элемент стека, который является блоком кода, который вы только что положили на там.

После того, как этот блок закончен, он будет удален из стека (вы делаете это в объявлении for), и он возобновится с вашим текущим блоком. Вся цель очистки текущих операторов и отталкивания рабочего блока обратно в стек предназначена для того, чтобы иметь возможность возобновить это.

+0

Я не вижу, как это правильно возобновляется после выполнения цикла. Что делает 'stmt.Remove()' do? – phant0m

+0

@ phant0m Кроме того, что он обрабатывает 'while statements' как простые« блоки кода »(точно так же, как рекурсивный пример OPs), что вы думаете, что происходит, когда оно возобновляется? –

+0

@ phant0m предполагается либо удалить инструкцию из блока. –

1

У вас есть стек в неправильном месте. Он должен быть объявлен в верхней части подпрограммы executeBody. Проверьте это:

executeBody(body) { 
    stack<body> work; 

    stack.push(body); 

    while (stack isNotEmpty) { 
     item = stack.pop(); 
     switch (item) { 
      case ASSIGNMENT: 
       // work; 
       break; 
      case WHILE-STMT: 
       stack.push(item); 
       break; 
     } 
    } 
} 

Этот псевдокод должен четко указывать, что все ваши тела входят в стек. Некоторые из них делают ASSIGNMENT, а некоторые делают WHILE.

+1

в WHILE_STMT, он должен читать stack.push (item-> body), иначе он превратится в бесконечный цикл. –

+0

Небольшое изменение: вам понадобится цикл для итеративного нажатия элементов while-stmt в стек. – SuperSaiyan

+0

Исходный второй фрагмент кода предполагает, что 'body' представляет собой последовательность операторов. Ваш код не делает на нем никакой итерации, что-то не так. – phant0m

Смежные вопросы