简体   繁体   English

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

[英]Returning array in C, Sudoku Solver

So I'm creating a sudoku solver in C. Here's my full code as of now, I've mostly been using python and just got into C, I basically converted a lot of python functions to C to get this but I think it'll work: 因此,我在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;
    }
}

My main issue when compiling is getting the last two functions work with each other. 我在编译时的主要问题是使最后两个函数相互配合。

Function 'solver' calls and binds function 'possible_v'. 函数“ solver”调用并绑定函数“ possible_v”。 Possible_V returns an array which I need to solve the puzzle. Possible_V返回一个数组,我需要解决这个难题。 How can I make this work? 我该如何进行这项工作? .

You have the array locally declared, hence it cannot be passed back since it is destroyed once the function is exited. 您已经在本地声明了数组,因此无法将其传递回,因为一旦退出函数,该数组将被销毁。 The workaround to this is to dynamically declare the array using malloc int *parray = (int*)malloc(9*sizeof(int)); 解决方法是使用malloc int *parray = (int*)malloc(9*sizeof(int));动态声明数组int *parray = (int*)malloc(9*sizeof(int)); and using the return type int* instead of int . 并使用返回类型int*而不是int But do not forget to free the allocated memory, else you will just keep allocating new memory from heap for every call you make. 但是不要忘记释放分配的内存,否则您将继续为每次调用从堆中分配新内存。

As a side note, your implementation of Sudoku solver is a bit complex, and there is no need to return an array. 附带说明一下,您的Sudoku求解器的实现有点复杂,不需要返回数组。 You need to pass only the board. 您只需要通过董事会。 Here is an implementation of Sudoku Solver. 这是Sudoku Solver的实现。 This works both for 9x9 and 6X6 boards. 这适用于9x9和6X6电路板。

Edit : As advised by David Rankin, I have converted the C++ code to C. 编辑 :根据大卫兰金的建议,我已经将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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM