Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的数独解算器。程序在某些情况下停止,我不';我不知道为什么_C_Sudoku_Backtracking_Solver - Fatal编程技术网

C中的数独解算器。程序在某些情况下停止,我不';我不知道为什么

C中的数独解算器。程序在某些情况下停止,我不';我不知道为什么,c,sudoku,backtracking,solver,C,Sudoku,Backtracking,Solver,我正在为一个解决数独难题的类编写一个c语言程序。我们应该实现三种方法,首先在只有一个可能选择的每个正方形中放置正确的数字,重复直到找不到为止。接下来,它使用蛮力,在每个正方形中放置尽可能少的数字。我有这两种方法。最后一种方法是带回溯的蛮力,这是蛮力函数的一部分。它的工作原理与普通蛮力相同,不同的是,它到达一个不能在其中放置数字的正方形时,移动到前一个正方形并放置下一个最高的数字。一旦这是实施这应该解决所有给定的数独难题,但这是我有麻烦的地方 我已经实现了所有这三种方法,并且给我们提供了不同的数独

我正在为一个解决数独难题的类编写一个c语言程序。我们应该实现三种方法,首先在只有一个可能选择的每个正方形中放置正确的数字,重复直到找不到为止。接下来,它使用蛮力,在每个正方形中放置尽可能少的数字。我有这两种方法。最后一种方法是带回溯的蛮力,这是蛮力函数的一部分。它的工作原理与普通蛮力相同,不同的是,它到达一个不能在其中放置数字的正方形时,移动到前一个正方形并放置下一个最高的数字。一旦这是实施这应该解决所有给定的数独难题,但这是我有麻烦的地方

我已经实现了所有这三种方法,并且给我们提供了不同的数独难题示例,一些可以只使用第一种“单选”方法解决,一些可以只使用“单选”和“不回溯的蛮力”解决,还有一些使用“单选”和“带回溯的蛮力”解决。我的程序既可以处理“单选”难题,也可以处理“单选”和“没有回溯的暴力”难题。然而,它不适用于“单一选择”和“回溯暴力”难题

奇怪的是,我不明白,对于回溯谜题,程序甚至在调用蛮力函数之前就停止工作了

以下是我的主要功能:

#include <stdio.h>
#include "sudokusolver.h"
int main()
{
   int puzzle[9][9], i, j, count, attempts=0, backTracks=0;
   readSudoku(puzzle);
   printf("a\n");
   do
   {
      count=0;
      for(i=0;i<9;i++)
      {
         for(j=0;j<9;j++)
         {
            if(singleCandidate(puzzle, i, j)==1)
               count++;
         }
      }
   }while(count!=0);
   bruteForce(puzzle, &attempts, &backTracks);
   printSudoku(puzzle);
   return 0;
}
这里有一个输出不起作用的例子。这是一个必须使用“单选”和“回溯暴力”解决的示例难题:

程序继续运行,就好像它在一个无限循环中,^C代表我退出程序一样。正如你所看到的,这个程序甚至从来没有到达它在数独游戏中读取的正下方的printf(“a”),甚至在它调用“带回溯的蛮力”函数之前,这很奇怪,因为只有那些需要带回溯的蛮力的游戏才不起作用

下面是readSudoku函数,它似乎被卡住了:

void readSudoku(int puzzle[][9])
{
   int i, j;
   for(i=0;i<9;i++)
   {
      printf("Enter line %d: ", i+1);
      for(j=0;j<9;j++)
      {
         scanf("%1d", &puzzle[i][j]);
      }
   }
}
void readSudoku(int-puzzle[][9])
{
int i,j;

对于(i=0;i我猜问题可能出在
singleCandidate()
中。我看不到它的源代码,但您应该验证它在不改变谜题时不返回1,因为这会导致无休止的循环


同时检查当您获得无效输入时(即数独没有解决方案时)它的行为。

在您的
bruteForce
中,您有

/* No legal guess found, so backtrack */
while(puzzle[i][j]==0)
{
    /* Find previous guessed position */
    /* the last guess was as puzzle[i][j] */
    temp=puzzle[i][j]+1;
    for(k=temp;k<9;k++)
    {
        if(checkValid(puzzle, i, j, k+1)==1)
        {
            found=1;
            puzzle[i][j]=k+1;
            break;
        }
    }
    if(found==0)
       puzzle[i][j]=0;
}
然后访问
谜题[-1][-1]
,调用未定义的行为

如果不幸的是,无效的内存访问没有导致崩溃(看起来是这样的),那么可能是
checkValid(-1,-1,k+1)
对某些
k
返回
1
,然后您开始再次尝试解决这个难题,进入相同的循环


不可否认的是,<代码> PROTF(“A\N”);应该打印出<代码> A <代码>,如果终端被设置为正常缓冲模式,但我认为打印缓冲区不可能比“<代码> > ReSudiukU/CODE >更神奇地检测需要回溯并拒绝对它们进行处理的谜题。(可能是“a”已缓冲,因此不显示。请在

printf
之后尝试
fflush(stdout);
)@missingno:你不应该编辑标记…@HotLicks这不太可能,因为stdout是用每一个换行符刷新的,但这仍然是一件值得尝试的事情。问题不是添加标记是错误的…但是添加应该来自OP…我被告知…在调试器中运行程序,并逐步完成代码一然后你可以检查变量,检查循环中的条件等等。
void readSudoku(int puzzle[][9])
{
   int i, j;
   for(i=0;i<9;i++)
   {
      printf("Enter line %d: ", i+1);
      for(j=0;j<9;j++)
      {
         scanf("%1d", &puzzle[i][j]);
      }
   }
}
void bruteForce(int puzzle[][9], int *attempt, int *backtracks)
{
   int stable[9][9], i, j, k, found=0, temp=0;
   for(i=0;i<9;i++)
   {
      for(j=0;j<9;j++)
      {
         if(puzzle[i][j]==0)
            stable[i][j]=0;
         else
            stable[i][j]=1;
      }
   }
   for(i=0;i<9;i++)
   {
      for(j=0;j<9;j++)
      {
         for(k=0;k<9;k++)
         {
            if(checkValid(puzzle, i, j, k+1)==1)
            {
               puzzle[i][j]=k+1;
               break;
            }
            if(k==8)
               break;
         }

         while(puzzle[i][j]==0)
         {
            found=0;
            temp=j-1;
            for(j=temp;j>=0;j--)
            {
               if(stable[i][j]==0)
               {
                  found=1;
                  break;
               }
            }
            temp=i-1;
            if(found==0)
            {
               for(i=temp;i>=0;i--)
               {
                  for(j=8;j>=0;j--)
                  {
                     if(stable[i][j]==0)
                     {
                        found=1;
                        break;
                     }
                  }
               if(found==1)
                  break;
               }
            }
            found=0;
            temp=puzzle[i][j]+1;
            for(k=temp;k<9;k++)
            {
               if(checkValid(puzzle, i, j, k+1)==1)
               {
                  found=1;
                  puzzle[i][j]=k+1;
                  break;
               }
            }
            if(found==0)
               puzzle[i][j]=0;
         }
      }
   }
}
/* No legal guess found, so backtrack */
while(puzzle[i][j]==0)
{
    /* Find previous guessed position */
    /* the last guess was as puzzle[i][j] */
    temp=puzzle[i][j]+1;
    for(k=temp;k<9;k++)
    {
        if(checkValid(puzzle, i, j, k+1)==1)
        {
            found=1;
            puzzle[i][j]=k+1;
            break;
        }
    }
    if(found==0)
       puzzle[i][j]=0;
}
found=0;
temp=j-1;
for(j=temp;j>=0;j--)
{
    if(stable[i][j]==0)
    {
        found=1;
        break;
    }
}
// Here, j == -1
 temp=i-1;
 if(found==0)
 {
     // if i == 0
     for(i=temp;i>=0;i--)
     {
     // i is set to -1 and the loop ends right now, with i == -1 and j == -1
     // if i was > 0, j is decremented from 8 to -1 for all i down to 0 in the inner loop
         for(j=8;j>=0;j--)
         {
             if(stable[i][j]==0)
             {
                 found=1;
                 break;
             }
         }
         if(found==1)
             break;
         // i is finally set to -1, with j still -1
     }
 }
 found=0;
 temp=puzzle[i][j]+1;