SC lab 1 P1 Magic Squares
Magic Squares
要求验证某个读入的矩阵是否是幻方,读入的文件要求数字间以\t分割且都是正整数,幻方要求为方阵且行列对角线之和相等。
- isLegalMagicSquare()
首先需要对对文件内容进行分割从而得到所需数据:- 调用txt2String()方法将文件按行分割为字符串
- 利用"\n"对字符串content进行分割,从而得到各行数据以及矩阵行数;
- 对数据进行处理,判断矩阵数据的合法性并分离出各数据的值同时得到各行各列以及对角线的和
- 通过各行各列以及对角线的和判断矩阵是否为MagicSquare,如果相等,则为Magic Square,否则不是,输出错误并返回false。
/**
* 该方法判断字符串是否为MagicSquare,若是则返回true 不是则返回false并给出原因
*
* @param MagicSquare
* @return boolean
*/
public static boolean isLegalMagicSquare(String fileName) {
File file = new File(fileName);
String line[] = txt2String(file).split("\n");
int rows = line.length - 1; // the rows of the square
int cols = rows;
for (int i = 0; i < rows; i++) {
line[i] = line[i + 1];
//System.out.println(line[i]);
}
int nums[][] = new int[rows][rows];
int sumR[] = new int[rows];// 各行和
int sumC[] = new int[cols];// 各列和
int sumD[] = new int[2];// 对角线和
//System.out.println(rows);
// 默认初始化为0
for (int i = 0; i < rows; i++)// 对数据进行处理,判断数据的合法性并分离出值
{
if (line[i].split("\\.").length != 1) {
System.out.println("数据存在浮点数");
return false;
}
if (line[i].split("-").length > 1) {
System.out.println("数据存在负数");
return false;
}
String[] data = line[i].split("\t", -1);
if (data.length != rows) {
if (i == 0)
System.out.println("行列数不等");
else
System.out.println("不为矩阵");
return false;
}
for (int j = 0; j < rows; j++) {
try {
int num = Integer.valueOf(data[j].trim()).intValue();
nums[i][j] = num;
} catch (NumberFormatException e) {
System.out.println("数据存在非法符号");
return false;
}
sumR[i] += nums[i][j];
sumC[j] += nums[i][j];
if (i == j) {
sumD[0] += nums[i][j];
}
if (i + j + 1 == cols) {
sumD[1] += nums[i][j];
}
}
}
if (sumD[0] != sumD[1]) {
return false;
}
int sum = sumD[0];
for (int i = 0; i < rows; i++) {
if (sumR[i] != sum || sumC[i] != sum)
return false;
}
return true;
}
- generateMagicSquare()
设计与实现:
给出的代码使用Merzirac法生成奇阶幻方:- 首先向第一行正中的方格内填写1
- 以下依次向右上角的方格内填写2、3、4……
- 若右上角的方格内已经有数字,则向下移动一格继续填写
- 若右上角的方格超出矩阵的行,则移到矩阵下一列的最下端继续填写
- 若右上角的方格超出矩阵的列,则移到矩阵下一行的最左端继续填写
给出的代码没有对2.1步骤进行判断,而是使用当前填入的数字是否是行列数的倍数来决定,如果是行列数的倍数,则右上角必然有数字,需要下移。
/**
* 该方法为实验提供的创建square二维数组的方法,当输入为正奇数的
* 时候成功创建并返回true,为负数或偶数的时候返回false
* @param n
* @return boolean
*/
public static boolean generateMagicSquare(int n) {
if (n % 2 == 0 || n <= 0) {
if(n % 2 == 0 && n>=0) System.out.println("n(n=" + n + ")的输入不合法:n为偶数");
else System.out.println("n(n=" + n + ")的输入不合法:n为负数");
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++) {
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++;//否则列数加一
}
}
writeFile(magic, n);//生成一个txt文档
/*
* for (i = 0; i < n; i++) { for (j = 0; j < n; j++)
* System.out.print(magic[i][j] + "\t"); System.out.println(); }
*/
return true;
}
- 对文件的操作
对于我来说,P1的难点在于对文件的操作和对字符串的分割,以下为我的代码。
public static String txt2String(File file) {
StringBuilder result = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));// 构造一个BufferedReader类来读取文件
String s = null;
while ((s = br.readLine()) != null) {// 使用readLine方法,一次读一行
result.append(System.lineSeparator() + s);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return result.toString();
}
而对字符串的切割可以用java.lang.string.split方法
示例1:
String str="Java string split test";
String[] strarray=str.split(" ");
for (int i = 0; i < strarray.length; i++)
System.out.println(strarray[i]);
将输出:
Java
string
split
test
通过查询资料,基本掌握了Java程序读写文件的方法。对于Java这种典型的OOP编程语言,一切内容都是围绕着类与对象展开的。所以有了OOP的编程思想,学习文件读写的这些内容也不是很难。