pta第一次Blog作业
1、前言:
这是第一次java的pta作业,涉及知识点不是很多,比较基础,所以并难度不大,但是相比之前学习c语言的时候的题量变多。
2、试题分析:
第一次题目集
7-5 去掉重复的字符
输入格式:
一行字符串
输出格式:
去掉重复字符后的字符串
输入样例:
在这里给出一组输入。例如:
查看代码
ofiweirowqrigu
输出样例:
在这里给出相应的输出。例如:
查看代码
ofiwerqgu
源码如下:
查看代码
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
char ch1,ch2;
Scanner input=new Scanner(System.in);
String str=input.nextLine();
int flag=0,a=str.length();
for(int i=0;i<a;i++)
{
ch1=str.charAt(i);
flag=0;
for(int j=0;j<i;j++)
{
ch2=str.charAt(j);
if(ch1==ch2)
{
flag=1;
break;
}
}
if(flag==0)
System.out.print(ch1);
}
}
}
设计与分析:
在写这道题目时其实是取巧了的,因为要求输出字符串,而我在判断之后直接输出了不重复的字符,虽然最后答案是一样,但不完全对。源码里主要使用两个循环对字符串每一个字符判断是否重复,再对不重复的字符进行输出。
踩坑心得:
题目比较简单没什么坑。
改进建议:
将循环中的输出字符改为连接字符成为字符串,最后加一个输出字符串的语句。
7-7 有重复的数据
在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。
你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。
输入格式:
你的程序首先会读到一个正整数n,n∈[1,100000],然后是n个整数。
输出格式:
如果这些整数中存在重复的,就输出:YES
否则,就输出:NO
输入样例:
查看代码
5
1 2 3 1 4
输出样例:
查看代码
YES
源码如下:
查看代码
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner b=new Scanner(System.in);
int n=b.nextInt();
int flag=0,num=0;
int a[]=new int[100000];
for(int i=0;i<n;i++)
{
flag=0;
num=0;
a[i]=b.nextInt();
for(int j=i;j>=0;j--)
{
if(a[i]==a[j])
{
num++;
}
if(num==2)
{
flag=1;
break;
}
}
if(flag==1)
{
System.out.print("YES");
break;
}
}
if(flag==0)
{
System.out.print("NO");
}
}
}
设计与分析:
源码中采用了边输入边判断之前有没有输入过重复的字符,对比输入之后再双循环判断提升了一点效率。但对于数值很大很大的重复判断还是太慢效率没什么提升,所以最后两个测试点没过。

踩坑心得:
在平常写接触到循环的代码时应要注意效率问题,要养成这个习惯。
改进建议:
使用更加简便快速的方法比如首尾同时判断和二分法查找,当然也要根据具体的情况来决定。
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”。
输入样例1:
在这里给出一组输入。例如:
查看代码
50 50 50.0
输出样例1:
在这里给出相应的输出。例如:
查看代码
Equilateral triangle
输入样例2:
在这里给出一组输入。例如:
查看代码
60.2 60.2 80.56
输出样例2:
在这里给出相应的输出。例如:
查看代码
Isosceles triangle
输入样例3:
在这里给出一组输入。例如:
查看代码
0.5 20.5 80
输出样例3:
在这里给出相应的输出。例如:
查看代码
Wrong Format
源码如下:
查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
float a=input.nextFloat();
float b=input.nextFloat();
float c=input.nextFloat();
int flag=0;
if(a<1||a>200||b<1||b>200||c<1||c>200)
flag=1;
else {
if(a+b<=c||a+c<=b||b+c<=a)
flag=2;
else {
if(a==b&&b==c&&a==c){
flag=3;
}
else if(a==b||a==c||c==b){
flag=4;
if(Math.abs(a*a-(b*b+c*c))<=1e-6||Math.abs(b*b-(c*c+a*a))<=1e-3||Math.abs(c*c-(a*a+b*b))<=1e-3){
flag=5;
}
}
else if(Math.abs(a*a-(b*b+c*c))<=1e-6||Math.abs(b*b-(c*c+a*a))<=1e-3||Math.abs(c*c-(a*a+b*b))<=1e-3){
flag=6;
}
else flag=7;
}
}
if(flag==1)
System.out.print("Wrong Format");
if(flag==2)
System.out.print("Not a triangle");
if(flag==3)
System.out.print("Equilateral triangle");
if(flag==4)
System.out.print("Isosceles triangle");
if(flag==5)
System.out.print("Isosceles right-angled triangle");
if(flag==6)
System.out.print("Right-angled triangle");
if(flag==7)
System.out.print("General triangle");
}
}
设计与分析:
使用多个if语句嵌套来达到判断的目的并改变flag的值,最后通过判断flag的值来输出对应结果。
踩坑心得:
对于判断的逻辑有点难以确定,事先应该在草稿纸上弄一个大致的模板,我在pta上提交答案错误之后又在草稿纸上写了一下各判断层级的优先级,后来才慢慢改对。但最后尽管逻辑正确,还是出现了问题,问题出现在对等腰直角三角形的判断那个测试点,因为是计算机语言不能和正常数学计算那样精确判断平方和相等,而是应该判断两者的差距大小小于一个范围从而来判断两者相等,以后在对浮点数的计算结果进行判断的时候应要多考虑到这一点。


修改之后:

改进建议:
用大量if语句使阅读起来较难,并且排版不好看,可以将if语句改成swich结构,使排版美观,结构清晰。
第三次题目集
7-3 定义日期类
定义一个类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 void main(String[] args){
Scanner input=new Scanner(System.in);
int year=input.nextInt();
int month=input.nextInt();
int day=input.nextInt();
Date a = new Date(year,month,day);
a.getNextDate();
}
}
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 Date(){
this.year=year;
this.month=month;
this.day=day;
}
public Date(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public int getYear(){
return year;
}
public int getMonth(){
return month;
}
public int getDay(){
return day;
}
public int setYear(int year){
return this.year=year;
}
public int setMonth(int month){
return this.month=month;
}
public int setDay(int day){
return this.day=day;
}
public boolean isLeapYear(int year){
if(year%400==0||year%4==0&&year%100!=0)
return true;
else return false;
}
public boolean checkInputValidity(){
if(year<=2000&&year>=1900&&month>=1&&month<=12&&day>=1){
if(isLeapYear(year)&&month==2){
if(day<=29)
return true;
else return false;
}
else if(day<=mon_maxnum[month])
return true;
else return false;
}
else return false;
}
public void getNextDate(){
if(checkInputValidity()){
if(isLeapYear(year)&&month==2&&day==29){
day=1;
month++;
}
else if(day==mon_maxnum[month]){
if(month==12){
year++;
month=1;
day=1;
}
else {
day=1;
month++;
}
}
else day++;
System.out.println("Next day is:"+year+"-"+month+"-"+day);
}
else System.out.println("Date Format is Wrong");
}
}
设计与分析:
这次题目集接触到了类的相关知识,通过前两题的练习基本有个大致了解,这道题主要涉及的是日期相关常识,由于之前c语言课程设计的题目与这个有部分重合,都需要判断日期,所以大致比较熟悉了,再经过老师之前的提醒,将月份最大的天数放入数组中,方便了很多,但特殊的二月份还是有问题,并且对无效值少考虑了一些情况,部分不存在的日期判断错误了,最后又仔细读了一遍题目,把程序重新读了几遍才改对。

踩坑心得:
对于这种常识有印象的也不能掉以轻心,多思考其中的细节。
改进建议:
还是用if语句用得太多,不太好看不太好读,改成swich会好一点。
7-4 日期类设计
参考题目3和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:
查看代码
public boolean checkInputValidity();//检测输入的年、月、日是否合法
public boolean isLeapYear(int year);//判断year是否为闰年
public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等
public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数
public String showDate();//以“year-month-day”格式返回日期值
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
程序主方法如下:
查看代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(
date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format - 当第一个数字为1且输入均有效,输出格式如下:
查看代码
year1-month1-day1 next n days is:year2-month2-day2 - 当第一个数字为2且输入均有效,输出格式如下:
查看代码
year1-month1-day1 previous n days is:year2-month2-day2 - 当第一个数字为3且输入均有效,输出格式如下:
查看代码
The days between year1-month1-day1 and year2-month2-day2 are:值
输入样例1:
在这里给出一组输入。例如:
查看代码
3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:
查看代码
The days between 2014-2-14 and 2020-6-14 are:2312
输入样例2:
在这里给出一组输入。例如:
查看代码
2 1834 2 17 7821
输出样例2:
在这里给出相应的输出。例如:
查看代码
1834-2-17 previous 7821 days is:1812-9-19
输入样例3:
在这里给出一组输入。例如:
查看代码
1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:
查看代码
1999-3-28 next 6543 days is:2017-2-24
输入样例4:
在这里给出一组输入。例如:
查看代码
0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:
查看代码
Wrong Format
设计与分析:
本题与上题有共同之处,本题求下n天相当于进行n次的上一题的求下一天,求上n天相当于进行n次求上一天,求两天相差天数相当于一直加或一直减直到等于另一个日期。总体难度还行,主要是因为有一个循序渐进的过程,源码中是进行了对日期的循环累加或累减,有对应特殊的变化,达到功能的实现。

踩坑心得:
还是二月的问题最大,一开始并没有用和上一题一样的思路,而是通过判断n的大小对n进行年月日天数的累加或累减,但是相对于直接对日期进行累加或累减太过繁琐,没有写对,换了一种方法之后再注意一下事最多的二月份,然后又出现了一些逻辑问题,又重新按原来的思路走一遍改了一些地方才写对。写之前还是要多想想简便方法,不要一下就埋头做。
改进建议:
对日期一天天累加虽然逻辑更加简单,但是当n非常大时,程序就需要许多时间来得出结果,效率不是很高,可以用逻辑更复杂的对n的大小判断再做对应处理的方法,可以减少很多运行的时间。
3、总结:
这是第一次java作业,知识点都比较基础,学到了类的相关知识,关于字符串的一些方法,计算机中浮点数的计算。认识到java与c语言有不同之处,java是一门面对对象的语言,更符合人类的思考逻辑,哪怕还没有完全理解面向对象的语言,但应该在编程的时候多往这个方面去想。在编程时还是有一些学习c语言遗留的问题存在,比如还是会更多地以c语言的角度来想怎么写,以后应该多多适应java的模式,多练多看多学。在编程时要多思考算法,最好是在草稿纸上多演算几遍,结合现实生活多注重思考细节,读题更仔细,并提高对自己的要求。
浙公网安备 33010602011771号