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;
}
}