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

github地址

https://github.com/bamboooooos/031702416


PSP表格

Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
计划 20 10
估计这个任务需要多少时间 10 2
开发 180 200
需求分析 (包括学习新技术) 60 120
生成设计文档 60 60
设计复审 10 10
代码规范 (为目前的开发制定合适的规范) 10 10
具体设计 40 30
具体编码 120 180
代码复审 30 20
测试(自我测试,修改代码,提交修改) 180 200
报告 60 30
测试报告 60 30
计算工作量 20 20
事后总结, 并提出过程改进计划 40 30
合计 900 952

解题思路

一开始看到需求没有什么太明确的思路,想了一会只想到一个一个填然后看有没有冲突;
睡午觉前上知乎百度找了下别人的算法,发现思路都差不多,睡了一觉起来大概有了一整个程序的思路;
文件输入输出流读写数独题,每一个题放在一个二维数组然后存放在ArrayList里面;
把题目一个一个取出来解题,解题就从[0][0]到最后一个有效的元素,先判断是否需要改,从1到9替换,进行行列宫测试,无冲突就进行下一个元素的判断,1到9都冲突就退回到上一个再+1;

流程图

流程图


代码

处理参数部分

参数一般为-m (m) -n (n) -i (input) -o (output)
简便处理直接取String数组args第1,3,5,7个元素

int rank=Integer.valueOf(args[1]).intValue();
int problem=Integer.valueOf(args[3]).intValue();
String filein=args[5];
String fileout=args[7];
输入部分

用文件流读取并将每个题放到ArrayList里

ArrayList<int[][]> problems=new ArrayList<>();
ArrayList<int[][]> results=new ArrayList<>();
try {//输入问题
	File file=new File(filein);
	BufferedReader bw=new BufferedReader(new FileReader(file));
	for(int times=0;times<problem;times++) {
		int[][] prob=new int[9][9];
		for(int i=0;i<rank;i++) {
			String toint=bw.readLine();
			String str = toint.replaceAll(" ","");
			for(int j=0;j<rank;j++) {
				prob[i][j]=Integer.valueOf(str.charAt(j)).intValue()-48;
			}
		}
		bw.readLine();
		problems.add(prob);
	}
	bw.close();
}catch(Exception e) {
	e.printStackTrace();
}
解题部分

将每一个题用solve方法解题后存放到ArrayList等待写到文件中

main里面的方法
for(int i=0;i<problem;i++) {//解决问题
	results.add(solve(problems.get(i),rank));
}
solve方法逻辑

将每个题(二维数组)传到solve方法中,对每个需要填的位置用test方法测试是否冲突,无冲突则测试下一个,没有无冲突的数则回到上一个

public static int[][] solve(int [][] problem,int rank){
	int [][] result=problem;
	int[] numX=new int[81];
	int[] numY=new int[81];
	int[] numNow=new int[81];
	int tosolve=0;
	numX[0]=0;
	numY[0]=0;
	numNow[0]=0;
	for(int i=0;i<rank;i++) {//存储需要更改的位置
		for(int j=0;j<rank;j++) {
			if(result[i][j]==0) {
				numX[tosolve]=i;
				numY[tosolve]=j;
				tosolve++;
			}
		}
	}
	int count=0;
	int x=0,y=0;
	for(;count<tosolve;) {
		x=numX[count];
		y=numY[count];
		int i=numNow[count]+1;
		for(;i<=rank;i++) {
			result[x][y]=i;
			if(test(result,x,y,rank)) {//替换成功
				numNow[count]=i; 
				count++;
				for(int clear=count;clear<tosolve;clear++) {
					numNow[clear]=0;
				}
				//log(result);
				break;
			}
		}
		if(i==rank+1) {
			for(int clear=count;clear<tosolve;clear++) {//错误清除之后所有改变的项
				int changedx=numX[clear];
				int changedy=numY[clear];
				result[changedx][changedy]=0;
			}
			count--;
		}
	}
	return result;
}
test方法逻辑

test方法进行行列测试(当阶数为4,6,8,9时额外进行宫测试)

public static boolean test(int[][] problem,int x,int y,int rank) {
	int flagx=0;
	int flagy=0;
	int xr=0;
	int yr=0;
	int flagr=0;
	for(int i=0;i<rank;i++) {//行测试
		if(problem[x][y]==problem[i][y]) {
			flagx++;
		}
	}
	if(flagx==2) {
		return false;
	}
	for(int i=0;i<rank;i++) {//列测试
		if(problem[x][y]==problem[x][i]) {
			flagy++;
		}
	}
	if(flagy==2) {
		return false;
	}
	switch(rank) {//宫测试初始化
		case 4:
			xr=2;
			yr=2;
			break;
		case 6:
			xr=2;
			yr=3;
			break;
		case 8:
			xr=4;
			yr=2;
			break;
		case 9:
			xr=3;
			yr=3;
			break;
		default:
 	}
	if(xr!=0) {//宫测试
		for(int i=x-x%xr;i<x+xr-x%xr;i++) {
			for(int j=y-y%yr;j<y+yr-y%yr;j++) {
				if(problem[x][y]==problem[i][j]) {
					flagr++;
				}
			}
		}
		if(flagr==2) {
			return false;
		}
	}
	return true;
}

文件流输出

输出部分
try {//输出结果
	File file=new File(fileout);
	BufferedWriter bw=new BufferedWriter(new FileWriter(file));
	for(int times=0;times<results.size();times++) {
		int[][] result=results.get(times);
		for(int i=0;i<rank;i++) {
			for(int j=0;j<rank;j++) {
				bw.write(result[i][j]+"");
				bw.write(" ");
			}
			bw.newLine();
			bw.flush();
		}
		bw.newLine();
		bw.flush();
	}
	bw.close();
}catch(Exception e) {
	e.printStackTrace();
}

性能分析

性能分析


测试

![案例测试](https://img2018.cnblogs.com/blog/1797453/201909/1797453-20190924215848104-1391967677.png)
posted @ 2019-09-24 21:40  Raiyon  阅读(205)  评论(1编辑  收藏  举报