簡體   English   中英

Sudoku求解器在C中崩潰

[英]Sudoku solver in c crashes

我試圖找出我的代碼出了什么問題,該代碼應該可以解決9x9數獨問題,當我使用sudoku的Wikipedia中的示例運行它時會崩潰。

我也嘗試過使用遞歸,但是對它不是很熟悉,因此它也不起作用。

  • findunassignedlocation返回1 ,如果仍有數獨和0 0 ,如果沒有更多的0。
  • 如果所有行,列和3x3網格均不包含數字,則isSafe返回1否則返回0

如果問題可能出在其他功能之一上,請告訴我,我將發送代碼。 忽略depth變量。

下面是我的代碼:

/* Returns an int which indicates whether if the sudoku has any
   more empty entries (which shows as a 0) */
int FindUnassignedLocation(int grid[9][9]) { 
    for (int row = 0; row < 9; row++) 
        for (int col = 0; col < 9; col++) 
            if (grid[row][col] == 0) 
                return 1; 
    return 0; 
}

/* Returns an int which indicates whether an assigned entry 
   in the specified row matches the given number. */
int UsedInRow(int grid[9][9], int row, int num) { 
    for (int col = 0; col < 9; col++) 
        if (grid[row][col] == num) 
            return 1; 
    return 0; 
} 

/* Returns an int which indicates whether an assigned entry 
   in the specified column matches the given number. */
int UsedInCol(int grid[9][9], int col, int num) { 
    for (int row = 0; row < 9; row++) 
        if (grid[row][col] == num) 
            return 1; 
    return 0; 
} 

/* Returns an int which indicates whether an assigned entry 
   within the specified 3x3 box matches the given number. */
int UsedInBox(int grid[9][9], int boxStartRow, int boxStartCol, int num) { 
    for (int row = 0; row < 3; row++) 
        for (int col = 0; col < 3; col++) 
            if (grid[row + boxStartRow][col + boxStartCol] == num) 
                return 1; 
    return 0; 
} 

/* Returns an int which indicates whether it will be legal to assign 
   num to the given row,col location. */
int isSafe(int grid[9][9], int row, int col, int num) { 
    /* Check if 'num' is not already placed in current row, 
       current column and current 3x3 box */
    if (!UsedInRow(grid, row, num) && 
        !UsedInCol(grid, col, num) && 
        !UsedInBox(grid, row - row % 3, col - col % 3, num) && 
        grid[row][col] == 0) {
        return 1;
    } else {
        return 0;
    }
} 

void solve_sudoku(int sudoku[9][9]) {
    int row = 0;
    int col = 0;
    if (FindUnassignedLocation(sudoku) == 0) { //if sudoku is completely filled
        return;
    }
    for (int num = 1; num <= 9; num++) {
        if (isSafe(sudoku, row, col, num) == 1) {
            sudoku[row][col] = num;
            solve_sudoku(sudoku, depth);
            sudoku[row][col] = 0;
        }
    }
}

一種簡單的方法(但由於對稱/旋轉而並非最有效)是嘗試所有嘗試將數字1最多放置到9的連續位置(0,0 0,1 .. 0,8 1,0。 ..)遞歸地,每次將數字放在8,8上都是一個解決方案

您的代碼幾乎不需要更改,只需刪除無用的FindUnassignedLocation並添加遞歸

如果我用SZ替換9以也能夠搜索大小3、6或9,然后添加解決方案的代碼,則代碼可以是:

#include <stdio.h>

// 3, 6 or 9
#define SZ 9

/* Returns an int which indicates whether an assigned entry 
   in the specified row matches the given number. */
int UsedInRow(int grid[][SZ], int row, int num) 
{ 
  for (int col = 0; col < SZ; col++)
    if (grid[row][col] == num) 
      return 1; 

  return 0; 
} 

/* Returns an int which indicates whether an assigned entry 
   in the specified column matches the given number. */
int UsedInCol(int grid[][SZ], int col, int num) 
{ 
  for (int row = 0; row < SZ; row++) 
    if (grid[row][col] == num) 
      return 1; 

  return 0; 
} 

/* Returns an int which indicates whether an assigned entry 
   within the specified 3x3 box matches the given number. */
int UsedInBox(int grid[][SZ], int boxStartRow, int boxStartCol, int num) { 
  for (int row = 0; row < 3; row++) 
    for (int col = 0; col < 3; col++) 
      if (grid[row + boxStartRow][col + boxStartCol] == num) 
        return 1; 

  return 0; 
} 


/* Returns an int which indicates whether it will be legal to assign 
   num to the given row,col location. */
int isSafe(int grid[][SZ], int row, int col, int num) 
{ 
  /* Check if 'num' is not already placed in current row, 
     current column and current 3x3 box */
  return (!UsedInRow(grid, row, num) && 
          !UsedInCol(grid, col, num) && 
          !UsedInBox(grid, row - row % 3, col - col % 3, num));
} 

/* print a solution */
void draw(int sudoku[][SZ])
{
  for (int row = 0; row != SZ; ++row) {
    for (int col = 0; col != SZ; ++col)
      printf("%d", sudoku[row][col]);
    putchar('\n');
  }
  putchar('\n');
}

void solve_sudoku(int sudoku[][SZ], int row, int col)
{
  for (int num = 1; num <= 9; num++) { //loop through numbers 1 to SZ
    if (isSafe(sudoku, row, col, num) == 1) { //the number is safe
      sudoku[row][col] = num;
      if ((col + 1) == SZ) {
        if ((row + 1) == SZ) {
          // done
          draw(sudoku);
        }
        else
          solve_sudoku(sudoku, row + 1, 0);
      }
      else
        solve_sudoku(sudoku, row, col + 1);
      sudoku[row][col] = 0;
    }
  }
}

int main()
{
  int sudoku[SZ][SZ] = {0};

  solve_sudoku(sudoku, 0, 0);
}

SZ 3的第一個解決方案(362880個可能的解決方案):

123
456
789

123
456
798

123
456
879

123
456
897

123
456
978

123
456
987

123
457
689

發現SZ 6的第一個解決方案:

123456
456789
789123
214365
365897
897214

123456
456789
789123
214365
365897
897241

123456
456789
789123
214365
365897
978214

123456
456789
789123
214365
365897
978241

123456
456789
789123
214365
365978
897214

123456
456789
789123
214365
365978
897241

發現SZ 9的第一個解決方案

123456789
456789123
789123456
214365897
365897214
897214365
531642978
642978531
978531642

123456789
456789123
789123456
214365897
365897214
897214365
531642978
648971532
972538641

123456789
456789123
789123456
214365897
365897214
897214365
531642978
672938541
948571632

123456789
456789123
789123456
214365897
365897214
897214365
531642978
678931542
942578631

123456789
456789123
789123456
214365897
365897214
897214365
531642978
942578631
678931542

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM