第二次BLOG總結
前言
1.前幾次作業作業量相對來說比較大,難度也比較高,需要綜合運用許多學過的和沒學過的知識,沒學過的需要自己找資料
2.期中考試、第4.5次大作業主要運用的知識有
(1)類的設計
(2)繼承與多型
(3)動態陣列
(4)正則表示式
3.主要是點線型的題目很難,需要設計很多個類
設計與分析
期中考試第一題
-
設計一個類表示平面直角座標系上的點Point,私有屬性分別為橫座標x與縱座標y,資料型別均為實型數,除構造方法以及屬性的getter與setter方法外,定義一個用於顯示資訊的方法display(),用來輸出該座標點的座標資訊,格式如下:
(x,y)
,數值保留兩位小數。為簡化題目,其中,座標點的取值範圍設定為(0,200]
Wrong Format
-
設計一個類表示平面直角座標系上的線Line,私有屬性除了標識線段兩端的點point1、point2外,還有一個字串型別的color,用於表示該線段的顏色,同樣,除構造方法以及屬性的getter與setter方法外,定義一個用於計算該線段長度的方法getDistance(),還有一個用於顯示資訊的方法display(),用來輸出線段的相關資訊,輸出格式如下:
``` The line's color is:顏色值 The line's begin point's Coordinate is: (x1,y1) The line's end point's Coordinate is: (x2,y2) The line's length is:長度值 ```
1 package 期中考試; 2 import java.util.Scanner; 3 public class 第一題 { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 Scanner in = new Scanner(System.in); 8 double x1 = in.nextDouble(); 9 double y1 = in.nextDouble();10 double x2 = in.nextDouble(); 11 double y2 = in.nextDouble(); 12 String color = in.next(); 13 Point p1 = new Point(x1, y1); 14 Point p2 = new Point(x2, y2); 15 16 Line line = new Line(p1, p2, color); 17 line.display(); 18 19 20 in.close(); 21 } 22 } 23 24 class Point { 25 private double x; 26 private double y; 27 28 public Point() { 29 30 } 31 32 public Point(double x, double y) { 33 this.x = x; 34 this.y = y; 35 } 36 37 public void setX(double x) { 38 this.x = x; 39 } 40 41 public double getX() { 42 return x; 43 } 44 45 public void setY(double y) { 46 this.y = y; 47 } 48 49 public double getY() { 50 return y; 51 } 52 53 public void display() { 54 System.out.println("("+String.format("%.2f",getX() )+","+String.format("%.2f",getY() )+")"); 55 } 56 } 57 class Line { 58 private Point p1; 59 private Point p2; 60 private String color; 61 62 public Line() { 63 64 } 65 66 public Line(Point p1, Point p2, String color) { 67 this.p1 = p1; 68 this.p2 = p2; 69 this.color = color; 70 } 71 72 public void setPoint1(Point p1) { 73 this.p1 = p1; 74 } 75 76 public Point getPoint1() { 77 return p1; 78 } 79 80 public void setPoint2(Point p2) { 81 this.p2 = p2; 82 } 83 84 public Point getPoint2() { 85 return p2; 86 } 87 88 89 public double getDistance() { 90 double distance; 91 distance = Math.sqrt(Math.pow(p1.getX() - p2.getX(), 2) + Math.pow(p1.getY() - p2.getY(),2 )); 92 return distance; 93 } 94 95 public void display() { 96 if(p1.getX() > 0 && p1.getX() <=200 && p1.getY() > 0 && p1.getY() <= 200 && p2.getX() > 0 && p2.getX() <= 200 && p2.getY() > 0 && p2.getY() <=200) { 97 System.out.println("The line's color is:"+color); 98 System.out.println("The line's begin point's Coordinate is:"); 99 p1.display(); 100 System.out.println("The line's end point's Coordinate is:"); 101 p2.display(); 102 System.out.println("The line's length is:"+String.format("%.2f", getDistance())); 103 } 104 else { 105 System.out.println("Wrong Format"); 106 } 107 } 108 109 }
這道題並不難,主要是類的設計,加深了我對類的理解,類與int、double、String這種的相似。
在第四題的第一題中需要用到動態陣列加上正則表示式,把每一行的數字全部提取出來
7-1
import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); String num = ""; int sum = 0; ArrayList<String> strList = new ArrayList<String>(); //動態陣列 while(!num.equals("end")) { //結束字元end num = in.nextLine(); strList.add(num); //新增至動態陣列 } String reg = "[0-9]+"; for(int i = 0; i < strList.size() - 1; i++) { Pattern pattern = Pattern.compile(reg); //編譯正則表示式 Matcher matcher = pattern.matcher(strList.get(i)); //指定要匹配的字串 while(matcher.find()) { sum = sum + Integer.parseInt(matcher.group()); //將匹配的字元轉換為整數並且累加 } System.out.println(sum); sum = 0; } } }
定義一個動態陣列:ArrayList<類> 名稱 = new ArrayList<類>();
使用add.()新增get.()提取,用使用Integer.parseInt()強制轉換把字串轉換為整數
7-3 設計一個銀行業務類
編寫一個銀行業務類BankBusiness,具有以下屬性和方法:
(1)公有、靜態的屬性:銀行名稱bankName,初始值為“中國銀行”。
(2)私有屬性:賬戶名name、密碼password、賬戶餘額balance。
(3)銀行對使用者到來的歡迎(welcome)動作(靜態、公有方法),顯示“中國銀行歡迎您的到來!”,其中“中國銀行”自動使用bankName的值。
(4)銀行對使用者離開的提醒(welcomeNext)動作(靜態、公有方法),顯示“請收好您的證件和物品,歡迎您下次光臨!”
(5)帶引數的構造方法,完成開戶操作。需要賬戶名name、密碼password資訊,同時讓賬戶餘額為0。
(6)使用者的存款(deposit)操作(公有方法,需要密碼和交易額資訊),密碼不對時無法存款且提示“您的密碼錯誤!”;密碼正確、完成使用者存款操作後,要提示使用者的賬戶餘額,例如“您的餘額有1000.0元。”。
(7)使用者的取款(withdraw)操作(公有方法,需要密碼和交易額資訊)。密碼不對時無法取款且提示“您的密碼錯誤!”;密碼正確但餘額不足時提示“您的餘額不足!”;密碼正確且餘額充足時扣除交易額並提示使用者的賬戶餘額,例如“請取走鈔票,您的餘額還有500.0元。”。
編寫一個測試類Main,在main方法中,先後執行以下操作:
(1)呼叫BankBusiness類的welcome()方法。
(2)接收鍵盤輸入的使用者名稱、密碼資訊作為引數,呼叫BankBusiness類帶引數的構造方法,從而建立一個BankBusiness類的物件account。
(3)呼叫account的存款方法,輸入正確的密碼,存入若干元。密碼及存款金額從鍵盤輸入。
(4)呼叫account的取款方法,輸入錯誤的密碼,試圖取款若干元。密碼及取款金額從鍵盤輸入。
(5)呼叫account的取款方法,輸入正確的密碼,試圖取款若干元(取款金額大於餘額)。密碼及取款金額從鍵盤輸入。
(6)呼叫account的取款方法,輸入正確的密碼,試圖取款若干元(取款金額小於餘額)。密碼及取款金額從鍵盤輸入。
(7)呼叫BankBusiness類的welcomeNext()方法。
輸入格式:
輸入開戶需要的姓名、密碼
輸入正確密碼、存款金額
輸入錯誤密碼、取款金額
輸入正確密碼、大於餘額的取款金額
輸入正確密碼、小於餘額的取款金額
輸出格式:
中國銀行(銀行名稱)歡迎您的到來!
您的餘額有多少元。
您的密碼錯誤!
您的餘額不足!
請取走鈔票,您的餘額還有多少元。
請收好您的證件和物品,歡迎您下次光臨!
1 import java.util.Scanner; 2 public class Main { 3 4 public static void main(String[] args) { 5 // TODO Auto-generated method stub 6 7 BankBusiness account = new BankBusiness(); 8 account.weclome(); 9 account.Open(); 10 account.deposit(); 11 account.withdraw(); 12 account.withdraw(); 13 account.withdraw(); 14 account.welcomeNext(); 15 } 16 17 } 18 19 class BankBusiness{ 20 21 Scanner in = new Scanner(System.in); 22 String input = new String(); 23 public String bankname = "中國銀行"; 24 private String name; 25 private String password; //密碼 26 private int balance; //餘額 27 28 public void weclome() { 29 System.out.println(bankname+"歡迎您的到來!"); 30 } 31 32 public void welcomeNext() { 33 System.out.println("請收好您的證件和物品,歡迎您下次光臨!"); 34 } 35 36 void Open() { 37 name = in.next(); 38 password = in.next(); 39 balance = 0; 40 } 41 42 public void deposit() { 43 String password; 44 password = in.next(); 45 46 if(password.equals(this.password)) { 47 this.balance = in.nextInt(); 48 System.out.println("您的餘額有"+balance+".0元。"); 49 } 50 else { 51 52 System.out.println("您的密碼錯誤!"); 53 54 } 55 56 } 57 58 public void withdraw() { 59 int balance; 60 String password; 61 password = in.next(); 62 balance = in.nextInt(); //取款 63 if(password.equals(this.password)) { 64 if(balance > this.balance) { 65 System.out.println("您的餘額不足!"); 66 } 67 else { 68 this.balance = this.balance - balance; 69 System.out.println("請取走鈔票,您的餘額還有"+this.balance+".0元。"); 70 } 71 } 72 else { 73 System.out.println("您的密碼錯誤!"); 74 } 75 76 } 77 78 }
這道題只需在類裡面設計一些功能即可
最難的是點線型的題目
點類的設計是最基本的
點類:
class point { private double x; private double y; public point() { } public point(double x, double y) { this.x = x; this.y = y; } public void setX (double x) { this.x = x; } public double getX () { return x; } public void setY (double y) { this.y = y; } public double getY () { return y; } }
對x,y進行封裝
線類:
public class Line { private Point p1;//線上的第一個點 private Point p2;//線上的第二個點 public Line(double x1, double y1, double x2, double y2) { Point p1 = new Point(x1, y1); Point p2 = new Point(x2, y2); LineInputError.pointsCoincideError(p1, p2);//兩點是否重合,重合則報錯並退出 this.p1 = p1; this.p2 = p2; } public Line(Point p1, Point p2) { LineInputError.pointsCoincideError(p1, p2);//兩點是否重合,重合則報錯並退出 this.p1 = p1; this.p2 = p2; } /* 獲取線條的斜率 */ public Double getSlope() { // (x1-x2=0)注意考慮斜率不存在即返回double型別無窮大"Infinite" return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX()); } /* 判斷x是否在線上 */ public boolean isOnline(Point x) { //System.out.println("isOnline"); //System.out.println(p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y + " "); // 點重合 if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) { return true; } Line l = new Line(p1, x); if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) { return true; } /* * if (l.getSlope().isInfinite() || this.getSlope().isInfinite()) { return * false; } */ // 此點與線上任意一點構成的線的斜率相等則此點在線上 double b1 = l.getSlope(), b2 = this.getSlope(); //System.out.println(b1 + " " + b2 + " " + (b1- b2) + " " + (Math.abs(b1 - b2) < 0.00000000001)); return Math.abs(b1 - b2) < 0.00000000001;// b1==b2; } /* 獲取點x到線的距離(最短距離,即垂線) */ public double getDistance(Point x) { // 利用兩點求直線方程,利用公式代入即可 // 直線方程x(y2-y1)-y(x2-x1)-x1(y2-y1)+y1(x2-x1)=0 double distY = p2.getY() - p1.getY(); double distX = p2.getX() - p1.getX(); return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX) / p1.getDistance(p2); } /* 判斷x是否在線上且在兩點之間 */ public boolean isBetween(Point x) { //System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y); if (!this.isOnline(x)) { return false; } // 與端點重合,認為不在在兩點之間, if (x.equals(p1) || x.equals(p2)) { return false; } // x到 p1和p2的距離 同時小於 p1到p2的距離 說明 交點在 p1到p2的線段上 double d = p2.getDistance(p1); boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d; //System.out.println("isBetween" + b); return b; } /* 判斷p1、p2是否在x的同一側 */ public boolean isSameSide(Point x) { // 點在線上且不在點之間 return isOnline(x) && !isBetween(x); } /* 獲取p1、p2之間的中點 */ public Point getMiddlePoint() { Point p = new Point(); p.setX((p1.getX() + p2.getX()) / 2); p.setY((p1.getY() + p2.getY()) / 2); return p; } /* 獲取線段的第一個座標點 */ public Point getPointA() { return p1; } /* 獲取線段的第二個座標點 */ public Point getPointB() { return p2; } /* 獲取與線條l之間的夾角,若兩條線段交叉(交叉點位於其中一條線的兩點之間),取較小的夾角 */ public double getAngle(Line l) { // 利用公式θ=arctan∣(k2- k1)/(1+ k1k2)∣,此時求較小的夾角 double k2 = getSlope(); double k1 = l.getSlope(); return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值為角度 } // 是否平行,平行返回true,否則false。 public boolean isParallel(Line l) { Double b1 = this.getSlope(); Double b2 = l.getSlope(); if ((b1.isInfinite()) && (b2.isInfinite())) { return true; } else { return (this.getSlope().doubleValue() == l.getSlope().doubleValue()); } } // 兩條線是否重合,重合返回true,否則false。 public boolean isCoincide(Line l) { if (!this.isParallel(l)) { return false; } if (this.isOnline(l.p1)) { return true; } return false; } // 獲取交叉點,若兩條線平行,返回null。 public Point getIntersection(Line l) { // LineInputError.isParallelError(this, l); if (this.isParallel(l)) { return null; } if (p1.equals(l.p1) || p1.equals(l.p2)) { return p1; } if (p2.equals(l.p1) || p2.equals(l.p2)) { return p2; } Point p3 = l.p1, p4 = l.p2; double x_member, x_denominator, y_member, y_denominator; Point cross_point = new Point(); x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y - p1.x * p3.y; x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; if (x_denominator == 0) cross_point.x = 0; else cross_point.x = x_member / x_denominator; y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x - p1.y * p3.x; y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; if (y_denominator == 0) cross_point.y = 0; else cross_point.y = y_member / y_denominator; // System.out.println(cross_point.x + ","+cross_point.y); return cross_point; // 平行返回(0,0) } }
用於判斷線段是否相交,是否平行
再新增一些其他類來完善點線型題目的功能
一個判斷直線是否相加我認為特別重要:java.awt.geom.Line2D.linesIntersect(x1,y1,x2,y2,x3,y3,x4,y4);
總結
總的來說這次的題集讓我對1.動態陣列2.繼承3.正則表示式都有著理解的加深