软件工程2019第三次作业
Gthub地址
https://github.com/putaoputao303/031702516
Psp表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 30 | 40 |
| Estimate | 估计这个任务需要多少时间 | 30 | 40 |
| Development | 开发 | 100 | 100 |
| Analysis | 需求分析 (包括学习新技术) | 60 | 66 |
| Design Spec | 生成设计文档 | 30 | 20 |
| Design Review | 设计复审 | 5 | 5 |
| Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 5 | 5 |
| Design | 具体设计 | 20 | 30 |
| Coding | 具体编码 | 120 | 100 |
| Code Review | 代码复审 | 10 | 10 |
| Test | 测试(自我测试,修改代码,提交修改) | 100 | 120 |
| Reporting | 报告 | 20 | 20 |
| Test Repor | 测试报告 | 30 | 30 |
| Size Measurement | 计算工作量 | 40 | 45 |
| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 70 |
| 合计 | 665 | 681 |
需求
实现一个命令行程序,不妨称之为Sudoku。
百度百科简介:
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

设计思路
采用了回溯法。思路如下:
设了一个9X9的二维数组a[9][9],然后判断 值k是否可以插入某个点 a[i][j]
①该数组所有横向没有存在过k值
for(n=0;n<9;n++)
if(a[i][n]k)return 0;
②该数组纵向没有存在过k值
for(m=0;m<9;m++)
if(a[m][j]k)return 0;
③该点位于的九宫格3X3区间没有存在过k值
xm=(i/3)3,xn=(j/3)3;
for(m=xm;m<xm+3;m++)
for(n=xn;n<xn+3;n++)
if(a[m][n]==k)return 0;
然后开始搜索的过程:9X9总共81个格子,就用一个数字n作为标记i,j坐标点的变量(i=n/9; j=n%9;),即:80就相当于最后一个格子 8/9=8,8%9=8
如果n等于80,那么就表示已经遍历到最后一个点了,如果满足条件的话就找到最终解了。
如果n不等于80,表示还要继续往下试,即用不同的k值试探当前i,j点是否可以放下,回归后回溯就ok了。
void SD(int a[9][9],int n)//求解
{
int i,j;
int b[9][9];
for(i=0;i<9;i++)
for(j=0;j<9;j++)
b[i][j]=a[i][j]; //用b进行尝试
i=n/9; j=n%9; //行列
if(a[i][j]!=0) //如果该位置固定
(n==80)?print(b):SD(b,n+1);
else
{
int k; //试数
for(k=1;k<=9;k++)
if(test(b,i,j,k)) //可以
{
b[i][j]=k;
n==80?print(b):SD(b,n+1);
b[i][j]=0; //回溯
}
}
}
完整代码如下:
include<stdio.h>
int count=0;
void print(int a[9][9])
{
count++;
printf("case: %d:\n",count);
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
printf("%d",a[i][j]);
j==2?printf(" "):0;
j==5?printf(" "):0;
j==8?printf("\n"):0;
j8&&i%32?printf("\n"):0;
}
}
//判断是否可以将第i行、第j列的数设为k
int test(int a[9][9],int i,int j,int k)
{
int m,n,xm,xn;
for(n=0;n<9;n++)
if(a[i][n]==k)return 0;
for(m=0;m<9;m++)
if(a[m][j]==k)return 0;
xm=(i/3)3,xn=(j/3)3;
for(m=xm;m<xm+3;m++)
for(n=xn;n<xn+3;n++)
if(a[m][n]==k)return 0;
return 1;
}
void SD(int a[9][9],int n)//求解
{
int i,j;
int b[9][9];
for(i=0;i<9;i++)
for(j=0;j<9;j++)
b[i][j]=a[i][j]; //用b进行尝试
i=n/9; j=n%9; //行列
if(a[i][j]!=0) //如果该位置固定
(n==80)?print(b):SD(b,n+1);
else
{
int k; //试数
for(k=1;k<=9;k++)
if(test(b,i,j,k)) //可以
{
b[i][j]=k;
n==80?print(b):SD(b,n+1);
b[i][j]=0; //回溯
}
}
}
int main()
{
int a[9][9];
printf("请输入原始数据,没有数据用0代替。\n");
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
scanf("%d",&a[i][j]);
printf("-------------------\n\n");
SD(a,0);
if(count==0)
printf("此数独无解!");
return 0;
}


在VS2017下编译运行时总是报错,至今我也不知道因为什么,等问问明白的人再做修改。


实验总结
GitHub的部分文件导入没查清楚,尝试了很多次真是太难用了,这几天我就看一下github里面的阅读指南,希望可以学会那里的操作,软件工程这门课真是不断让我学习新的东西,每次都是,对我来说作业开始困难起来,可能过几次会熟悉。

浙公网安备 33010602011771号