软件构造实验Lab1的P1

Lab1对于第一次做软构实验的人来说还是比较难的,全是英文的实验手册,恶心的软件安装,还有没法机翻的英语界面,实在是搞人心态。所以在这里给出做Lab1的P1框架,P2,P3都大同小异,主要是入个门,希望看到这篇文章的小伙伴可以上来就理清这个有(chao)难(bian)度(tai)的实验到底让你干嘛。

P1

P1是让你做一个幻方,具体要求全是英文的,这里简单说一下。像Eclipse的安装就按实验手册来吧,这个就算机翻也完全ok。

翻译了一下P1的要求界面,大概要求如下:
你要写一个Java程序(MagicSquare.java)检查行/列/对角值的矩阵,然后判断它是一个魔术方块我们给你五个文本文件:1.txt, 2.txt, ..5.三种。在PPT给定的链接上下载下来,并将它们添加到你的项目目录\src\P1\txt\;对于每个文件打开文件,并检查所有行的总和是否确实是同一个常量。检查一下这些列和对角线是否也是同一个常数。返回一个布尔结果,指示输入是否为魔方。

函数规约:boolean isLegalMagicSquare(String fileName)
在 main()函数中调用五次 isLegalMagicSquare()函数,将 5 个文本文件名分别作为参数输入进去,看其是否得到正确的输出(true, false)。

需要能够处理输入文件的各种特殊情况,例如:文件中的数据不符合Magic Square 的定义(行列数不相等、并非矩阵等)、矩阵中的某些数字并非正整数、数字之间并非使用\t 分割、等。若遇到这些情况,终止程序执行(isLegalMagicSquare 函数返回 false),并在控制台输出错误提示信息。一些提示将所有五个文本文件复制到项目的\src\P1\txt\目录下。你还可以使用文件的绝对路径(Windows上是c:\somedir\1.txt, Mac上是/Users/myuser/1.txt)。但是,最好使用这些文件的相对路径。您需要处理或重新抛出IOException。软件构建的实验手册基础Java编程和测试逐行读取文件。使用分割(“\ t”);以TAB字符分隔每行,产生一个字符串数组(字符串[]),每个字符串包含一个值。最后,使用转换为Intenger。返回对象的值(字符串);将每个字符串值转换为整数值。

要求都列出来了,比较有难度的部分是用try抛异常与java中I/O流的使用,去bilibili搜一下尚硅谷的java教程,看一下就会了。剩下的算法思想写在注释里面了,下面是代码:

package P1;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;



public class MagicSquare {
	
	
    //main函数
	public static void main(String[] args) throws FileNotFoundException{
		//循环读取5个文件,每次调用函数isMagicSquare(fileName)
		for(int i = 1; i <= 5; i++) {
			String fileName = "./src/P1/txt/" + String.valueOf(i) + ".txt";//int类型转化成字符串
			boolean isMagicSquare = isLegalMagicSquare(fileName);
			System.out.println(String.valueOf(i) + ".txt is " + isMagicSquare);
		}
			
		//判断generateMagicSquare函数生成的是否为幻方
		if (generateMagicSquare(9)) {//参数只能为奇数
			System.out.println("6.txt\t" + isLegalMagicSquare("./src/P1/txt/6.txt"));
		} else {
			System.out.println("生成幻方失败!");
		}
	}
	
	
	/**
     * Determine Whether the MagicSquare is legal.
     * 
     * There is a simple formula for judge whether the MagicSquare is legal;
     * you can use it in your program.
     * 
     *  
     * @author LiMingda
     * @create 2021 
     * @param the file which contain data of the MagicSquare
     * @return whether the MagicSquare is legal
     */
	
	
	//isLegalMagicSquare函数
	public static boolean isLegalMagicSquare(String fileName) {
		final int NUM = 200;//矩阵的n的值最大设置为200(5个文件中最多的为121行)
		
		//变量初始化
		int inputNum[][] = new int[NUM][NUM];//读取文件记录矩阵的二维数组
		int rowSum[] = new int[NUM];//对每一行求和
		int colSum[] = new int[NUM];//对每一列求和
		int diaSum_1 = 0;//对角线求和1
		int diaSum_2 = 0;//对角线求和2
		for(int i = 0; i < NUM; i++)//初始化
		{
			rowSum[i] = 0;
			colSum[i] = 0;
		}
		
		//判断文件是否为空
		FileInputStream in = null;
		try {
			in = new FileInputStream(fileName);
			int size = in.available();
			if(size == 0) {
				System.out.println("文件为空");
				return false;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		//读文件
		File file = new File(fileName);
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(file));
			String tempString = "";//按行读取,tempString用来记录每行的字符串
			int col = 0;//矩阵的列数
			int row = 0;//矩阵的行数,兼职行计数变量
			//循环按行读取并记录信息
			while((tempString = br.readLine()) != null) {
				//当读取文件结束,tempString的值为空,结束循环
				col = tempString.split("\t").length;
				String rowString[] = {};
				try {
					rowString = tempString.split("\t");
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					System.out.println("不是以\t分隔的!");
				}
				//数组rowString用于保存每一行的所有元素
				if(col != rowString.length) {//判断所读行与第一行元素的个数是否相同,不同则说明不是矩阵,直接返回false.
					System.out.println("行个数不同,不是矩阵!");
					return false;
				}
				for(int i = 0; i < col; i++)//对每行分别求和
				{
					int a = -1;
					try {
						a = Integer.valueOf(rowString[i]);
					}catch(Exception e) {
						System.out.println("矩阵中有非整数!");
					}
					if(a <= 0) {//确保矩阵都是正整数
						System.out.println("矩阵中有非正整数!");
						return false;
					}
					inputNum[row][i] = Integer.valueOf(rowString[i]);
					rowSum[row] +=  Integer.valueOf(rowString[i]);//行求和
					colSum[i] += Integer.valueOf(rowString[i]);//列求和
					if (i == row) {
			            diaSum_1 += Integer.valueOf(rowString[i]);
			        }
			        if (i + row + 1 == col) {
			            diaSum_2 += Integer.valueOf(rowString[i]);
			        }//对角线求和
				}
				row++;
				
			}
			
			//判断是否是幻方
			if(row != col) {
				System.out.println("行列不等,不是矩阵!");
				return false;
			}
			int sum = rowSum[0];
			for(int i = 0; i < col; i++)
			{
				if(rowSum[i] != sum) {
					System.out.println("行和不等,不是幻方!");
					return false;
				}
				if(colSum[i] != sum) {
					System.out.println("列和不等,不是幻方!");
					return false;
				}
			}
			if(diaSum_1 != sum) {
				System.out.println("对角线和不等,不是幻方!");
				return false;
			}
			if(diaSum_2 != sum) {
				System.out.println("行和不等,不是幻方!");
				return false;
			}
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			if(br != null){
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		
		return true;//以上条件均满足返回true	
	}
	
	
	//generateMagicSquare函数
	public static boolean generateMagicSquare(int n) throws FileNotFoundException {
		
		//判断n是否为正奇数
		if(n <= 0) return false;
		if(n % 2 == 0) return false;
		
		int magic[][] = new int[n][n];//创建要打印的二维数组
		int row = 0, col = n / 2, i, j, square = n * n;//初始化为第一行,中间列
		for (i = 1; i <= square; i++) {//从1到square开始赋值
			magic[row][col] = i;
			if (i % n == 0) row++;//跳转到下一行
			else {
				if (row == 0) row = n - 1;
				else row--;//跳转到上一行,第一行跳转到最后一行
				if (col == (n - 1)) col = 0;
				else col++;//跳转到下一列,最后一列跳转到第一列
			} 
		}
		
		//以文件输出
		
		File file = new File("src/P1/txt/6.txt");
		try {
			FileWriter fw = new FileWriter(file);
			for (i = 0; i < n; i++) {
				for (j = 0; j < n; j++) fw.write(magic[i][j] + "\t", 0, (magic[i][j] + "\t").length());
				fw.write('\n');
			}
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return true;
	}
	
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值