Magic Squares
要求1:
在MagicSquqre.java文件中添加isLegalMagicSquare()函数,判断一个矩阵是否为MagicSquare。
MagicSquare说明:矩阵行数以及列数相同,且每行元素之和,每列元素之和以及对角线元素之和都应相等:
1.我们需要从https://github.com/rainywang/Spring2018_HITCS_SC_Lab1/tree/master/P1获取1.txt, 2.txt, ..., 5.txt等5个测试文件,并将其添加到项目的指定路径:\src\P1\txt\;
2.判断是否为MagicSquare,返回true or false;
函数规约:
1)boolean isLegalMagicSquare(String fileName)
2)在 main()函数中调用五次 isLegalMagicSquare()函数,将 5 个文本 文件名分别作为参数输入进去,看其是否得到正确的输出(true, false)。
3)需要能够处理输入文件的各种特殊情况,例如:文件中的数据不符合 Magic Square 的定义(行列数不同、并非矩阵等)、矩阵中的数字并非正 整数、数字之间并非使用\t 分割、等。若遇到这些情况,终止程序执行(isLegalMagicSquare 函数返回 false),并在控制台输出错误提示信息。
实现步骤
创建项目:略
boolean isLegalMagicSquare(String fileName) 函数实现过程:
1.根据文件名访问并读取对应文件:
1)已知文件存储在项目的\src\P1\txt\文件夹下,可利用相对路径访问文件并创建file对象;
2)通过file对象读取文件大小filelongth,新建对应大小的byte[]数组filecontent存储文件内容;
3)将读取的文件内容转化为"UTF-8"编码的字符串存储在content字符串中;
String filename = "src/P1/txt/" + fileName;//构造文件路径
String encoding = "UTF-8";//文件字符串编码规格
String content = null;
File file = new File(filename);//文件对象
Long filelongth = file.length();
byte[] filecontent = new byte[filelongth.intValue()];
int cols = 0 , rows = 0;
try{
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
try{
content = new String(filecontent,encoding);
}catch(UnsupportedEncodingException e){
System.err.println("The OS does not support " + encoding);//实时输出
e.printStackTrace();
}
2.对文件内容进行分割从而得到所需数据
1)利用"\n"对字符串content进行分割,从而得到各行数据以及矩阵行数;
2)对数据进行处理,判断矩阵数据的合法性并分离出各数据的值同时得到各行各列以及对角线的和
3)通过各行各列以及对角线的和判断矩阵是否为MagicSquare
1 String line[] = content.split("\n"); 2 rows = line.length; //the rows of the square 3 cols = rows; 4 int nums[][] = new int[rows][rows]; 5 int sumR[] = new int[rows];//各行和 6 int sumC[] = new int[cols];//各列和 7 int sumD[] = new int[2];//对角线和 8 //默认初始化为0 9 10 for(int i = 0; i < rows;i++)//对数据进行处理,判断数据的合法性并分离出值 11 { 12 13 if(line[i].split("\\.").length != 1) 14 { 15 System.out.println("数据存在浮点数"); 16 return false; 17 } 18 19 if(line[i].split("-").length > 1) 20 { 21 System.out.println("数据存在负数"); 22 return false; 23 } 24 25 String []data = line[i].split("\t"); 26 27 if(data.length != rows) 28 { 29 if(i == 0) 30 System.out.println("行列数不等"); 31 else 32 System.out.println("不为矩阵"); 33 return false; 34 } 35 36 for(int j = 0; j < rows ;j++) 37 { 38 try{ 39 int num = Integer.valueOf(data[j]).intValue(); 40 nums[i][j]=num; 41 }catch(NumberFormatException e){ 42 System.out.println("数据存在非法符号"); 43 return false; 44 } 45 46 sumR[i] += nums[i][j]; 47 sumC[j] += nums[i][j]; 48 49 if(i == j) 50 { 51 sumD[0] += nums[i][j]; 52 } 53 54 if(i + j +1 == cols) 55 { 56 sumD[1] += nums[i][j]; 57 } 58 } 59 } 60 61 if(sumD[0] != sumD[1]) 62 { 63 return false; 64 } 65 66 int sum = sumD[0]; 67 68 for(int i = 0; i<rows; i++) 69 { 70 if(sumR[i] != sum || sumC[i] != sum) 71 return false; 72 } 73 74 return true;
main()函数测试代码
public static void main(String args[]){ MagicSquare magic = new MagicSquare(); for(int i = 1 ; i<6 ; i++) { if(magic.isLegalMagicSquare(String.valueOf(i)+".txt")) System.out.println(i+":Yes"); else{ System.out.println(i+":No"); } } }
要求2
阅读以下代码,将其加入你的 MagicSquare 类中作为一个静态函数,并试着 在 main()中测试它:
public static boolean generateMagicSquare(int n) { int magic[][] = new int[n][n]; int row = 0, col = n / 2, i, j, square = n * n; for (i = 1; i <= square; i++) { 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++; } } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) System.out.print(magic[i][j] + "\t"); System.out.println(); } return true; }
为该函数绘制程序流程图,并解释它如何根据输入的参数(奇数 n)生成一 个 n×n 的 Magic Square。
如果输入的 n 为偶数,函数运行之后在控制台产生以下输出:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 12
at MagicSquare.generateMagicSquare(MagicSquare.java:17)
at MagicSquare.main(MagicSquare.java:121)
如果输入的 n 为负数,函数运行之后在控制台产生以下输出:
Exception in thread "main" java.lang.NegativeArraySizeException
at MagicSquare.generateMagicSquare(MagicSquare.java:11)
at MagicSquare.main(MagicSquare.java:121)
请查阅 JDK 了解上述异常的含义,并分析该函数为何会产生这些异常(注: 我们将在 Lab4 中训练异常处理机制)。
对该函数做扩展:(1) 将产生的 magic square 写入文件\src\P1\txt\6.txt 中;(2) 当输入的 n 不合法时(n 为偶数、n 为负数等),不要该函数抛出异常 并非法退出,而是提示错误并“优雅的”退出——函数输出 false 结束。
利用你前面已经写好的 isLegalMagicSquare()函数,在 main()函数判断 该函数新生成的文本文件 6.txt 是否符合 magic square 的定义。
项目的目录结构:
程序流程图: