[Java]题目集1-3总结
一.前言:
总结三次题目集的知识点、题量、难度等情况:
对于入门Java的第一次题目集,题目量虽然多了点,但基本都是很基础的入门题目,同时题目的设置上也是有一定的跨度的,第一题的送分题以及后面的逐步深入,到了7-8的判断三角形类型便需要开始考虑算法问题了,比如等腰直角三角形、等边三角形、等腰三角形、等腰三角形与等腰直角三角形的相互包含问题,都对答题者的算法思维有一定的考量。
而到了第二次题目集,题目集的难度也增加了,从单一的只要Main函数里实现的功能,现在需要定义一个简单的类,或者数组并对他们进行使用才能够完成题目要求了,以及设置不同返回值的各种方法以满足各个功能的实现,例如第二次题目集的7-3、7-4、7-5三题以求日期、求下一天日期、求前几天后几天日期、难度逐步增大,同时也需要考虑算法的不同实现。
到了第三次题目集,可谓是见到了java的难度递增,从7-1、7-2创建一个日期类并对其进行各个部分功能的实现,到7-3的史诗级难度题目----一元多项式求导!可谓是难倒了很多的英雄好汉,从入门级的解题方法---正则表达式,便让人学的头疼,更不说它的常系数分离以及其他的运算储存,以及PTA上***钻的大数测试点......
总的来说,这三次的题目集的难度呈现指数型增长,越做越难,越来越废时间,而引发的知识点也是越来越多,很多的知识都需要同学们的自学。题目精而不烂,每一题都非常有特色,都考验着我们的思维容量与知识储备。
设计与分析:
题目集1——7-8:
题目要求:
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。
输出格式:
(1)如果输入数据非法,则输出“Wrong Format”; (2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; (3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; (3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; (5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; (6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; (7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。
源代码:
这题的难度虽然不算大,但需要考虑到一个很小的细节:等腰三角形中与等腰直角三角形的相互包含;直角三角形与等腰直角三角形的相互包含;因此在这两个三角形的If语句当中,还要进行嵌套if语句的嵌套,才能保证程序的完整运行,从而不会导致错解或者漏解的情况。
以下为SourceMonitor 的生成报表:
题目集2——7-4
题目要求:
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
要求:Main类中必须含有如下方法,签名如下:
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
- 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日
输入样例1:
在这里给出一组输入。例如:
2020 3 10
输出样例1:
在这里给出相应的输出。例如:
Next date is:2020-3-11
输入样例2:
在这里给出一组输入。例如:
2025 2 10
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
源代码:
这个题目的难度属于比较容易,只要定义类的时候认真一点,定义方法的时候认真一点便可以合理的实现本题目的需求。前提是的熟练的掌握定义类的方法与用法。
以下为SourceMonitor 的生成报表:
题目集2——7-5
题目要求:
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
- 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
- 当输入数据合法时,输出“n days ago is:年-月-日”
输入样例1:
在这里给出一组输入。例如:
2018 6 19 8
输出样例1:
在这里给出相应的输出。例如:
8 days ago is:2018-6-11
输入样例2:
在这里给出一组输入。例如:
2018 6 19 -8
输出样例2:
在这里给出相应的输出。例如:
-8 days ago is:2018-6-27
源代码:
import java.util.Scanner;
public class Main {
//判断闰年
public static boolean isLeapYear(int year) {
boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
return isLeapYear;
}
//判断日期的合理性
public static boolean checkInputValidity(int year, int month, int day) {
boolean result = false;
if (year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
//输入数据的基本合理性检测
if (month == 2 && day >= 29) {
result = false;
} else {
result = true;
}
}
return result;
}
//判断日期的余数的正负
public static boolean tf(int day,int n) {
int theEnd = day - n;
boolean r ;
if(theEnd>=0){
r = true;
}else{
r =false;
}
return r;
}
//计算日期的余数
public static int result(int day,int n){
int result =day -n;
return result;
}
//计算核心
public static void endResult(int year,int month,int day,int n,int monthArry[]) {
if (isLeapYear(year)) {
monthArry[2] = 29;
if ((tf(day, n) && (day - n <= monthArry[month]))) {
System.out.println(n + " days ago is:" + year + "-" + month + "-" + day);
} else {
if (!(tf(day, n))) {
int temp = 0 - (day - n);
if (month - 1 < 1) {
year -= 1;
month = 13;
}
System.out.printf("%d days ago is:%d-%d-%d\n", n, year, month - 1, monthArry[month - 1] - temp);
} else {
int temp = day - n - monthArry[month];
if (month + 1 > 12) {
year += 1;
month = 0;
}
System.out.printf("%d days ago is:%d-%d-%d\n", n, year, month + 1, temp);
}
}
}
else{
if ((tf(day, n) && (day - n <= monthArry[month]))) {
System.out.println(n + " days ago is:" + year + "-" + month + "-" + day);
} else {
if (!(tf(day, n))) {
int temp = 0 - (day - n);
if (month - 1 < 1) {
year -= 1;
month = 13;
}
System.out.printf("%d days ago is:%d-%d-%d\n", n, year, month - 1, monthArry[month - 1] - temp);
} else {
int temp = day - n - monthArry[month];
if (month + 1 > 12) {
year += 1;
month = 0;
}
System.out.printf("%d days ago is:%d-%d-%d\n", n, year, month + 1, temp);
}
}
}
}
//主函数
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int year = sc.nextInt();
int month = sc.nextInt();
int day = sc.nextInt();
int n = sc.nextInt();
int[] monthArray = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(checkInputValidity(year,month,day)){
endResult(year,month,day,n,monthArray);
}else{
System.out.println("Wrong Format");
}
}
}
题目小结:本题需要创建一个月份数组进行每个不同的月份进行天数的存储,从而实现每一个月的前N天的进一退一,保证不会出现正常的逻辑错误,
相较于同类型的其他题目这个题目的难度要大很多,要考虑很多情况,其中包括闰年的二月份,非闰年的二月份以及其他的特殊月份的考虑。
其中还需要判断对输入年月日的合理性,比如闰年的二月份的29/30天的情况等等,需要满足人类认知里的日期合理性。
以下为SourceMonitor 的生成报表:
题目集3——7-2
题目要求:
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000]
,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
- 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
输入样例1:
在这里给出一组输入。例如:
1912 12 25
输出样例1:
在这里给出相应的输出。例如:
Next day is:1912-12-26
输入样例2:
在这里给出一组输入。例如:
2001 2 30
输出样例2:
在这里给出相应的输出。例如:
Date Format is Wrong
源代码:
import java.util.Scanner;
public class Main {
public static class Date{
private int year;
private int month;
private int day;
int[] mon_maxnum = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
//判断日期的合理性
public boolean checkInputValidity(int year, int month, int day) {
boolean result = false;
if (year >= 1900 && year <= 2000 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
//输入数据的基本合理性检测
if(isLeapYear(year)) {
if (month == 2 && day > 29) {
result = false;
} else {
result = true;
}
}else if (month == 2 && day > 28) {
result = false;
} else {
result = true;
}
}
return result;
}
//判断闰年
public boolean isLeapYear(int year) {
boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
return isLeapYear;
}
public boolean whichmonth(int month) {
boolean tf ;
//31天的月份
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
tf = true;
} else {
//30天的月份
tf = false;
}
return tf;
}
public void nextDate(int year, int month, int day) {
//闰年日期变化
if (isLeapYear(year)) {
if (month == 2 && day == 29) {
month += 1;
day = 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
} else if (whichmonth(month) && day == 31) {
if (month == 12) {
year += 1;
month = 1;
day = 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
else {
month += 1;
day = 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
} else if((!whichmonth(month) )&& day == 30){
month +=1;
day =1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
} else {
day += 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
} else {
//平年日期变化
if (month == 2 && day == 28) {
month += 1;
day = 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
} else if (whichmonth(month) && day == 31) {
if (month == 12) {
year += 1;
month = 1;
day = 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
} else {
month += 1;
day = 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
} else {
day += 1;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
}
}
}
public static void main(String[] args) {
Date date =new Date();
Scanner sc =new Scanner(System.in);
date.year =sc.nextInt();
date.month =sc.nextInt();
date.day =sc.nextInt();
if(date.checkInputValidity(date.year,date.month,date.day)){
date.nextDate(date.year,date.month,date.day);
}else{
System.out.println("Date Format is Wrong");
}
}
}
题目小结:
这个题目的基本算法和上一题的基本一样,只不过这一题需要定义一个全新的类进行解答,考验了学生对类的了解与掌握,以及对类方法的应用,对定义
对象的正确使用等等。
以下为SourceMonitor 的生成报表:
题目集3——7-3
题目要求:一元多项式求导(类设计)
编写程序性,实现对简单多项式的导函数进行求解
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
- 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
- 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
- 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
- 当输出结果第一项系数符号为“+”时,不输出“+”;
- 当指数符号为“+”时,不输出“+”;
- 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
输出格式见输入输出示例。
输入样例1:
在这里给出一组输入。例如:
-2* x^-2+ 5*x^12-4*x+ 12
输出样例1:
在这里给出相应的输出。例如:
4*x^-3+60*x^11-4
输入样例2:
在这里给出一组输入。例如:
2*x^6-0*x^7+5
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
源代码:
import java.util.Scanner;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String totalRegex = "(([-+]?[1-9][0-9]*)" + "(\\*?[+-]?x(\\^([+-]?[1-9][0-9]*))?)?)+";//判断表达式
String sbuRegex = "[-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[0-9]+)?";//提取每一项
String numRegex = "[-+]?[0-9]+";//数字项
String nunm ="[-+]?[0-9]\\*";
String xishu ="[-+]?[0-9]*";
Scanner sc =new Scanner(System.in);
String input1 = sc.nextLine();
System.out.println(input1);
String input = input1.replace(" ", "");//去除其中的所有空格
System.out.println(input);
//input="2*x^6-0*x^7+5";
ArrayList listNum =new ArrayList();
ArrayList listXshu = new ArrayList();
ArrayList listXshuResult =new ArrayList();
boolean bl = Pattern.matches(totalRegex, input);
if (bl == true) {
Pattern pattern= Pattern.compile(sbuRegex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
String tmp = matcher.group();
int begin = matcher.start();
int end = matcher.end();
Boolean isNum =Pattern.matches(numRegex,tmp);
if(tmp.equals("+x")){
int a = 1;
listNum.add(a);
}
if(tmp.equals("-x")){
int a =-1;
listNum.add(a);
}
if(!isNum) {
Pattern p = Pattern.compile(numRegex);
Matcher m = p.matcher(tmp);
while (m.find()) {
String a = m.group();
BigInteger aB = new BigInteger(a);
listXshu.add(aB);
if (end == input.length())
break;
}
}
}
for (int i = 0; i < matcher.groupCount() ; i++) {
int groupResult =listXshu.size();
if(groupResult>1) {
int a = 0;
int b = 1;
BigInteger a1 = (BigInteger) listXshu.get(a);
BigInteger a2 = (BigInteger) listXshu.get(b);
BigInteger aResult = a1.multiply(a2);
BigInteger a2Result = a2.subtract(BigInteger.valueOf(1));
listXshuResult.add(aResult);
listXshuResult.add(a2Result);
listXshu.remove(0);
listXshu.remove(0);
}
}
int a = (int) listNum.get(0);
System.out.println(listXshuResult.get(0)+"*x^"+listXshuResult.get(1)+"+"+listXshuResult.get(2)+"*x^"+listXshuResult.get(3)+listXshu.get(0));
//连接
} else
System.out.println("Wrong Format");
}
}
题目分析:
由于本题的难度跨度实属太大,所以这里只展示本人的小想法,这题的正则表达式、匹配函数、替代函数、以及
涉及到了函数的拼接。
以下展示大佬的代码:
五、总结:
对于入门Java的第一次题目集,题目量虽然多了点,但基本都是很基础的入门题目,同时题目的设置上也是有一定的跨度的,第一题的送分题以及后面的逐步深入,到了7-8的判断三角形类型便需要开始考虑算法问题了,比如等腰直角三角形、等边三角形、等腰三角形、等腰三角形与等腰直角三角形的相互包含问题,都对答题者的算法思维有一定的考量。
而到了第二次题目集,题目集的难度也增加了,从单一的只要Main函数里实现的功能,现在需要定义一个简单的类,或者数组并对他们进行使用才能够完成题目要求了,以及设置不同返回值的各种方法以满足各个功能的实现,例如第二次题目集的7-3、7-4、7-5三题以求日期、求下一天日期、求前几天后几天日期、难度逐步增大,同时也需要考虑算法的不同实现。
到了第三次题目集,可谓是见到了java的难度递增,从7-1、7-2创建一个日期类并对其进行各个部分功能的实现,到7-3的史诗级难度题目----一元多项式求导!可谓是难倒了很多的英雄好汉,从入门级的解题方法---正则表达式,便让人学的头疼,更不说它的常系数分离以及其他的运算储存,以及PTA上***钻的大数测试点......
总的来说,这三次的题目集的难度呈现指数型增长,越做越难,越来越废时间,而引发的知识点也是越来越多,很多的知识都需要同学们的自学。题目精而不烂,每一题都非常有特色,都考验着我们的思维容量与知识储备。