java之第一次实验总结
首先,来到题目集一的7-8
上题目
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(a+b>c&&c-b<a)
//判断能否组成三角形
请看各三角形的判断条件
(由于普通三角形类型比较多,这里先判断其他特殊三角形)
献给三边排个序
if(a>b) {
float temp = a;
a=b;
b=temp;
}
if(a>c) {
float temp = a;
a=c;
c=temp;
}
if(b>c) {
float temp = b;
b=c;
c=temp;
}
进入判断过程
if(a==b||b==c||a==c)//判断是否有两边相等
{
if((a*a+b*b-c*c<=0.00001))//是否符合构成直角三角形
System.out.println("Isosceles right-angled triangle");
else//如不是,则为普通等腰三角形
System.out.println("Isosceles triangle");
}
else if((a*a+b*b-c*c<=0.00001)&&(a==b))//判断是否为等腰直角三角形
System.out.println("Isosceles right-angled triangle");
else if(a==b&&a==c)//判断等边三角形
System.out.println("Equilateral triangle");
else if((a!=b&&a!=c&&b!=c)&&(a*a+b*b!=c*c))//判断为普通三角形
System.out.println("General triangle");
else//以上条件不成立则为普通直角三角形
System.out.println("Right-angled triangle");
else//对应上面判断三角的条件
System.out.println("Not a triangle")
else//对应上边三边是否合法
System.out.println("Wrong Format");
踩坑:判断三角形最重要的就是仔细,一定要小心谨慎,不能遗漏每一种情况,不然就会有测试点过不去。还有就是,(a*a+b*b-c*c<=0.00001)
,这个是判断直角的,写等号就会报错
来看题目集的7-4、7-5
7-4 求下一天 (30 分)
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[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:年-月-日
上代码
public static void main(String[] args) {//main函数
Scanner input = new Scanner(System.in);
int year = input.nextInt();//输入年份
int month = input.nextInt();//输入月份
int day = input.nextInt();//输入那一天
if (checkInputValidity(year, month, day)) {//检查输入是否正确方法
nextDate(year, month, day);//求下一天方法
}
}
```java
public static boolean isLeapYear(int year) {//判断年份是否为闰年,采用布尔型方法
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//闰年的判断条件
return true;
else
return false;
}
public static void nextDate(int year, int month, int day) { //求输入日期的下一天
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)//这个方法有点复杂,其实可以用数组来代替 {
if (day < 1 || day > 31) {//数据输入错误
System.out.println("Wrong Format");
} else if (day == 31 && month != 12) {//非12月的最后一天(前提已是有31天的月份)
System.out.println("Next date is:" + year + "-" + ++month + "-" + 1);
} else if (month == 12 && day == 31) {//12月的最后一天(前提已是有31天的月份)
System.out.println("Next date is:" + ++year + "-" + 1 + "-" + 1);
} else {//正常情况则为天数++
System.out.println("Next date is:" + year + "-" + month + "-" + ++day);
}
} else if (month == 2) {//二月特殊情况
if (day < 1 || day > 29) {
System.out.println("Wrong Format");//不管是否闰年,一旦超29提前你直接输出错误
} else if (day == 29 && isLeapYear(year)) {//闰年二月最后一天
System.out.println("Next date is:" + year + "-" + ++month + "-" + 1);
} else if (day == 28 && !isLeapYear(year)) {//非闰年二月最后一天
System.out.println("Next date is:" + year + "-" + ++month + "-" + 1);
} else {//非闰年二月普通的一天
System.out.println("Next date is:" + year + "-" + month + "-" + ++day);
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {//为30天的月份
if (day < 1 || day > 30) {//超过30天·直接输出错误
System.out.println("Wrong Format");
} else if (day == 30) {//月末则++month(如果用month++则会导致输出的为输入的月份)
System.out.println("Next date is:" + year + "-" + ++month + "-" + 1);
} else {//普通一天情况
System.out.println("Next date is:" + year + "-" + month + "-" + ++day);
}
}
}
public static boolean checkInputValidity(int year, int month, int day) {//检查输入的数据是否正确
if (year < 1820 || year > 2020 || month < 1 || month > 12) {//与条件不符输出错误
System.out.println("Wrong Format");
return false;//方法返回false
} else if (month == 2) {//二月特殊情况
if (!isLeapYear(year)&&(day < 1 || day > 28)||isLeapYear(year) && (day > 29|| day < 1)) {
System.out.println("Wrong Format");
return false;
} else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)&&(day < 1 || day > 31)||(month == 4 || month == 6 || month == 9 || month == 11 )&&(day < 1 || day > 30))//这里也可以用数组 {
System.out.println("Wrong Format");
return false;
}
}
return true;
}
这题用数组会方便很多,就是我踩的坑之一,7-3限制了行数长度,这样用就过不了。
改进:下面的7-5,我将用数组,代码会简单很多就像:
shuzu = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//shuzu[1]就是一月份,对应31天,以下的一样
7-5:求前N天 (30 分)
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
当输入数据合法时,输出“n days ago is:年-月-日”
main方法就不赘述了,直接上其他方法
public static boolean isLeapYear(int year) {//判断闰年的方法还是一样的
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return true;
else
return false;
}
public static void manydayafter(int year, int month, int day,int bian) { //求输入日期的下或上好多天
int[] shuzu;//在每个方法里都要先申明这个数组
int i;
shuzu = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (i = 0; i < 12; i++) {
if (i == month)//定义变量i用来标记输入的月份
break;
}
if (isLeapYear(year)) {//如果是闰年的话呢,代表二月份的数组里面的数据变成29
shuzu[2] = 29;
}
day=day-bian;//day为改变后的天数
if(bian>0){//1 2 3
if(day>0){//天数大于零
System.out.println(bian +" days ago is:" + year + "-" + month + "-" + day);
}
else if(day<=0&&month!=1){//变化后的天数小于零,且月份不是一月的话,就--month
day=shuzu[i-1]+day;
System.out.println(bian +" days ago is:" + year + "-" + --month + "-" + day);
}
else if(day<0&&month==1){//是一月的话,year就要减一
day=31+day;//减一回到上一年的12月,所以day+=31
System.out.println(bian +" days ago is:" + --year + "-" + "12" + "-" + day);
}
}
else{//1 2 -3
while (day>shuzu[month]) {
day-=shuzu[month];
month++;
if (month==13){
month-=12;
year++;
}
}
System.out.println(bian +" days ago is:" + year + "-" + month + "-" + day);
}
}
以上就是用数组存月份的方便,代码很是简洁。
7-3 一元多项式求导(类设计) (50 分)
编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 OO作业3-3题目说明.pdf
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
当输出结果第一项系数符号为“+”时,不输出“+”;
当指数符号为“+”时,不输出“+”;
当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
这题对于现在的我还是相当的,嗯,对有难度。哈哈哈哈,没有花太多时间去弄这题,以下的代码是结束之后,在弄得哈哈哈哈
正则表达式//点击可以学习正则
上代码:
import java.math.BigInteger;
import java.util.Scanner;
import java.lang.Integer;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ct {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int z;
//String pipei = "([-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[1-9]+[0-9]*)?)+";
//String A;
//String s = input.nextLine();
String totalRegex = "([-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[1-9]+[0-9]*)?)+";//正则表达式,这个适用于搜索全部的
String sbuRegex = "[-+]?([1-9]+[0-9]*(\\*)?)?x?(\\^[+-]?[1-9]+[0-9]*)?";//没有+则是一小段的
String sbuRegex1 = "([-+]?([1-9])?[0-9])+";//这是判断搜索系数与指数的
String s1 = input.nextLine();
//String s1="+2*x^-2+2*x^12-4*x+12";
//String s1="2*x^6-0*x^7+5";
//String s1="12+3*x^2+4*x^-2-3*x^-3-4*x^2+12";
String regex = " ";//定义一个字符串,里面有空格
String regex2 = "+";
String ss = "";//定义字符串
String END="";
String W,W2;//定义两个字符串,后期存储字符
String result = s1.replaceAll(regex, ss);//这个函数的功能为将后面字符串里面的空格清空
int flag=0;
for(int j=0;j<result.length();j++){
if(result.charAt(j)=='x'){
flag=1;//判断是否有x
}
}
if(flag==0){
System.out.println("0");//没有出现直接输出0
return;
}
//result="+2*x^-2+5*x^12-4*x+12";
//input="2*x^6-0*x^7+5";
boolean bl = Pattern.matches(totalRegex, result);//以下就是正则了
if (bl == true) {
Pattern pattern = Pattern.compile(sbuRegex);
Matcher matcher1 = pattern.matcher(result);
while (matcher1.find()) {
int a[]=new int[3];
int k=0;
String tmp = matcher1.group()//找到每一个小组,存在tmp中;
int begin = matcher1.start();//tmp起始位置
int end = matcher1.end();//tmp结束位置
//System.out.println(tmp);
END+=gai(tmp);//gai为定义的放法,用来求导,END是用来存储求导后的
if (end == result.length())
break;
}
char d[];//后面定义的字符串数组是为了排除第一个为加号的情况第一个为+就把+消掉
int k=0;
d=new char[END.length()];
for(int j=0;j<END.length();j++){//将END存在字符串里
d[j]=END.charAt(j);
k++;
}
if(d[0]=='+'){//如果第一个为+,则置零
d[0]='\0';
}
for(int j=0;j<k;j++){
System.out.print(d[j]);//打印后面的结果
}
//System.out.println(END);
} else//非正常数据输入错误
System.out.println("Wrong Format");
}
public static String gai(String A){//求导的方法
//System.out.println(A);
String w3="";
int flag=0,flag2=0;
for(int i=0;i<A.length();i++){//判断是否为全数字
if(A.charAt(i)=='x'){
flag=1;
}
if(A.charAt(i)=='^'){
flag2=1;
}
}
if(flag==0){
A="";//是全数字,就将A等于空字符串
}
else if(flag2==0&&flag==1){//这是一次项的情况,将x消除
String regex = "x";
String s = "\\*";
String ss = "";
String result = A.replaceAll(regex, ss);
A=result.replaceAll(s, ss);
//System.out.print(A);
w3+=A;
}
else {//以下为二次项
int j1 = 0;
if (A.charAt(j1) == '-') {// -5*x^12
String s2 = "";//存系数
String s3 = "";//存指数
for (int i = 0; A.charAt(i) != '*'; i++) {
s2 += A.charAt(i);//存系数
}
for (int i = 0; i < A.length(); i++) {
if (A.charAt(i) == '^') {
for (int j = i + 1; j < A.length(); j++) {
s3 += A.charAt(j);//存指数
}
}
}
// System.out.println(s2);
// System.out.println(s3);
int z = Integer.valueOf(s2, 10);//此方法是将字符串转十进制数字
int z1 = Integer.valueOf(s3, 10);
int a1 = z * z1;//求导系数
int a2 = z1 - 1;//求导指数
//System.out.println(s2);
// System.out.println(a1);
// System.out.println(s3);
// System.out.println(a2);
String W = Integer.toString(a1);//将求导后的转化成字符串
String W2 = Integer.toString(a2);
if (a1 > 0 && a2 != 1) {//系数大于0,指数不为1
w3+="+" + a1 + "*x^" + a2;
//System.out.print("+" + a1 + "*x^" + a2);
} else if (a1 < 0 && a2 != 1) {//系数小于0,指数不为1
w3+=a1 + "*x^" + a2;
//System.out.print(a1 + "*x^" + a2);
} else if (a1 > 0 && a2 == 1) {//系数大于0,指数为1
w3+="+"+a1 + "*x";
//System.out.print(a1 + "*x");
} else if(a1 < 0 && a2 == 1) {//系数小于0,指数为1
w3+=a1 + "*x";//w3存结果
//System.out.print(a1 + "*x");
}
}
if (A.charAt(j1) == '+'){//第一个字符为+
j1 = 0;
String s2 = "";//存系数
String s3 = "";//存指数
for (int i = 0; A.charAt(i) != '*'; i++) {
s2 += A.charAt(i);
}
for (int i = 0; i < A.length(); i++) {
if (A.charAt(i) == '^') {
for (int j = i + 1; j < A.length(); j++) {
s3 += A.charAt(j);
}
}
}
// System.out.println(s2);
// System.out.println(s3);
int z = Integer.valueOf(s2, 10);
int z1 = Integer.valueOf(s3, 10);
int a1 = z * z1;
int a2 = z1 - 1;
//System.out.println(s2);
// System.out.println(a1);
// System.out.println(s3);
// System.out.println(a2);
String W = Integer.toString(a1);
String W2 = Integer.toString(a2);
if (a1 > 0 && a2 != 1) {
w3+="+" + a1 + "*x^" + a2;
//System.out.print("+" + a1 + "*x^" + a2);
} else if (a1 < 0 && a2 != 1) {
w3+=a1 + "*x^" + a2;
//System.out.print(a1 + "*x^" + a2);
} else if (a1 > 0 && a2 == 1) {
w3+="+"+a1 + "*x";
//System.out.print(a1 + "*x");
} else if(a1 < 0 && a2 == 1) {
w3+=a1 + "*x";
//System.out.print(a1 + "*x");
}
}
else if(A.charAt(j1) != '+'&&A.charAt(j1) != '-'){
j1 = 0;
String s2 = "";//存系数
String s3 = "";//存指数
for (int i = 0; A.charAt(i) != '*'; i++) {
s2 += A.charAt(i);
}
for (int i = 0; i < A.length(); i++) {
if (A.charAt(i) == '^') {
for (int j = i + 1; j < A.length(); j++) {
s3 += A.charAt(j);
}
}
}
// System.out.println(s2);
// System.out.println(s3);
int z = Integer.valueOf(s2, 10);
int z1 = Integer.valueOf(s3, 10);
int a1 = z * z1;
int a2 = z1 - 1;
//System.out.println(s2);
// System.out.println(a1);
// System.out.println(s3);
// System.out.println(a2);
String W = Integer.toString(a1);
String W2 = Integer.toString(a2);
if (a1 > 0 && a2 != 1) {
w3+="+" + a1 + "*x^" + a2;
//System.out.print("+" + a1 + "*x^" + a2);
} else if (a1 < 0 && a2 != 1) {
w3+=a1 + "*x^" + a2;
//System.out.print(a1 + "*x^" + a2);
} else if (a1 > 0 && a2 == 1) {
w3+="+"+a1 + "*x";
//System.out.print(a1 + "*x");
} else if(a1 < 0 && a2 == 1) {
w3+=a1 + "*x";
//System.out.print(a1 + "*x");
}
}
}
//System.out.println(A);
return w3;
}
}
先说几个坑吧:在没确定代码的正确性时,不要用从键盘里输入数据,直接赋值他不下香吗,省下一大笔时间
还有就是字符串是可以直接加的
心得:学会了字符串类型之间的转换,学会了如何正确的分类情况,学会了使用类,学会了用数组存储月份的天数,这个真的是很巧妙。