簡體   English   中英

用C,數獨求解器返回數組

[英]Returning array in C, Sudoku Solver

因此,我在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;
    }
}

我在編譯時的主要問題是使最后兩個函數相互配合。

函數“ solver”調用並綁定函數“ possible_v”。 Possible_V返回一個數組,我需要解決這個難題。 我該如何進行這項工作?

您已經在本地聲明了數組,因此無法將其傳遞回,因為一旦退出函數,該數組將被銷毀。 解決方法是使用malloc int *parray = (int*)malloc(9*sizeof(int));動態聲明數組int *parray = (int*)malloc(9*sizeof(int)); 並使用返回類型int*而不是int 但是不要忘記釋放分配的內存,否則您將繼續為每次調用從堆中分配新內存。

附帶說明一下,您的Sudoku求解器的實現有點復雜,不需要返回數組。 您只需要通過董事會。 這是Sudoku Solver的實現。 這適用於9x9和6X6電路板。

編輯 :根據大衛蘭金的建議,我已經將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