对Java前三周学习内容及前三次作业总结

一,前言概括

在学习Java过程中的问题概括

1.大概是由于语言之间的相似之处而又刚刚结束C语言的学习,对编程语言有了一定的基础,所以java初步的语法学习得心应手,

但是语法相似的同时两者思维方向上的区别还是不小的,首先C语言是面对过程的的语言,而Java语言是面对对象的语言,

在一些编码思维上有极大的不同,因此由于有C语言思维惯性的我,遇到问题层出不穷在三次作业中可以体现(细节稍后再详细叙述)。

2.学不能以致用,不能以思辨,这里这就涉及到对于课堂上的学习内容不能做到实际应用,更没很好的去理解。

3.由于前两次题目集较为容易故选了一部分题目进行分析

二,题目集问题分析

第一次题目集:
判断三角形类型

import java.util.Scanner;

public class Main {
 
	public static void main(String[] args) {
		
	
	Scanner input =new Scanner(System.in);
	double []line =new double [3];
        double temp;
	for(int i=0;i<3;i++)
		line[i]=input.nextDouble();
	for(int i=0;i<3-1;i++)
	{
		for( int j=0;j<3-1-i;j++) {
			if(line[j]>line[j+1]) {
				 temp=line[j];
				line[j]=line[j+1];
				line[j+1]=temp;
			}
		}
	}
	
	if(1>line[0]||line[0]>200||1>line[1]||line[1]>200||1>line[2]||line[2]>200) {
		System.out.println("Wrong Format");
	}else if(line[2]>=line[1]+line[0]) {
		System.out.println("Not a triangle");
	}else if(line[0]==line[1]&&line[1]==line[2]) {
		System.out.println("Equilateral triangle");
	}else if((line[1]==line[0]||line[1]==line[2])) {
		if(line[1]==line[0]&&((2*line[1]*line[0])-(line[2]*line[2])<=0.0001))
			System.out.println("Isosceles right-angled triangle");
		else
			System.out.println("Isosceles triangle");
		}else if((Math.pow(line[1],2)+Math.pow(line[0],2))-Math.pow(line[2], 2)<=0.0001){
			System.out.println("Right-angled triangle");
		}else {
			System.out.println("General triangle");
		}
		
	}
}

Source Monitor 分析图:

由源代码分析:
编码思维体现着严重且典型的C语言思维,套用可了数组和if-else镶嵌语句进行的解决问题

由SM图分析可知,由于if-else的运用导致Average Complexity高达21

原因:大概由于初学Java只掌握了一些基础语法,算法宴席了C语言的解题方式

编码遇到的问题:
在利用勾股定理进行判断是否为直角关系时忽略了数据的基本型为双精度浮型

由于双精度浮点型的储存方式存在误差,而此时又进行了平方的计算,造成了

误差扩大,所以此时进行关系运算== 进行判断是否等价是无法得到准确的结果。

通过查阅资料
此时必须采用求差,然后其差小于10^-6时就可以判断其是相等的

第二次题目集
判断闰年及星期几

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();
		String date ="null";
		if(year<1820||year > 2020|| month<1||month>12||day<1||day>31||day>monthDays(year,month)) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
		if(isLeapYear(year)) {
			System.out.println(year+" is a leap year.");
		}else {
			System.out.println(year+" is not a leap year.");
		}
		date = getWhatDay(numOfDays(year,month,day));
		System.out.println(year+"-"+month+"-"+day+" is "+date+".");

	}
public static boolean isLeapYear(int year) {
	if(year % 400 == 0||(year % 4 == 0 && year %100 != 0))
		return true;
	return false;
}
public static int numOfDays(int year, int month, int day) {
	int num=0;
	for(int i=1;i<year;i++) {
		if(isLeapYear(i)) {
			num+=366;
		}else {
			num+=365;
		}
	}
	for(int i=1;i<month;i++) {
		num+=monthDays(year,i);
	}
	return num+day;
}
public static int monthDays(int year,int month) {
	int day = 0;
	switch(month) {
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		day =31;break;
	case 2:
		if(isLeapYear(year))
			day=29;
		else
			day=28;
		break;
	case 4:
	case 6:
	case 9:
	case 11:
		day=30;break;
	}
	return day;
}
public static String getWhatDay(int days) {
	String str="NULL";
	switch(days%7) {
	case 0:
		str ="Sunday";
		break;
	case 1:
		str = "Monday";
		break;
	case 2:
		str = "Tuesday";
		break;
	case 3:
		str = "Wednesday";
		break;
	case 4:
		str = "Thursday";
		break;
	case 5:
		str = "Friday";
		break;
	case 6:
		str = "Saturday";
		break;
	}
	return str;
}
}

Source Monitor 分析图:

** 求下一天**

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();
		if(checkInputValidity( year, month, day)) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
		
		nextDate(year,month,day);

	}

public static boolean isLeapYear(int year) {
	if(year % 400 == 0||(year % 4 == 0 && year %100 != 0))
		return true;
	return false;
}


public static boolean checkInputValidity(int year,int month,int day) {
	if(year<1820||year > 2020|| month<1||month>12||day<1||day>31||day>monthDays(year,month)) {
		return true;
	}
	return false;
}
public static int monthDays(int year,int month) {
	int day = 0;
	switch(month) {
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		day =31;break;
	case 2:
		if(isLeapYear(year))
			day=29;
		else
			day=28;
		break;
	case 4:
	case 6:
	case 9:
	case 11:
		day=30;break;
	}
	return day;
}
public static void nextDate(int year,int month,int day) {
	int mday = 0;
	mday = monthDays(year,month);
	if(day == mday) {
		if(month == 12) {
			month = 1;
			day = 1;
            year++;
		}else {
			month++;
			day = 1;
		}
	}else {
		day++;
	}
	System.out.println("Next date is:"+year+"-"+month+"-"+day);
  }
}

Source Monitor 分析图:

** 求前N天:**

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();
		int n = input.nextInt();
		if(checkInputValidity( year, month, day,n)) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
		
		nextDate(year,month,day,n);

	}
public static boolean isLeapYear(int year) {
	if(year % 400 == 0||(year % 4 == 0 && year %100 != 0))
		return true;
	return false;
}
public static boolean checkInputValidity(int year,int month,int day, int n) {
	if(year<1820||year > 2020|| month<1||month>12||day<1||day>31||day>monthDays(year,month)||n< -10||n>10) {
		return true;
	}
	return false;
}
public static int monthDays(int year,int month) {
	int day = 0;
	switch(month) {
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		day =31;break;
	case 2:
		if(isLeapYear(year))
			day=29;
		else
			day=28;
		break;
	case 4:
	case 6:
	case 9:
	case 11:
		day=30;break;
	}
	return day;
}
public static void nextDate(int year,int month,int day,int n) {
	int mday = 0;
	mday = monthDays(year,month);
	day = day - n;
	if(day > mday) {
		if(month == 12) {
			day = day -mday;
			month = 1;
			year++;
		}else {
			month++;
			day = day -mday;
		}
	}else if(day< 1) {
		if(month ==  1) {
		day = monthDays(year-1,12)+day;
		month=12;
		year--;
	}else {
		day =monthDays(year,month-1)+day;
		month--;
	}
		
	}
	System.out.println(n+" days ago is:"+year+"-"+month+"-"+day);
}
}

Source Monitor 分析图:

由于第二次题目集的后三道题类似度比较大,故整一块来分析

代码分析:
由于对视对日期进行处理的题目,三道题的核心之处都在对

该天在第几个月份,30天31天还是28.29天进行判断

从而衍生出是否月末/月初,是否是闰年进行判断从而进行下一步的处理

这些进行判断都是可以设计成方法来处理。

而SM图体现if-else的复杂度还是比较高的
优化想法:
由于对类有了更深一步学习,我认为完全可以把月份,年份和日期设计成类,这样就可以更好的解决对各项值进行操作,而不需要嵌套循环

第三次题目集

定义日期类

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Date date = new Date();
		Scanner input = new Scanner(System.in);
		int year = input.nextInt();
		int month = input.nextInt();
		int day = input.nextInt();
		date.setYear(year);
		date.setMonth(month);
		date.setDay(day);
		date.getNextDate();
	}
}
 class Date {
	private int year;
	private int month;
	private int day;
	private int mom_maxnum[] = new int[] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	public Date() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Date(int year, int month, int day) {
		super();
		this.year = year;
		this.month = month;
		this.day = day;
	}

	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 isLeapYear(int year) {
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
			return true;
		else
			return false;

	}

	public boolean checkInputValidity() {
        judge2Monthdays();
		if (this.year < 1900 || this.year > 2000 || this.month < 1 || this.month > 12 || this.day < 1
				|| this.day > mom_maxnum[this.month])
			return true;
		return false;
	}

	public void judge2Monthdays() {
		if (isLeapYear(this.year))
			this.mom_maxnum[2] = 29;
	}

	public void getNextDate() {
		int nyear = this.year;
		int nmonth = this.month;
		int nday = this.day;
		if (checkInputValidity()) {
			System.out.println("Date Format is Wrong");
			System.exit(0);
		}
		judge2Monthdays();
		if (this.day < mom_maxnum[this.month]) {
			nday++;
		} else {
			if (this.month < 12) {
				nday = 1;
				nmonth++;
			} else {
				nday = 1;
				nmonth = 1;
				nyear++;
			}
		}
		System.out.println("Next day is:" + nyear + "-" + nmonth + "-" + nday);

	}
}

Source Monitor 分析图:

代码分析:
该题是第二次题集的迭代和深入,虽然该代码使用了类,但是只是把日期设置成类,依旧没有脱离C语言的思维,

仍没把类这个概念没有把握好。

由于当时对类这个概念没有丝毫的理解,只是简单的把其当做C语言中的数据结构然后加上方法(函数)

存在的较大问题:
违背了类的几大原则:
比如说其单一责任原则

而该代码中的类其类的功能杂乱,同时方法也比较杂乱

而且方法中还是有输出

优化想法:
调整类的设计,就如前面所想,是否能把年月日分别设置成类

让其负责独自的部分,同时对方法也进行优化,让其功能单一

一元多项式求导(类设计)

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
	String line = input.nextLine();
		Check check = new Check(line);
         if(check.checkCons()){
            System.out.println("0");
		}else if(check.checkvalidty()) {
			check.Derivate();
        }else {
			System.out.println("Wrong Format");
		}

	}

}

class Check {
	private String line = null;
    private String tformat = "([ ]*[-+]?[ ]*([1-9]+[0-9]*[ ]*(\\*)?)?[ ]*(x(\\^[+-]?[1-9]+)?)?)+";
	private String subformat = "[ ]*[-+]?[ ]*([1-9]+[0-9]*[ ]*(\\*)?)?[ ]*(x(\\^[+-]?[1-9]+[0-9]*)?)?";
    private String costant = "[0-9]+";

	public Check() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Check(String line) {
		super();
		this.line = line;
	}

	public String getLine() {
		return line;
	}

	public void setLine(String line) {
		this.line = line;
	}

	public boolean checkvalidty() {

		if (line.matches(tformat)) {
			return true;
		} else {
			return false;
		}
	}
    public boolean checkCons(){
        if (line.matches(costant)) {
			return true;
		} else {
			return false;
		}
    }

	public void Derivate() {
        this.line = this.line.replace(" ", "");
		int num1 = 1, num2 = 1;
		Pattern pattern = Pattern.compile(subformat);
		Matcher matcher = pattern.matcher(line);
		int flag = 1;
		while (matcher.find()) {
			String tempString = matcher.group();
			int begin = matcher.start();
			int end = matcher.end();
			if (tempString.indexOf("x") != -1) {
				String[] string = tempString.split("(\\*)?[+-]?x(\\^)?");
				String[] string2 = tempString.split("(\\d+)(\\*)?[+-]?x(\\^)?");
				if(string.length ==0) {
					num1=1;
					num2=1;
				}else if(string2.length == 1&&string.length==2) {
					num1=1;
					num2 = Integer.parseInt(string[1]);
				}else if(string.length==1) {
					num2 = 1;
					num1 = Integer.parseInt(string[0]);
				}else {
				num1 = Integer.parseInt(string[0]);
				num2 = Integer.parseInt(string[1]);
				}
				num1 = num1 * num2;
				num2 = num2 - 1;
				if (num1 == 1 && num2 != 1&&num2 !=0) {
					if(num1>0&&flag != 1)
					System.out.print("+"+"x^");
					else
					System.out.print("x^");
					System.out.print(num2);
					flag++;
				}else if(num1 == 1 && num2 != 1&&num2 ==0){
					if(num1>0&&flag!= 1)
					System.out.print("+1");
					else
					System.out.print("1");
                    flag++;
				}else if (num1 != 1 && num2 == 1) {
					if(num1>0&&flag != 1)
					System.out.print("+"+num1 + "*x");
					else
					System.out.print(num1 + "*x");
                    flag++;
				} else if(num1 != 1 && num2 == 0){
					if(num1>0&&flag != 1)
					System.out.print("+"+num1);
					else
					System.out.print(num1);
                    flag++;
				}
				else {
					if(num1>0&&flag != 1)
					System.out.print("+"+num1 + "*x^" + num2);
					else
						System.out.print(num1 + "*x^" + num2);
                    flag++;
				}
			}
			if (end == line.length())
				break;
		}
	}
}

Source Monitor 分析图:

代码分析:

该题求导难度较大,需要用到正则表达式对字符串进行约束,以及对字符串的操作

我的代码是首先使用正则表达式对整个字符串的合法性进行判断,而后再用子项正则表达式进行group分组

进而用split去分割系数和指数,所以只能用if-else去对所有情况进行判断,进而得出结果。

出现的问题:

由于用了split去分割系数和指数,对一般的情况可以适用,但是对于指数或者系数为1,且省略的情况不再适用

因为在Eeclipse的环境下其返回值为null但是在PTA中不是,所以无法使用 if(?==null)来进行判断

故无法完成算法
代码优化:

经过老师的提点,可以把各项设置为类进行处理,这样就不需要进行对多种情况用if-esle进行一一判断

同时对大数的处理可以使用BigDecimal

三,总结

做题经验:由于PTA JAVA编译环境不同在某些地方会和eclipse不匹配

对于学习:
1.编程思想,比如说类,虽然老师已经跟我们讲了雨刷的例子,但是我们只单纯的看到了雨刷这个例子的表面

更深层次的面向对象思想没有领悟到,进而导致不能应用在题目集中。在这三次题集中,自己慢慢的意识到这个问题。

2.对正则表达式的学习,为我们打开了一个新的世界,对输入输出合法性的检测

3.对大数据的处理

4.对实型误差的处理

5.会使用debug进行错误的查找

posted @ 2021-04-04 18:12  Trash_CODER  阅读(68)  评论(0)    收藏  举报