软件工程实践2019第三次作业

一、Github项目地址

https://github.com/huang-sy/031702602


二、PSP表

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 30
Estimate 估计这个任务需要多少时间 900 1370
Development 开发 120 180
Analysis 需求分析 (包括学习新技术) 120 200
Design Spec 生成设计文档 60 30
Design Review 设计复审 30 30
Coding Standard 代码规范(为目前的开发制定合适的规范) 30 50
Design 具体设计 120 180
Coding 具体编码 60 90
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 180 200
Reporting 报告 60 100
Test Repor 测试报告 60 100
Size Measurement 计算工作量 30 60
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 60 90
合计 980 1370

三、解题思路

语言实现:选C++,因为还不会Java语言(⊙﹏⊙)。

1、数独的话,以前有玩过,但每每也是稍微靠了一点点游戏提示,现在年龄大了,应该可以自己来了。然后下了全民数独开始玩。四宫格、六宫格、九宫格,都试着玩了几局,有点感觉了。我想先写不是用文件输入输出的代码,测试没问题了再弄完整。先三宫的,再递增,先写盘面数为1的(即m=3,n=1)。

代码如下:/三宫格代码/

#include<iostream>
using namespace std;
int main()
{
	int a[3][3], b = 0;

	for (int i = 0; i < 3; i++)/*输入盘面,0为要填的格子*/
	{
		for (int j = 0; j < 3; j++)
		{
			cin >> a[i][j];
			if (a[i][j] == 0)/*b记录0的个数,即:空格子数,为了后面循环次数*/
			{
				b++;
			}
		}
	}

	for (int as = 0; as < b; as++)/*b个0*/
	{
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				if (a[i][j] == 0)
				{
					int c[5], k = 0;/*c[]数组中存放当前格所在行和列中已有的数值,这里不考虑重复*/
					for (int x = 0; x < 3; x++)/*纵向已有值*/
					{
						if (a[x][j] != 0)
						{
							c[k] = a[x][j];
							k++;
						}
					}
					for (int y = 0; y < 3; y++)/* 横向已有值 */
					{
						if (a[i][y] != 0)
						{
							c[k] = a[i][y];
							k++;
						}
					}

					int cc[]={1,2,3}, cx = 3;/*cx表示当前格的数值的可能情况,三宫格最多为3*/

					for (int ca1 = 0; ca1 < 3; ca1++)/*数组cc[]和数组c[]比较*/
					{
						for (int ca2 = 0; ca2 < k; ca2++)
						{
							if (cc[ca1] == c[ca2] && cc[ca1] != 0)
							{
								cc[ca1] = 0;
								cx--;
							}
						}
					}
					if (cx == 1)/*cx=1表示当前格的数值只有一种可能,即可将其填入数组*/
					{
						for (int cs = 0; cs < 3; cs++)
						{
							if (cc[cs] != 0)
							{
								a[i][j] = cc[cs];
							}
						}
					}
				}
			}
		}
	}/*阶梯恐怖*/

	cout << endl;
	for (int i = 0; i < 3; i++)/*输出*/
	{
		for (int j = 0; j < 3; j++)
		{
			cout << a[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}    

第一次输入三宫格测试时,竟然这样输:

然后,就没得嘞

要这样啊啊啊!感谢室友“卓大哥”!!!

应该是如下:

2、三宫格出来了,突然想到三宫格、五共格、七宫格应该是一样的,就把3改成5和7,都试了下,五宫出来了,七宫还不行。如下:

七宫暂时不行,再想想。先来加上m和n,再试下:

用文件输入输出,这部分算是现学现用,测试的时候出来一大堆,感谢百度大哥

百度了一下,在代码的最开始,加上#define_CRT_SECURE_NO_DEPRECATE,可以消除警告,不知道这样做行不行,先加着吧。

暂时只做出了三宫和五宫,五宫也是刚好能用三宫代。

完整代码如下

#define _CRT_SECURE_NO_DEPRECATE/*不知道这样做行不行,先加着吧*/
#include<iostream>
#include<fstream>
//#include<stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
	int m, n;/*m=3或m=5,n为盘面数*/
	//cin >> m >> n;
	FILE* fp1;
	FILE* fp2;
	m = atoi(argv[2]);
	n = atoi(argv[4]);
	fp1 = fopen("input.txt", "r");
	if (fp1 == NULL)
	{
		return -1;
	}
	
	fp2 = fopen("output.txt", "w");
	if (fp2 == NULL)
	{
		return -1;
	}
	fclose(fp2);

	for (int nn = 0; nn < n; nn++)/*nn为盘面的循环次数*/
	{
		int a[9][9], b = 0, i, j;/*每为一个新题都重新变量初始化, b记录此题的待填个数(即空格数)*/
		for (i = 0; i < m; i++)
		{
			for (j = 0; j < m; j++)
			{
				//cin >> a[i][j];
				fscanf(fp1, "%d", &a[i][j]);
				if (a[i][j] == 0)
				{
					b++;/*0即空格,b记数*/
				}
			}
		}
		fp2 = fopen("output.txt", "a");
		if (fp2 == NULL)
		{
			return -1;
		}
		for (int as = 0; as < b; as++)/*至多循环b次可填好整个盘面*/
		{
			for (i = 0; i < m; i++)
			{
				for (j = 0; j < m; j++)
				{
					if (a[i][j] == 0)/*找到要填的当前格*/
					{
						int c[18], k = 0;/*一个盘面,一行一列格数和至多为18(2*9)*/
						for (int x = 0; x < m; x++)/*找出当前列里所有已有值,依次放入c[]数组*/
						{
							if (a[x][j] != 0)
							{
								c[k] = a[x][j];
								k++;
							}
						}
						for (int y = 0; y < m; y++)/*找出当前列里所有已有值,依次放入c[]数组,不考虑重复*/
						{
							if (a[i][y] != 0)
							{
								c[k] = a[i][y];
								k++;
							}
						}
						int cc[9] = { 1,2,3,4,5,6,7,8,9 }, cx = m;
						for (int ca1 = 0; ca1 < m; ca1++)/*ca1给cc[]*/
						{
							for (int ca2 = 0; ca2 < k; ca2++)/*ca2给c[]*/
							{
								if (cc[ca1] == c[ca2] && cc[ca1] != 0)/*一个个比较cc[]里的数,若有和c[]数组里一样的则置0,最后cc[]数组中的非零值即是当前格的所有可能取值*/
								{
									cc[ca1] = 0;
									cx--;/*cx记录当前格可能取值的情况数,cc[]有一个置0,cx就减1*/
								}
							}
						}
						if (cx == 1)/*当前格取值情况唯一,即可填入当前格*/
						{
							for (int cs = 0; cs < m; cs++)
							{
								if (cc[cs] != 0)/*找到cc[]里唯一的非0值,赋给当前格a[i][j]*/
								{
									a[i][j] = cc[cs];
								}
							}
						}
					}
				}
			}
		}
		
		for (i = 0; i < m; i++)/*输出填好的完整格,m*m*/
		{
			for (j = 0; j < m; j++)
			{
				//cout << a[i][j] << " ";
				fprintf(fp2, "%d", a[i][j]);
				fprintf(fp2, " ");
			}
			//cout << endl;
			fprintf(fp2, "\n");
		}
		//cout << endl;
		fprintf(fp2, "\n");
	}
}

结果如下:


四、总结心得:

数独确实挺好玩的,可代码暂时会写三宫格的(五共格算是碰巧的附带),判断一小宫的得再想想,有一点模糊的感觉,脑壳啊。代码部分,感觉只是用了个比较没很大技术的方法,这个做法是我脑子里第一个出来的(可见储备量及熟练度。。。)。这次的代码里没有使用定义的函数,只有一连串的循环,后面看的时候,额,也是“服”了自己了。关于文件部分的,纯属现学现用,效果很神奇。PSP表本来的目标是写好基础的,三宫格,还超预期了。。。合理计划安排时间是很重要的,给定时间做个事,无不可阻挡的“意外”,有效率实施是重要的。对于新接触的VS,虽然目前只是会了一丢丢,比较开心的是,这次下载安装使用VS,真的是“纯手工,纯亲自”,呃呃,百度大哥是主要。一个个找一个个试,遇到一个问题解决一个,还成功的感觉真的不赖(待学的还有很多啊)。

posted @ 2019-09-25 22:14  仰望星辰兮  阅读(260)  评论(2编辑  收藏  举报