1. 程式人生 > 其它 >題目集1~3的總結性Blog

題目集1~3的總結性Blog

一、前言

前三次題目集整體難度中等,題量也不大。尤其題目集1的大部分題目,幾乎第一次提交就通過所有測試點;題目二對我來說有一定的難度,很多測試點不能通過,所以我花費了大量的時間提交測試,雖然最終通過,但多次修改導致程式碼複雜性高,可讀性不高;題目三雖然只有三道題,但我只能寫出演算法,多次修改到最後也沒有通過測試點,找不出問題所在。

二、設計與分析

題目集1

7-8 判斷三角形型別

輸入三角形三條邊,判斷該三角形為什麼型別的三角形。

輸入格式:

在一行中輸入三角形的三條邊的值(實型數),可以用一個或多個空格或回車分隔,其中三條邊的取值範圍均為[1,200]

輸出格式:

1)如果輸入資料非法,則輸出

“Wrong Format”;(2)如果輸入資料合法,但三條邊不能構成三角形,則輸出“Not a triangle”;(3)如果輸入資料合法且能夠成等邊三角形,則輸出“Equilateral triangle”;(4)如果輸入資料合法且能夠成等腰直角三角形,則輸出“Isosceles right-angled triangle”;(5)如果輸入資料合法且能夠成等腰三角形,則輸出“Isosceles triangle”;(6)如果輸入資料合法且能夠成直角三角形,則輸出“Right-angled triangle”;(7)如果輸入資料合法且能夠成一般三角形,則輸出“General triangle”

原始碼:

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
double a = in.nextDouble();
double b = in.nextDouble();
double c = in.nextDouble();
if(a<1||b<1||c<1||a>200||b>200||c>200) {
System.out.println("Wrong Format");
}
else if(a+b<=c||a+c<=b||b+c<=a) {
System.out.println("Not a triangle");
}
else if(a==b&&b==c) {
System.out.println("Equilateral triangle");
}
else if(((a*a + b*b - c*c)<0.1||(a*a + c*c - b*b)<0.1|| (b*b + c*c - a*a)<0.1)&&(a==b||b==c||c==a)){
System.out.println("Isosceles right-angled triangle");
}
else if(a==b||b==c||c==a) {
System.out.println("Isosceles triangle");
}
else if(a*a + b*b == c*c||a*a + c*c == b*b|| b*b + c*c == a*a) {
System.out.println("Right-angled triangle");
}
else {
System.out.println("General triangle");
}

}

}

SourceMonitor的生成報表內容如下:

題目集2

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:--

原始碼:
import java.util.*;

public class Main {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
boolean m = new String() != null;
boolean n = new String() != null;
m = isLeapYear(year);
n = checkInputValidity( year, month, day);

if((m==true&&(month==2&&day>29))||(m==false&&(month==2&&day>28))|| (month == 4 && day == 31) || (month == 6 && day ==31)|| (month == 9&& day == 31)||(month == 11 && day ==31))
{
System.out.println ("Wrong Format");
}
else if (n==false)
{
System.out.println ("Wrong Format");
}
else
{
nextDate( year, month,day);
}
}
public static boolean isLeapYear(int year)
{
int flag=-1;
if(year%4==0||(year%4==0&&year%400==0))
{
flag=1;
}
else if(year%4!=0||(year%4==0&&year%400!=0))
{
flag=0;
}
if(flag==1)
{
return true;
}
else
{
return false;
}

}
public static boolean checkInputValidity(int year,int month,int day)
{
int flag;

if(year <1820 || year > 2020 || month < 1 || month > 12 || day < 1 || day > 31)
{
return false;
}
else
{
return true;
}
}
public static void nextDate(int year,int month,int day)
{
boolean m = new String() != null;

if(year%4==0||(year%4==0&&year%400==0))
{
m = true;
}
else if(year%4!=0||(year%4==0&&year%400!=0))
{
m = false;
}


if((m==true&&(month==2&&day>29))||(m==false&&(month==2&&day>28))|| (month == 4 && day == 31) || (month == 6 && day ==31)|| (month == 9&& day == 31)||(month == 11 && day ==31))
{
System.out.println ("Wrong Format");
}
else
{

String week = new String();
int f,Year = 0 ,Month = 0,Day = 0;

if((m==true&&(month==2&&day==29))||(m==false&&(month==2&&day==28))|| ((month == 4||month==6||month==9||month==11) && day == 30))
{
Month = month+1;
Day = 1;
Year = year;
}
else if (month == 12&&day==31)
{
Month = 1;
Day = 1;
Year = year + 1;
}
else if((month==1||month==3||month==5||month==7||month==8||month==10)&&day==31)
{
Month = month+1;
Day = 1;
Year = year;
}
else
{
Day = day+1;
Year = year;
Month = month;
}
System.out.println("Next date is:"+Year+"-"+Month+"-"+Day);
}
}
}

SourceMonitor的生成報表內容如下:

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:--

原始碼:
import java.util.Scanner;
public class Main {

public static void main(String[] args)
{

Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
int n = in.nextInt();
boolean m = new String() != null;
boolean o = new String() != null;
m = isLeapYear(year);
o = checkInputValidity( year, month, day);
if(o==false||n>10||n<-10)
{
System.out.println ("Wrong Format");
}
else if((m==true&&(month==2&&day>29))||(m==false&&(month==2&&day>28))|| (month == 4 && day == 31) || (month == 6 && day ==31)|| (month == 9&& day == 31)||(month == 11 && day ==31))
{
System.out.println ("Wrong Format");
}
else
{
DaysAgo (year, month, day, n);


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

}
public static boolean checkInputValidity(int year,int month,int day)
{
int flag;
if(year <1820 || year > 2020 || month < 1 || month > 12 || day < 1 || day > 31){
return false;
}
else{
return true;
}
}
public static void DaysAgo (int year,int month,int day,int n)
{
boolean m = new String() != null;
int Year = 0 ,Month = 0,Day = 0;
if(year%4==0||(year%4==0&&year%400==0)){
m = true;
}
else if(year%4!=0||(year%4==0&&year%400!=0)){
m = false;
}
if(n>0){
if(month==1&&day-n<=0)
{
Day=31-(n-day);
Month = 12;
Year = year - 1;
}
else if(day-n<=0&&(month==4||month==6||month==9||month ==11||month==8))
{
Day=31-(n-day);
Month = month - 1;
Year = year ;
}
else if (day-n<=0&&(month== 12||month==5||month==7||month==10))
{
Day=30-(n-day);
Month = month - 1;
Year = year ;
}
else if (m==true&&month==3&&day-n<=0)
{
Day=29-n+day;
Month =month - 1;
Year = year ;
}
else if (m==false&&month==3&&day-n<=0)
{
Day=28-n+day;
Month = month -1;
Year = year ;
}
else
{
Day = day - n;
Month = month;
Year = year;
}
}
else if(n<0)
{
if(month==12&&day-n>31)
{
Day = -(31-day+n);
Month = 1;
Year = year + 1;
}
else if ((month ==1 ||month ==3||month==5||month==7||month==8||month==10)&&day-n>31)
{
Day = -(31-day+n);
Month = month + 1;
Year = year;
}
else if ((month==4||month==6||month==9||month ==11)&&day-n>30)
{
Day = -(30-day+n);
Month = month + 1;
Year = year;
}
else if(m==true&&month==2&&day-n>29)
{
Day = -(29-day+n);
Month = month + 1;
Year = year;
}
else if (m==false&&month==2&&day-n>28)
{
Day = -(28-day+n);
Month = month + 1;
Year = year;
}
else
{
Day = day -n;
Month = month ;
Year = year;
}
}
else if (n==0)
{
Day = day;
Month = month ;
Year = year;
}
System.out.println(n+" days ago is:"+Year+"-"+Month+"-"+ Day);
}

SourceMonitor的生成報表內容如下:

題目集3

7-2 定義日期類 (28 分)

定義一個類Date,包含三個私有屬性年(year)、月(month)、日(day),均為整型數,其中:年份的合法取值範圍為[1900,2000] ,月份合法取值範圍為[1,12] ,日期合法取值範圍為[1,31] 注意:不允許使用Java中和日期相關的類和方法,否則按0分處理。

原始碼:
import java.util.*;

public class Main {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
boolean m = new String() != null;
boolean n = new String() != null;
m = isLeapYear(year);
n = checkInputValidity( year, month, day);

if((m==true&&(month==2&&day>29))||(m==false&&(month==2&&day>28))|| (month == 4 && day == 31) || (month == 6 && day ==31)|| (month == 9&& day == 31)||(month == 11 && day ==31))
{
System.out.println ("Date Format is Wrong");
}
else if (n==false)
{
System.out.println ("Date Format is Wrong");
}
else
{
nextDate( year, month,day);
}
}
public static boolean isLeapYear(int year)
{
int flag=-1;
if(year%4==0||(year%4==0&&year%400==0))
{
flag=1;
}
else if(year%4!=0||(year%4==0&&year%400!=0))
{
flag=0;
}
if(flag==1)
{
return true;
}
else
{
return false;
}

}
public static boolean checkInputValidity(int year,int month,int day)
{
int flag;

if(year <1820 || year > 2020 || month < 1 || month > 12 || day < 1 || day > 31)
{
return false;
}
else
{
return true;

}
}
public static void nextDate(int year,int month,int day)
{
boolean m = new String() != null;

if(year%4==0||(year%4==0&&year%400==0))
{
m = true;
}
else if(year%4!=0||(year%4==0&&year%400!=0))
{
m = false;
}


if((m==true&&(month==2&&day>29))||(m==false&&(month==2&&day>28))|| (month == 4 && day == 31) || (month == 6 && day ==31)|| (month == 9&& day == 31)||(month == 11 && day ==31))
{
System.out.println ("Date Format is Wrong");
}
else
{

String week = new String();
int f,Year = 0 ,Month = 0,Day = 0;

if((m==true&&(month==2&&day==29))||(m==false&&(month==2&&day==28))|| ((month == 4||month==6||month==9||month==11) && day == 30))
{
Month = month+1;
Day = 1;
Year = year;
}
else if (month == 12&&day==31)
{
Month = 1;
Day = 1;
Year = year + 1;
}
else if((month==1||month==3||month==5||month==7||month==8||month==10)&&day==31)
{
Month = month+1;
Day = 1;
Year = year;
}
else
{
Day = day+1;
Year = year;
Month = month;
}
System.out.println("Next day is:"+Year+"-"+Month+"-"+Day);
}
}
}

SourceMonitor的生成報表內容如下:

7-3 一元多項式求導(類設計) (50 分)

編寫程式性,實現對簡單多項式的導函式進行求解。詳見作業指導書。
輸入格式:

在一行內輸入一個待計算導函式的表示式,以回車符結束。

輸出格式:

如果輸入表示式不符合上述表示式基本規則,則輸出“Wrong Format”

如果輸入合法,則在一行內正常輸出該表示式的導函式,注意以下幾點: 結果不需要排序,也不需要化簡;

  • 當某一項為“0”時,則該項不需要顯示,但如果整個導函式結果為“0”時,則顯示為“0”
  • 當輸出結果第一項係數符號為“+”時,不輸出“+”
  • 當指數符號為“+”時,不輸出“+”
  • 當指數值為“0”時,則不需要輸出“x^0”,只需要輸出其係數即可。

原始碼:
import java.util.ArrayList;
import java.util.List;

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);
String expr = sc.nextLine();


Polynomial polynomial = new Polynomial(expr);
if (!polynomial.isPolynomial()) {
System.out.println("Wrong Format");
} else {
List<Term> newTerms = new ArrayList<Term>();
try {
List<Term> terms = polynomial.getPolynomial();
for (Term term : terms) {
newTerms.add(term.getDerivative());
}
Expression expression = new Expression(newTerms);
System.out.println(expression);
} catch (Exception e) {
System.out.println("Wrong Format");
}
}
}
}
class Expression {

private List<Term> trems = new ArrayList<Term>();

public Expression() {
super();
}

public Expression(List<Term> trems) {
super();
this.trems = trems;
}

@Override
public String toString() {
StringBuffer result = new StringBuffer();
for (Term term : trems) {
result.append(term.toString());
}
if(result.length() == 0) {
return "0";
} else {
if(result.charAt(0) == '+') {
result.deleteCharAt(0);
}
return result.toString();
}
}
}
class ConstantTerm extends Term {

private BigInteger value;

public ConstantTerm() {
super();
}

public ConstantTerm(BigInteger value) {
super();
this.value = value;
}

// 常數項的導數為0
@Override
public Term getDerivative() {
return new ConstantTerm(BigInteger.ZERO);
}

public BigInteger getValue() {
return value;
}

public void setValue(BigInteger value) {
this.value = value;
}

@Override
public String toString() {
int compareTo = value.compareTo(BigInteger.ZERO);
if (compareTo == 0) {
return "";
} else if(compareTo > 0) {
return "+"+value;
} else {
return value.toString();
}
}

}
class Polynomial {

// 正整數正則
private static Pattern PATTERN1 = Pattern.compile("^[+-]{0,1}[1-9]\\d*$");

// 變數項正則 注意除了數字 任何地方都可以有空格
private static Pattern PATTERN2 = Pattern.compile("^[+-]{0,1}([1-9]\\d*\\s*\\*\\s*){0,1}x\\s*(\\^\\s*[+-]{0,1}[1-9]\\d*){0,1}$");

// 原始多項式
private String data;

public Polynomial() {
super();
}

public Polynomial(String data) {
super();
this.data = data;
}

public boolean isPolynomial() {
String value = data;
if (value == null) {
return false;
}
// 去除首尾空格
value = value.trim();

// 空字串
if (value.equals("")) {
return false;
}

// 按照運算加減號分隔原字串
List<String> arrArea = split(value);
if(arrArea == null) {
return false;
}
for (String item : arrArea) {
// 驗證每一項是否合法
item = item.trim();
if (item.equals("")) {
return false;
}
if(item.indexOf("x") > -1) {
// 包含x 需要按變數項判斷
Matcher matcher = PATTERN2.matcher(item);
if (!matcher.matches()) {
return false;
}
} else {
// 不包含x 按常量項判斷 只需要判斷是否為整數即可
Matcher matcher = PATTERN1.matcher(item);
if (!matcher.matches()) {
return false;
}
}
}
// 所有項校驗通過
return true;
}

public List<Term> getPolynomial() {
List<Term> result = new ArrayList<Term>();
String value = data.trim();
List<String> arrArea = split(value);
for (String item : arrArea) {
// 移除所有空格
item = item.replace(" ", "");
if (item.indexOf("x") > -1) {
BigInteger coeff = item.startsWith("-") ? BigInteger.valueOf(-1L) : BigInteger.valueOf(1L);
BigInteger index = BigInteger.valueOf(1L);
String[] temp = item.split("\\*");
if (temp.length == 1) {
temp = temp[0].split("\\^");
if (temp.length == 1) {
// x
} else {
// x^3
index = BigInteger.valueOf(Long.valueOf(temp[1]));
}
} else {
coeff = BigInteger.valueOf(Long.valueOf(temp[0]));
temp = temp[1].split("\\^");
if (temp.length == 1) {
// 5*x
} else {
// 5*x^3
index = BigInteger.valueOf(Long.valueOf(temp[1]));
}
}
result.add(new PowerFunctionTerm(coeff,index));
} else {
result.add(new ConstantTerm(BigInteger.valueOf(Long.valueOf(item))));
}
}
return result;
}

private static List<String> split(String value) {
if (value.endsWith("+") || value.endsWith("-")) {
return null;
}
// 先找到只能作為是運算子的+-
List<String> result = new ArrayList<String>();
char[] charArray = value.toCharArray();
char previous = charArray[0];
List<Integer> indexs = new ArrayList<Integer>();
indexs.add(0);
for (int i = 0; i < charArray.length; i++) {
if (i == 0) {
continue;
}
char c = charArray[i];
if (c == '+' || c == '-') {
if (previous != '^') {
indexs.add(i);
} else if (previous == '+' || previous == '-') {
return null;
}
}
if (c != ' ') {
previous = c;
}
}
indexs.add(value.length());
for (int i = 0; i < indexs.size() - 1; i++) {
result.add(value.substring(indexs.get(i), indexs.get(i + 1)));
}
return result;
}

public static void main(String[] args) {
Matcher matcher = PATTERN2.matcher("0*x");
System.out.println(matcher.matches());
}
}
abstract class Term {

// 項求導 - 返回的也是項
public abstract Term getDerivative();
}
class PowerFunctionTerm extends Term {
// 係數
private BigInteger coeff;

// 指數
private BigInteger index;

private static final BigInteger ONE = BigInteger.valueOf(1L);

public PowerFunctionTerm() {
super();
}

public PowerFunctionTerm(BigInteger coeff, BigInteger index) {
super();
this.coeff = coeff;
this.index = index;
}

@Override
public Term getDerivative() {
// 指數如果是1 求導後應該變為常數項
if (index.compareTo(ONE) == 0) {
return new ConstantTerm(coeff.multiply(index));
} else {
// 求導函式 f(x) = ax^b f'(x) = abx^b-1
return new PowerFunctionTerm(coeff.multiply(index), index.subtract(ONE));
}
}

// 係數和指數都不會為0
@Override
public String toString() {
int compareTo = coeff.compareTo(BigInteger.ZERO);
StringBuffer result = new StringBuffer();
result.append(compareTo > 0 ? "+" : "-");
// 係數絕對值為1的時候不用顯示
if (coeff.abs().compareTo(ONE) != 0) {
result.append(coeff.abs().toString());
result.append("*");
}
result.append("x");

// 指數為1的時候不用顯示
if (index.compareTo(ONE) != 0) {
result.append("^");
result.append(index.toString());
}
return result.toString();
}

public BigInteger getCoeff() {
return coeff;
}

public void setCoeff(BigInteger coeff) {
this.coeff = coeff;
}

public BigInteger getIndex() {
return index;
}

public void setIndex(BigInteger index) {
this.index = index;
}

}

SourceMonitor的生成報表內容如下:

三、採坑心得

1.條件判斷表示式比較長的情況下,可以封裝成一個方法isXXX(),返回boolean

2.Javathis super 的異同:簡單的來說,this呼叫的是本類中的東西,super呼叫的是父類中的東西。

如果B類繼承了A類,super對應A類,this對應B類。

3.Java變數的命名規則如下:

1.可以以數字、字母、‘_’'$'符組成

2.首字元不能以數字開頭

3.中文可以作為變數名,但不提倡使用

4.Java大小寫敏感,命名變數時要注意

5.不能使用Java保留字

四、改進建議

寫程式時應先確定一個思路再順著往下寫,要是邊寫邊想邊改,會造成程式碼思路不清晰且難以找出錯誤。

五、總結

目集1的大部分題目,幾乎第一次提交就通過所有測試點;題目二對我來說有一定的難度,很多測試點不能通過,所以我花費了大量的時間提交測試,雖然最終通過,但多次修改導致程式碼複雜性高,可讀性不高;題目三雖然只有三道題,但我只能寫出演算法,多次修改到最後也沒有通過測試點,找不出問題所在。所以越長越複雜的題目,越應該確定思路。