用C,数独求解器返回数组

时间:2018-10-27 03:45:43

标签: c

所以我正在C中创建一个数独求解器。到目前为止,这是我的完整代码,我主要是使用python并刚进入C,我基本上将很多python函数转换为C来实现,但我认为会起作用:

#include <stdio.h>
#include <stdlib.h>

int is_empty();
int possible_v();
int solver();

int main(){
    int s_array[9][9];
    FILE * fpointer;
    int i;
    int j;

    fpointer = fopen("sudoku001.txt", "r");

    for (i=0; i<9; i++){
        for(j = 0; j<9; j++){
            fscanf(fpointer, "%d", &s_array[i][j]);
        }
    }

    for (i=0; i<9; i++) {
        if (i % 3 == 0) {
            printf("------------------------------\n");
        }

        for (j = 0; j < 9; j++) {
            printf(" %d ", s_array[i][j]);
            if ((j + 1) % 3 == 0) {
                printf("|");
            }
        }
        printf("\n");
    }



    solver(s_array);

    for (i=0; i<9; i++) {
        if (i % 3 == 0) {
            printf("------------------------------\n");
        }

        for (j = 0; j < 9; j++) {
            printf(" %d ", s_array[i][j]);
            if ((j + 1) % 3 == 0) {
                printf("|");
            }
        }
        printf("\n");
    }
    return 0;


}

int is_empty(int board[9][9]){
    int i;
    int j;
    int is_empty= 0;
    for (i=0; i<9; i++){
        for(j = 0; j<9; j++){
            if (board[i][j] == 0) {
                is_empty = 1;
                break;
            }
        }
        if (is_empty == 1){
            break;
        }
    }
    return is_empty;
}

int possible_v(int board[9][9], int i, int j) {
    int p_array[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
    int x;
    int y;
    int temp;

    for (x = 0; x < 9; x++) {
        if (board[x][j] != 0) {
            temp = board[x][j];
            p_array[temp - 1] = temp;
        }
    }
    for (y = 0; y < 9; y++) {
        if (board[i][y] != 0) {
            temp = board[i][y];
            p_array[temp - 1] = temp;
        }
    }

    int m;
    int n;
    int temp1;
    int temp2;
    if (i>= 0 && i <= 2) {
        m = 0;
    }
    else if (i>= 3 && i<=5) {
        m = 3;
    }
    else{
        m = 6;
    }

    if (j>= 0 && j <= 2) {
        n = 0;
    }
    else if (j>= 3 && j<=5) {
        n = 3;
    }
    else{
        n = 6;
    }

    temp1 = m;
    temp2 = n;

    for (temp1; temp1<temp1+3; temp1++){
        for (temp2; temp2<temp2+3; temp2++){
            if (board[temp1][temp2] != 0){
                p_array[board[temp1][temp2]] = 1;
            }
        }
    }
    temp1 = 1;
    for (temp1; temp1<10){
        if (p_array[temp1] == 0){
            p_array[temp1] = temp1;
        }
        else{
            p_array[temp1] = 0;
        }
    }
    return p_array;
}

int solver(int board[9][9]){
    int i;
    int j;
    int x;
    int y;
    int empty_check;
    int p_values;
    int temp;

    if (is_empty(board) == 0){
       printf("Board Completed");
       empty_check = 0;
       return empty_check;
    }
    else{
        for (x = 0; x < 9; x++){
            for (y = 0; y< 9; y++){
                if (board[x][y] == 0){
                    i = x;
                    j = y;
                    break;
                }
            }
        }
        p_values = possible_v(board, i, j);

        for (temp = 1; temp <10; temp++){
            if (p_values[temp] != 0){
                board[i][j] = p_values[temp];
                solver(board);
            }
        }
        board[i][j] = 0;
    }
}

编译时,我的主要问题是使最后两个函数相互配合。

函数“求解器”调用并绑定函数“ possible_v”。 Possible_V返回一个数组,我需要解决这个难题。我该如何进行这项工作?

1 个答案:

答案 0 :(得分:0)

您已经在本地声明了数组,因此一旦传递函数退出,它将被销毁,因此无法传递回该数组。解决方法是使用malloc int *parray = (int*)malloc(9*sizeof(int));并使用返回类型int*而不是int动态声明数组。但是不要忘记释放已分配的内存,否则您将继续为每次调用从堆中分配新内存。

请注意,您的Sudoku求解器的实现有点复杂,不需要返回数组。您只需要通过董事会。这是Sudoku Solver的实现。这适用于9x9和6X6电路板。

编辑:根据David Rankin的建议,我已将C ++代码转换为C。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int n;

int issafe(int **board,int i,int j,int num){

  for(int k=0;k<n;k++)
    if(board[i][k] == num || board[k][j] == num)
     return 0;

  int cellx,celly;
  if(n==6){

   cellx = (i/2)*2;
   celly = (j/3)*3;

   for(int l=cellx;l<cellx+2;l++)
     for(int m=celly;m<celly+3;m++)
      if(board[l][m] == num){
        return 0;
      }

   return 1;
 }

 int root = sqrt(n);
 cellx = (i/(root))*root;
 celly = (j/(root))*root;

 for(int l=cellx;l<cellx+root;l++)
  for(int m=celly;m<celly+root;m++)
    if(board[l][m] == num)
     return 0;

 return 1;
}

int solve(int **board,int i,int j){

  if(i == n)
    return 1;

  if(j == n){
    return solve(board,i+1,0);
  }

  if(board[i][j] != 0)
    return solve(board,i,j+1);

  for(int k=1;k<n+1;k++)
    if(issafe(board,i,j,k)){
      board[i][j] = k;
      if(solve(board,i,j+1))
        return 1;
      //backtrack
      board[i][j] = 0;
    }

  return 0;
}

int main(){

  do{
    printf("Enter size of board(9 or 6): ");
    scanf("%d",&n);
  }while(n != 9 && n != 6);

  int **board;
  board = malloc(sizeof *board * n);
  for(int i=0;i<n;i++)
    board[i] = malloc(sizeof *board * n);

  // input
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      scanf("%d",&board[i][j]);

  if(solve(board,0,0))
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++)
        printf("%d ",board[i][j]);
      printf("\n");
    }
  return 0;
}