使用堆栈将递归实现转换为迭代实现

时间:2018-08-11 12:17:08

标签: c recursion stack sudoku c89

我想编写一个函数,该函数将计算给定Sudoku板的可能解决方案的数量。

此外,我希望可以使用堆栈将其实现为迭代解决方案。

我发现this recursive solution是用Java实现的,并且我已经用C编写了它(它首先用countSolutionsRec(board, 0, 0, 0)进行了调用,其中board是代表Sudoku棋盘游戏的2D整数数组) ):

int countSolutionsRec(int board[9][9], int i, int j, int counter) {
  int value;
  if (i == 9) {
    i = 0;
    if (++j == 9){
        return 1+counter;
    }
  }
  if (board[i][j] != 0){
    return countSolutionsRec(board, i+1, j, counter);
  }
  for (value = 1; value <= 9; ++value) {
    if (validCheck(board, j, i, value)){ //This function checks if the value is a legal value to place in board[i][j] according to sudoku rules
        board[i][j]= value;
        counter = countSolutionsRec(board, i+1, j, counter);
    }
  }
  board[i][j] = 0;
  return counter;
}

然后,我尝试遵循this guide将上述代码转换为使用堆栈的迭代实现,这就是我想出的:

int countSolutions(int board[9][9]) {

  int returnValue, value;

  SnapShotStruct newSnapshot;

  StackNode* snapshotStack;

  SnapShotStruct currentSnapshot;
  currentSnapshot.i = 0;
  currentSnapshot.j = 0;
  currentSnapshot.counter = 0;

  push(&snapshotStack, currentSnapshot);

  while (!empty(snapshotStack)) {
    currentSnapshot=top(snapshotStack);
    pop(&snapshotStack);
    if (currentSnapshot.i == 9){
        currentSnapshot.i = 0;
        if (++currentSnapshot.j == 9) {
            returnValue = currentSnapshot.counter + 1;
            continue;
        }    
    }
    if (board[currentSnapshot.i][currentSnapshot.j] != 0) {
        newSnapshot.i = currentSnapshot.i + 1;
        newSnapshot.j = currentSnapshot.j;
        newSnapshot.counter = currentSnapshot.counter;
        push(&snapshotStack, newSnapshot);
        continue;
    }
    for (value = 1; value <= 9; ++value) {
        if (validCheck(board, currentSnapshot.j, currentSnapshot.i, value)){
            board[currentSnapshot.i][currentSnapshot.j] = value;
            newSnapshot.i = currentSnapshot.i + 1;
            newSnapshot.j = currentSnapshot.j;
            newSnapshot.counter = returnValue;
            push(&snapshotStack, newSnapshot);
            continue;
        }
    }
    board[currentSnapshot.i][currentSnapshot.j] = 0;
  }
  return returnValue;
}

我的堆栈实现:

typedef struct SnapShotStruct {
   int i;        
   int j;
   int counter;   
   int stage;
} SnapShotStruct;

typedef struct StackNode {
  struct SnapShotStruct snapshot;
  struct StackNode* next;
} StackNode;

StackNode* newNode(SnapShotStruct snapshot) {
  StackNode* stackNode = (StackNode*) malloc(sizeof(StackNode));
  stackNode->snapshot.i = snapshot.i;
  stackNode->snapshot.j = snapshot.j;
  stackNode->snapshot.counter = snapshot.counter;
  stackNode->snapshot.stage = snapshot.stage;
  stackNode->next = NULL;
  return stackNode;
}

int empty(StackNode *root) {
  return !root;
}

void push(StackNode** root, SnapShotStruct snapshot) {
  StackNode* stackNode = newNode(snapshot);
  stackNode->next = *root;
  *root = stackNode;
}

SnapShotStruct pop(StackNode** root) {
  SnapShotStruct popped;
  StackNode* temp = *root;
  if (empty(*root))
    return popped;
  *root = (*root)->next;
  popped = temp->snapshot;
  free(temp);
  return popped;
}

SnapShotStruct top(StackNode* root) {
  SnapShotStruct snapshot;
  if (empty(root))
    return snapshot;
  snapshot = root->snapshot;
  return snapshot;
}

问题在于,迭代实现会导致错误的结果。

我认为问题是我转换了以下行的方式:

counter = countSolutionsRec(board, i+1, j, counter);

但是我不确定如何解决它并获得迭代实现以返回正确的结果。

感谢您的帮助。

0 个答案:

没有答案