完成实验的代码内容

main
Li Yanxiao 1 year ago
parent 6b48a3068f
commit 020940d788

4
.gitignore vendored

@ -0,0 +1,4 @@
.DS_Store
*.o
.vscode
SudokuMatrix

@ -0,0 +1,66 @@
#include "SudokuMatrix.h"
#include <stdio.h>
bool JudgeMatrix(SudokuMatrix* matrix){
printf("The original Sudoku matrix: \n");
PrintMatrix(matrix);
bool result = true;
// 检查每一行
// 原理: 用一个长度为9的数组记录每个数字出现的次数
// 如果某个数字出现了两次,那么这个数独矩阵就不符合要求
// 以下检查列和九宫格的原理相同。
for (int i=0;i<9;i++){
int row[9] = {0};
for (int j=0;j<9;j++){
row[matrix->matrix[i][j]-1]++;
}
for (int j=0;j<9;j++){
if (row[j] > 1){
printf("False:Invalid initial Sudoku matrix!\n");
printf("The number %d in the row %d has been used!\n", j+1, i+1);
return false;
}
}
}
// 检查每一列
for (int i=0;i<9;i++){
int column[9] = {0};
for (int j=0;j<9;j++){
column[matrix->matrix[j][i]-1]++;
}
for (int j=0;j<9;j++){
if (column[j] > 1){
printf("False:Invalid initial Sudoku matrix!\n");
printf("The number %d in the col %d has been used!\n", j+1, i+1);
return false;
}
}
}
// 检查每一个 3x3 的矩阵
for (int i=0;i<3;i++){
for (int j=0;j<3;j++){
int block[9] = {0};
for (int k=0;k<3;k++){
for (int l=0;l<3;l++){
block[matrix->matrix[i*3+k][j*3+l]-1]++;
}
}
for (int k=0;k<9;k++){
if (block[k] > 1){
printf("False:Invalid initial Sudoku matrix!\n");
printf("The number %d in the block %d has been used!\n", k+1, i*3+j+1);
return false;
}
}
}
}
if (result){
printf("True:Valid initial Sudoku matrix!\n");
}
return result;
}

@ -0,0 +1,23 @@
SudokuMatrix: PrintMatrix.o main.o SudokuMatrix.o RandomMatrix.o JudgeMatrix.o SolveMatrix.o
gcc -o SudokuMatrix main.o PrintMatrix.o SudokuMatrix.o RandomMatrix.o JudgeMatrix.o SolveMatrix.o
main.o: main.c SudokuMatrix.o
gcc -c -o main.o main.c
PrintMatrix.o: PrintMatrix.c SudokuMatrix.o
gcc -c -o PrintMatrix.o PrintMatrix.c
RandomMatrix.o: RandomMatrix.c SudokuMatrix.o
gcc -c -o RandomMatrix.o RandomMatrix.c
JudgeMatrix.o: JudgeMatrix.c SudokuMatrix.o
gcc -c -o JudgeMatrix.o JudgeMatrix.c
SolveMatrix.o: SolveMatrix.c SudokuMatrix.o
gcc -c -o SolveMatrix.o SolveMatrix.c
SudokuMatrix.o : SudokuMatrix.h SudokuMatrix.c
gcc -c -o SudokuMatrix.o SudokuMatrix.c
clean:
rm -rf *.o SudokuMatrix

@ -0,0 +1,21 @@
#include "SudokuMatrix.h"
#include <stdio.h>
void PrintMatrix(SudokuMatrix *matrix){
for (int i=0;i<9;i++){
if (i == 0 || i == 3 || i == 6){
printf("|-----------------------------|\n");
}
for (int j=0;j<9;j++){
if (j == 0 || j == 3 || j == 6){
printf("|");
}
printf(" %d ",matrix->matrix[i][j]);
}
// 打印最后一列的竖线
printf("|\n");
}
// 打印尾巴那行
printf("|-----------------------------|\n");
}

@ -1,2 +1,38 @@
# SudokuMatrix # SudokuMatrix
> 程序设计基础:数独矩阵实验
>
> 作者:李彦筱
由于教学资料中没有实验报告的模版,暂时只提交说明性文件。
## 程序运行
### 类 Unix 系统macOS, Linux
- 确保您的系统已经安装了 gcc 与 make
- 在终端中打开作业所在文件夹,输入 `make` 即可编译
- 输入 `./SudokuMatrix` 即可运行程序
> 输入 `make clean` 可以清除已编译的文件,只留源代码
### Windows 下Visual Studio中运行
暂时待补充。
## 程序内容
`main.c` 中包含了 `testRandomMatrix`, `testJudgeMatrix`, `testSolveMatrix` 三个测试函数。在主函数中分别调用每一个函数,即可查看该部分的测试效果。
`testRandomMatrix` 测试了程序生成随机数独矩阵的能力。请注意,由于题目描述要求,生成的随机数独矩阵甚至不一定满足 `judgeMatrix` 对数独矩阵的要求
> `judgeMatrix` 中要求数独矩阵的列不能有重复的数字;但 `randomMatrix` 生成矩阵的要求不包含这点,导致生成的矩阵绝大部分都不满足要求
`testJudgeMatrix` 测试了程序判断数独矩阵是否有效的能力。数独矩阵有效,仅当它每一行、每一列、每个九宫格内没有重复的两个数字。
`testSolveMatrix` 测试了程序对三个预定义矩阵的求解能力。这个函数需要你传递 02 的一个整数作为参数,以便指定你要用哪个预定义矩阵做测试。这三个矩阵:
- 第一个:满足数独矩阵的要求,有解
- 第二个:不满足数独矩阵的要求,因此无解
- 第三个:满足数独矩阵的要求,但是无解
本函数不使用随机生成的数独矩阵。这是因为随机生成的数独矩阵几乎都不满足数独矩阵的要求(大概率存在列冲突),导致十个矩阵没一个是能解的…
四个要求的函数分别处于 `PrintMatrix.c` `RandomMatrix.c``JudgeMatrix.c` 和 `SolveMatrix.c` 中。矩阵类本身的定义位于 `SudokuMatrix.h` 当中,其中函数(比如构造函数,析构函数)的实现位于 `SudokuMatrix.c` 中。想要查看这些函数的实现的话,请到对应文件中寻找。我已经为每个函数写了很详细的注释了,

@ -0,0 +1,56 @@
#include "SudokuMatrix.h"
#include <stdio.h>
/**
* @brief
*
* @param a
* @param b
*/
void Swap(int*a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}
/**
* @brief int
*
* @param array
* @param length
*/
void Shuffle(int* array, int length){
if (length != 0){
for (int i = length - 1; i > 0; i--) {
int j = rand() % (i + 1);
Swap(&array[i], &array[j]);
}
}
}
void RandomMatrix(SudokuMatrix* matrix){
int random_row[9] = {1,2,3,4,5,6,7,8,9};
int random_place[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
// 重置矩阵内容为全0
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
matrix->matrix[i][j] = 0;
}
}
for (int i=0;i<3;i++){
// 先生成这九个数的顺序,再随机生成这九个数应该在哪里。
Shuffle(random_row,9);
for (int j=0;j<3;j++){
Shuffle(random_place,9);
for (int k=0;k<3;k++){
matrix->matrix[i*3+j][random_place[k]] = random_row[j*3+k];
}
}
}
}

@ -0,0 +1,100 @@
#include "SudokuMatrix.h"
#include <stdio.h>
/**
* @brief num
*
* @param sudoku
* @param row
* @param col
* @param num
* @return true
* @return false
*/
bool isSafe(SudokuMatrix *sudoku, int row, int col, int num) {
// 检查行
for (int i = 0; i < 9; i++) {
if (sudoku->matrix[row][i] == num) {
return false;
}
}
// 检查列
for (int i = 0; i < 9; i++) {
if (sudoku->matrix[i][col] == num) {
return false;
}
}
// 检查九宫格
int startRow = row - row % 3;
int startCol = col - col % 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (sudoku->matrix[i + startRow][j + startCol] == num) {
return false;
}
}
}
return true;
}
/**
* @brief 使
* 西
*
* @param matrix
* @return true
* @return false
*/
bool _SolveMatrix(SudokuMatrix* matrix){
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (matrix->matrix[row][col] == 0) {
for (int num = 1; num <= 9; num++) {
if (isSafe(matrix, row, col, num)) {
matrix->matrix[row][col] = num;
if (_SolveMatrix(matrix)) {
return true; // 已找到解决方案
}
matrix->matrix[row][col] = 0; // 回溯
}
}
return false; // 没有解决方案
}
}
}
return true; // 所有格子都已填满,找到解决方案
}
bool SolveMatrix(SudokuMatrix *matrix, SudokuMatrix *result){
// 检查可求解性
if (!JudgeMatrix(matrix)){
printf("No solution!\n");
return false;
}
// 复制矩阵内容
if (matrix != result){
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
result->matrix[i][j] = matrix->matrix[i][j];
}
}
}
// 进行求解
bool result_bool = _SolveMatrix(result);
if (result_bool){
printf("The solution of Sudoku matrix:\n");
PrintMatrix(result);
return true;
}
else{
printf("No solution!\n");
return false;
}
}

@ -0,0 +1,31 @@
#include "SudokuMatrix.h"
SudokuMatrix* CreateMatrix(){
SudokuMatrix *matrix = (SudokuMatrix*)malloc(sizeof(SudokuMatrix));
// 初始化这个数组里的数为0
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
matrix->matrix[i][j] = 0;
}
}
return matrix;
}
SudokuMatrix* CreateMatrixFromArray(int matrix[9][9]){
SudokuMatrix *newMatrix = CreateMatrix();
// 拷贝内部的数组为输入的数组
for(int i=0; i<9; i++){
for(int j=0; j<9; j++){
newMatrix->matrix[i][j] = matrix[i][j];
}
}
return newMatrix;
}
void DeleteMatrix(SudokuMatrix *matrix){
// 释放整个结构体
if (matrix != NULL)
{
free(matrix);
}
}

@ -0,0 +1,96 @@
#ifndef SudokuMatrix_h
#define SudokuMatrix_h
#include <stdlib.h>
#include <stdbool.h>
/**
* @brief
* C with Class!
* CreateMatrix
* C
* C
* DeleteMatrix
* 便
*/
typedef struct SudokuMatrix{
int matrix[9][9];
} SudokuMatrix;
/**
* @brief Create a Matrix object
*
* @return SudokuMatrix*
*/
SudokuMatrix* CreateMatrix();
/**
* @brief Create a Matrix From Array object
*
* @param matrix
* @return SudokuMatrix*
*/
SudokuMatrix* CreateMatrixFromArray(int matrix[9][9]);
/**
* @brief
* SudokuMatrix
*
* @param matrix
*/
void DeleteMatrix(SudokuMatrix *matrix);
/**
* @brief
*
* PrintMatrix.c
*
* @param matrix
*/
void PrintMatrix(SudokuMatrix *matrix);
/**
* @brief 0-9
* x1<=x<=9
* xx[1,9] 0
* 1-3 1-9 9 4-6 7-9
* RandomMatrix.c
*
*
* @param matrix
*/
void RandomMatrix(SudokuMatrix *matrix);
/**
* @brief
* 1-9 01
* 1-9 01
* 1-9 3x3 01;
* /
* 使
*
* @param matrix
* @return true
* @return false
*/
bool JudgeMatrix(SudokuMatrix *matrix);
/**
* @brief
*
* result result
*
* @param matrix
* @param result
* @return true
* @return false
*/
bool SolveMatrix(SudokuMatrix *matrix, SudokuMatrix *result);
#endif // SudokuMatrix_h

@ -0,0 +1,85 @@
#include "SudokuMatrix.h"
#include <time.h>
/**
* @brief
*/
void testRandomMatrix(){
SudokuMatrix* matrix = CreateMatrix();
RandomMatrix(matrix);
PrintMatrix(matrix);
DeleteMatrix(matrix);
}
/**
* @brief
*
*/
void testJudgeMatrix(){
SudokuMatrix* matrix = CreateMatrix();
RandomMatrix(matrix);
JudgeMatrix(matrix);
DeleteMatrix(matrix);
}
/**
* @brief
*
* @param matrix_used 0: board0; 1: board1; 2: board2
*/
void testSolveMatrix(int matrix_used){
int board0[9][9] = {{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}};
int board1[9][9] = {{8, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}};
int board2[9][9] = {{5, 2, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}};
SudokuMatrix* matrix;
switch (matrix_used){
case 0:
matrix = CreateMatrixFromArray(board0);
break;
case 1:
matrix = CreateMatrixFromArray(board1);
break;
case 2:
matrix = CreateMatrixFromArray(board2);
break;
}
SudokuMatrix* result = CreateMatrix();
SolveMatrix(matrix, result);
DeleteMatrix(matrix);
DeleteMatrix(result);
}
int main(){
// 初始化随机数种子
srand(time(NULL));
// 自选你要调用(用来测试)的函数
testSolveMatrix(0);
}
Loading…
Cancel
Save