软件构造感想2
对给定的Java项目进行实现与升级
给出一个Java题目
给定研究人员的一系列论文(每个论文是一个非负整数),编写一个函数来计算研究人员的h-index数。(
根据维奇百科上h-index的定义:“如果科学家的N篇论文中的h篇中每篇至少被引用h次,而其他N-h篇论文中每篇不超过h篇引用,则h被称为科学家的h-index。”
- 例子:
输入: citations = [3,0,6,1,5]
输出: 3 - 说明:
[3,0,6,1,5]表示研究人员总共有5篇论文,每篇论文分别获得3、0、6、1、5篇引用。 由于研究人员拥有3篇论文,每篇论文至少被3次引用,其余两篇论文每篇被引用不超过3次,因此她的h-index为3。 - 注意:如果h有多个可能的值,则将最大值作为h-index。
解决思路、编写Java代码、执行
思路:先把数组从大到小排序,再从头遍历,找到符合要求的h-index值。
[3,0,6,1,5]→[6,5,3,1,0]
遍历时,如果数组中该位置的数值大于等于其序号+1,则h-index至少为序号+1。
例如:
- 第0位为6,6>=1,则h-index=1;
- 第1位为5,5>=2,则h-index=2;
- 第2位为3,3>=3,则h-index=3;
- 第4位为1,1<4,则h-index不再变化,算法终止。
先创建Java项目:
- 在Eclipse中构造工程,命名为SC2020Spring_Classroom_Exercise;
在src中创建包,命名为exercise_6_6;
在包中创建类HIndex.java。
(1)控制台读入用户输入,按3,0,6,1,5的格式,存储于数组
Scanner scanner = new
Scanner(System.in);
int[] citations = new int[100];
String[] strs;
System.out.println("Please input the citation numbers:");
String line = scanner.nextLine();
strs = line.split(",");
for (int i = 0; i < strs.length; i++)
citations[i] = Integer.parseInt(strs[i]);
(2)编写排序功能(冒泡排序)
for (int i = 0; i < number - 1; i++) {
for (int j = 0; j < number - 1; j++) {
if (citations[j] < citations[j + 1]) {
int temp = citations[j + 1];
citations[j + 1] = citations[j];
citations[j] = temp;
}
}
}
(3)计算h-index
int hindex = 0;
for (int j = 0; j < number; j++) {
if (citations[j] >= j + 1)
hindex = j + 1;
else
break;
}
System.out.println("The h-index is: " + hindex);
接下来要输入不同的数组,进行手工测试。
上述编写完成后,git commit到v0.1All code in main()
(4)提取出单独的int hindex(int[] citations)函数
(5)提取出来形成单独的排序函数void sort(int[] array),git commit到v0.2 separate functions
(6) 从文本文件读入,存储于数组
健壮性处理
进行健壮性测试:
- 输入空数组——抛出异常了
String line = new String();
line = scanner.nextLine();
while(line.length() == 0)
{
System.out.println("Input empty, please re-input:");
line = scanner.nextLine();
}
git commit到v0.3 avoid empty input string
- 输入负值:
策略:split之后,调用Integer.parseInt(strs[i])得到整数,检查其是否<0 - 输入特殊值(非整数、非法字符等)
策略1:比较笨的方法:逐个字符位置检查是否为数字
策略2:与负值一起处理,用正则表达式检查分割后字符串是否匹配"[0-9]+"
策略3:直接调用Integer.parseInt()或者Integer.valueOf().intValue(),若抛出异常,说明不合法,需要在捕获异常之后让用户重新输入
举例实现策略2:
//read input from keyboard
Scanner scanner = new
Scanner(System.in);
System.out.println("Please input the citation numbers:");
int[] citations = new int[100];
String[] strs;
String line = new String();
//loop, until user inputs legal string
while (true) {
line = scanner.nextLine();
//if the nput is empty
if (line.length() == 0)
{
System.out.println("Input empty, please re-input:");
continue;
}
//check if each part is integer >= 0
boolean legalNumbers = true;
strs = line.split(",");
for (int i = 0; i < strs.length; i++) {
//if not,stop checking others and let user re-input
if(! strs[i].matches("[0-9]+")) {
System.out.println(strs[i] + " is illegal: ");
legalNumbers = false;
break;
}
//otherwise,store the integer into array
citations[i] = Integer.parseInt(strs[i]);
}
if (!legalNumbers)
continue;
else {
//calculate h-index
int hindex = hindex(citations);
//output to console
System.out.println("The h-index is: " + hindex);
break;
}
}
git commit到v0.4 avoid input string containing illegal characters
- 需要注意的是,如果这里超过100个输入则会抛出异常,但是我们不能提前得知用户输入多少个
策略:使用Java Collections, List, Set, Map, etc
//int[] citations = new int[5];
List<Integer> citations = new ArrayList<>();
//citations[i] = value;
citations.add(value);
int hindex = hindex(citations);
public static int hindex(List<Integer> citations) {
//Integer[]
array1 = (Integer[])citations.toArray();
int[] array2 = new int[citations.size()];
for(int i=0; i<citations.size(); i++)
array2[i] = citations.get(i);
// 冒泡排序
sort(array2);
// 计算h-index
int hindex = 0;
for (int j = 0; j < array2.length; j++) {
if (array2[j] >= j + 1)
hindex = j + 1;
else
break;
}
return hindex;
}
git commit到v0.5 use java collections instead of arrays
将计算功能与用户输入分离开来
从main中分离出来计算,main只处理调用(作为客户端程序)
public class HIndex3 {
private List<Integer> citations = new ArrayList<>();
public HIndex3(String input) {
if(input == null || input.length() == 0)
throw new IllegalArgumentException("Empty");
dealInput(input);
}
private void dealInput(String input) {
String[] strs = input.split(",");
for (int i = 0; i < strs.length; i++) {
if(! strs[i].matches("[0-9]+"))
throw new IllegalArgumentException(strs[i] + " is illegal");
citations.add(Integer.parseInt(strs[i]));
}
}
public static void main(String[] args) {
String[] inputs = new String[] {"1,0", "3,-2,4,8"};
for(int i=0;i<inputs.length;i++) {
HIndex3 h = new HIndex3(inputs[i]);
System.out.println(h.calcHIndex());
}
}
public int calcHIndex() {...}
...
}
git commit到v0.6 separate input with calculation
我们还可以通过静态函数进行调用
for(int i=0;i<inputs.length;i++) {
//HIndex3 h = new HIndex3(inputs[i]);
System.out.println(HIndex3.calcHIndex(inputs[i]));
}
git commit到v0.7 use static methods of a class
直接编写测试用例
打开Junit,演示测试用例如何书写、如何运行、正确和错误的执行结果
创建一个新的测试类HIndexTest.java
演示如何编写测试函数并启动执行、查看结果
- 正确的、错误的
普通的用例如何测试:assertEquals
抛出异常如何测试?
- 只看抛出异常的类型是否正确
还要看抛出异常的消息是否正确
最好每个测试方法里只写一个测试用例
git commit到v0.8 design test cases manually
根据等价类和边界值思想,设计和编写测试用例
设计更完备的测试用例
Testing strategy:
- 对输入的字符串进行等价类划分
- 针对每一个划分结果来设计测试用例并撰写测试方法
git commit到v0.9 design test cases by equivalence partitioning
改造为OOP
构造Paper类,存储论文的题目、年份、期刊、引用数,封装起来,对Paper类进行功能扩展,包括增加引用数、减少引用数;
基于Paper类改造之前的HIndex类,将其改造为Author类,其中管理作者名字、发表论文清单,使用集合类表达一组Paper而不再用数组。
在Author类中增加功能:新增论文、修改某个论文的引用数、计算HIndex、toString(第一行打印出作者,后面每行是一篇论文[题目、引用数],最后是该作者的HIndex)。
写一个客户端(Author类的main函数,模拟使用Paper和Author类)
git commit到v1.0 oop
让Paper类具备在Collections中的排序功能:
- 方案0:自行编写排序功能
- 方案1:使用Comparator
- 方案2:使用Comparable
实现方案2
git commit到v1.1 use comparator for sorting papers
重新编写和执行JUnit测试用例
对Paper类的各函数进行测试
对Author类的各函数进行测试
构造GUI
为用户开发一个GUI,让用户输入一组论文题目和引用数,计算出HIndex
使用JFrame,创建新GUI类
读取文本文件
在GUI上选择一个文件,从文本文件里读取数据,写入Paper对象和Collections
总结
本次习题课主要是为之前帮助Java没有了解的同学用Java编写项目。比如老师为同学们介绍了很多在编写Java项目中常用的方法或类,着重强调了与之前学过的C语言不同的地方,帮助同学们顺利完成实验一。
上一篇: 软件构造课堂笔记(2)初识设计模式
下一篇: 《软件构造》Lab 2
推荐阅读
-
win2008 r2因为使用安全设置软件导致权限丢失无法打开磁盘的解决方法
-
网络限速软件p2p终结者怎么用?p2p终结者使用图文教程
-
win2008 r2因为使用安全设置软件导致权限丢失无法打开磁盘的解决方法
-
keil uvision2怎么仿真?Keil uVision2进行软件仿真调试的方法教程
-
如何阻止局域网用户使用P2P软件下载
-
ipad mini2怎么下载软件和游戏需要什么辅助工具
-
华硕2t硬盘容量限制工具Disk Unlocker软件使用教程
-
网络限速软件p2p终结者怎么用?p2p终结者使用图文教程
-
小米电视2怎么安装软件?小米电视2安装第三方软件教程
-
3D Video Converter如何安装激活?2D转3D软件安装激活教程