java面向对象程序设计题目集7~9的总结

一、前言

    不知不觉已经到第三次题目集总结了,本次题目集涵盖了类的继承、多态性使用方法以及接口的应用,以实际实现一个游戏或者一个小项目的形式考察我们目前的编程水平。处于课程后期,题目集的量已经少了很多,取而代之的是习题的难度有所上升,需要考虑的各个方面更加周全。

接下来我将分析本次习题集的7(7-1)(7-2)两道题目的递进式设计和题目集8和题目集9两道ATM机仿真题目的设计思路。

二、设计与分析

①题目集7(7-1)、(7-2)两道题目的递进式设计分析总结

先来看题目集7吧

7-1 图形卡片排序游戏 (40 分)
 

掌握类的继承、多态性使用方法以及接口的应用。详见作业指导书 2020-OO第07次作业-1指导书V1.0.pdf

输入格式:

  • 首先,在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如: 1 3 4 2 1 3 4 2 1 3 0
  • 然后根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。

输出格式:

  • 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边不能组成三角形),则输出Wrong Format
  • 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
  1. 排序前的各图形类型及面积,格式为图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格;
  2. 排序后的各图形类型及面积,格式同排序前的输出;
  3. 所有图形的面积总和,格式为Sum of area:总面积值

输入样例1:

在这里给出一组输入。例如:

1 5 3 2 0
 
结尾无空行
 

输出样例1:

在这里给出相应的输出。例如:

Wrong Format
 
结尾无空行
 

输入样例2:

在这里给出一组输入。例如:

4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 3.5
 
结尾无空行
 

输出样例2:

在这里给出相应的输出。例如:

The original list:
Trapezoid:1.14 Rectangle:3.22 Circle:98.52 Triangle:4.02 
The sorted list:
Circle:98.52 Triangle:4.02 Rectangle:3.22 Trapezoid:1.14 
Sum of area:106.91
 
结尾无空行
 

输入样例3:

在这里给出一组输入。例如:

4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 8.4
 
结尾无空行
 

输出样例3:

在这里给出相应的输出。例如:

Wrong Format
 
结尾无空行
代码如下:

//7-1
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	// 在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接
	// 使用Main.input.next…即可(避免采坑)
	public static Scanner input = new Scanner(System.in);

	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<Integer>();
		int num = input.nextInt();
		while (num != 0) {
			if (num < 0 || num > 4) {
				System.out.println("Wrong Format");
				System.exit(0);
			}
			list.add(num);
			num = input.nextInt();
		}
		DealCardList dealCardList = new DealCardList(list);
		if (!dealCardList.validate()) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
		dealCardList.showResult(list);
		input.close();
	}
}

class DealCardList {
	ArrayList<Double> area = new ArrayList<Double>();
	public double getarea(ArrayList<Double> area) {
		double sum=0;
		for(int i=0;i<area.size();i++) {
			sum+=area.get(i);
		}
		return sum;
	}
	public DealCardList(ArrayList<Integer> list) {
		// TODO 自动生成的构造函数存根
		for (int a : list) {
			switch (a) {
			case 1:
				Circle circle = new Circle();
				circle.radius = Main.input.nextDouble();
				if (circle.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(circle.getArea());
				}
				break;
			case 2:
				Rectangle rectangle = new Rectangle();
				rectangle.length = Main.input.nextDouble();
				rectangle.width = Main.input.nextDouble();
				if (rectangle.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(rectangle.getArea());
				}
				break;
			case 3:
				Triangle triangle = new Triangle();
				triangle.a = Main.input.nextDouble();
				triangle.b = Main.input.nextDouble();
				triangle.c = Main.input.nextDouble();
				if (triangle.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(triangle.getArea());
				}
				break;
			case 4:
				Trapezoid trapezoid = new Trapezoid();
				trapezoid.up = Main.input.nextDouble();
				trapezoid.dowm = Main.input.nextDouble();
				trapezoid.h = Main.input.nextDouble();
				if (trapezoid.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(trapezoid.getArea());
				}
				break;
			}
		}
	}

	boolean validate() {
		return true;
	}

	void showResult(ArrayList<Integer> list) {
		System.out.println("The original list:");
		int i = 0;
		for (Object object : area) {
			switch (list.get(i++)) {
			case 1:
				System.out.print("Circle:");
				break;
			case 2:
				System.out.print("Rectangle:");
				break;
			case 3:
				System.out.print("Triangle:");
				break;
			case 4:
				System.out.print("Trapezoid:");
				break;
			}
			System.out.print(String.format("%.2f", object) + " ");
		}
		System.out.println("\nThe sorted list:");
		for (i = 0; i < area.size() - 1; i++) {
			for (int j = 0; j < area.size() - 1 - i; j++) {
				if (area.get(j) < area.get(j + 1)) {
					double temp = area.get(j);
					area.set(j, area.get(j + 1));
					area.set(j + 1, temp);
					int t = list.get(j);
					list.set(j, list.get(j + 1));
					list.set(j + 1, t);
				}
			}
		}
		i = 0;
		for (Object object : area) {
			switch (list.get(i++)) {
			case 1:
				System.out.print("Circle:");
				break;
			case 2:
				System.out.print("Rectangle:");
				break;
			case 3:
				System.out.print("Triangle:");
				break;
			case 4:
				System.out.print("Trapezoid:");
				break;
			}
			System.out.print(String.format("%.2f", object) + " ");
		}
		System.out.println("\nSum of area:"+String.format("%.2f",getarea(area)));
	}

}

class Shape {// 形状
	Scanner in = new Scanner(System.in);

	public String toString(double Area) {// 返回面积信息
		if (Area == -1)
			return "Wrong Format";
		else
			return Double.toString(Area);
	}

	public boolean validate(double num) {// 检测输入是否有误
		if (num > 0)
			return true;
		else
			return false;
	}

	public double getArea() {// 返回面积
		return 0.0;
	}
}

class Circle extends Shape {
	double radius = 0;

	public double getArea() {// 返回面积

		if (validate(radius))
			return Math.PI * radius * radius;
		else
			return -1;
	}
}

class Rectangle extends Shape {// 矩形
	double length = 0;
	double width = 0;

	public double getArea() {
		if (validate(length) && validate(width))
			return length * width;
		else
			return -1;
	}

}

class Triangle extends Shape {// 三角形
	double a = 0;
	double b = 0;
	double c = 0;

	public double getArea() {
		if (validate(a) && validate(b) && validate(c) && a + b > c && a + c > b && b + c > a) {
			double p = (a + b + c) / 2;
			return Math.sqrt(p * (p - a) * (p - b) * (p - c));
		} else
			return -1;
	}
}

class Trapezoid extends Shape {// 梯形
	double up = 0;
	double dowm = 0;
	double h = 0;

	public double getArea() {
		if (validate(up) && validate(dowm) && validate(h))
			return (up + dowm) * h / 2;
		else
			return -1;
	}
}

分析结果:(其实用的是7-2,做修改的时候没有另外存7-1)

本题在整体结构上以多个从抽象图形类衍生出来的子类为基础对其不同运算方式进行重构实现游戏功能。

7-2 图形卡片分组游戏 (60 分)
 

掌握类的继承、多态性使用方法以及接口的应用。 具体需求参考作业指导书。

2021-OO第07次作业-2指导书V1.0.pdf

输入格式:

  • 在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:1 3 4 2 1 3 4 2 1 3 0
  • 根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。

输出格式:

  • 如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出Wrong Format
  • 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
  1. 排序前的各图形类型及面积,格式为[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ],注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前;
  2. 输出分组后的图形类型及面积,格式为[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积],各组内格式为图形名称:面积值。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出;
  3. 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
  4. 各组中面积之和的最大值输出,格式为The max area:面积值

输入样例1:

在这里给出一组输入。例如:

1 5 3 2 0
 
结尾无空行
 

输出样例1:

在这里给出相应的输出。例如:

Wrong Format
 
结尾无空行
 

输入样例2:

在这里给出一组输入。例如:

4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 3.5
 
结尾无空行
 

输出样例2:

在这里给出相应的输出。例如:

The original list:
[Trapezoid:1.14 Rectangle:3.22 Circle:98.52 Triangle:4.02 ]
The Separated List:
[Circle:98.52 ][Rectangle:3.22 ][Triangle:4.02 ][Trapezoid:1.14 ]
The Separated sorted List:
[Circle:98.52 ][Rectangle:3.22 ][Triangle:4.02 ][Trapezoid:1.14 ]
The max area:98.52
 
结尾无空行
 

输入样例3:

在这里给出一组输入。例如:

2 1 2 1 1 3 3 4 4 1 1 1 2 1 0
2.3 3.5 2.5 4.5 2.1 2.6 8.5 3.2 3.1 3.6 8.5 7.5 9.1245 6.5 3.4 10.2 11.2 11.6 15.4 5.8 2.13 6.2011 2.5 6.4 18.65
 
结尾无空行
 

输出样例3:

在这里给出相应的输出。例如:

The original list:
[Rectangle:8.05 Circle:19.63 Rectangle:9.45 Circle:21.24 Circle:226.98 Triangle:4.65 Triangle:29.80 Trapezoid:50.49 Trapezoid:175.56 Circle:105.68 Circle:14.25 Circle:120.81 Rectangle:16.00 Circle:1092.72 ]
The Separated List:
[Circle:19.63 Circle:21.24 Circle:226.98 Circle:105.68 Circle:14.25 Circle:120.81 Circle:1092.72 ][Rectangle:8.05 Rectangle:9.45 Rectangle:16.00 ][Triangle:4.65 Triangle:29.80 ][Trapezoid:50.49 Trapezoid:175.56 ]
The Separated sorted List:
[Circle:1092.72 Circle:226.98 Circle:120.81 Circle:105.68 Circle:21.24 Circle:19.63 Circle:14.25 ][Rectangle:16.00 Rectangle:9.45 Rectangle:8.05 ][Triangle:29.80 Triangle:4.65 ][Trapezoid:175.56 Trapezoid:50.49 ]
The max area:1601.31
 
结尾无空行
 

输入样例4:

在这里给出一组输入。例如:

1 1 3 0
6.5 12.54 3.6 5.3 6.4
 
结尾无空行
 

输出样例4:

在这里给出相应的输出。例如:

The original list:
[Circle:132.73 Circle:494.02 Triangle:9.54 ]
The Separated List:
[Circle:132.73 Circle:494.02 ][][Triangle:9.54 ][]
The Separated sorted List:
[Circle:494.02 Circle:132.73 ][][Triangle:9.54 ][]
The max area:626.75
 
结尾无空行
代码如下:(折叠)
查看代码
//package week10;

//7-2
import java.util.ArrayList;
import java.util.Scanner;

public class Main{
	// 在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接
	// 使用Main.input.next…即可(避免采坑)
	public static Scanner input = new Scanner(System.in);

	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<Integer>();
		int num = input.nextInt();
		while (num != 0) {
			if (num < 0 || num > 4) {
				System.out.println("Wrong Format");
				System.exit(0);
			}
			list.add(num);
			num = input.nextInt();
		}
		if (list.size() == 0) {
			System.out.println("Wrong Format");
			System.exit(0);
		}

		DealCardList dealCardList = new DealCardList(list);
		if (!dealCardList.validate()) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
		dealCardList.showResult(list);
		input.close();
	}
}

class DealCardList {
	ArrayList<Double> area = new ArrayList<Double>();

	public double getarea(ArrayList<Double> area) {
		double sum = 0;
		for (int i = 0; i < area.size(); i++) {
			sum += area.get(i);
		}
		return sum;
	}

	public double getmaxarea(ArrayList<Double> area) {
		double sum = 0;
		for (int i = 0; i < area.size(); i++) {
			if (sum < area.get(i))
				sum = area.get(i);
		}
		return sum;
	}

	public DealCardList(ArrayList<Integer> list) {
		// TODO 自动生成的构造函数存根
		for (int a : list) {
			switch (a) {
			case 1:
				Circle circle = new Circle();
				circle.radius = Main.input.nextDouble();
				if (circle.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(circle.getArea());
				}
				break;
			case 2:
				Rectangle rectangle = new Rectangle();
				rectangle.length = Main.input.nextDouble();
				rectangle.width = Main.input.nextDouble();
				if (rectangle.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(rectangle.getArea());
				}
				break;
			case 3:
				Triangle triangle = new Triangle();
				triangle.a = Main.input.nextDouble();
				triangle.b = Main.input.nextDouble();
				triangle.c = Main.input.nextDouble();
				if (triangle.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(triangle.getArea());
				}
				break;
			case 4:
				Trapezoid trapezoid = new Trapezoid();
				trapezoid.up = Main.input.nextDouble();
				trapezoid.dowm = Main.input.nextDouble();
				trapezoid.h = Main.input.nextDouble();
				if (trapezoid.getArea() == -1) {
					System.out.print("Wrong Format");
					System.exit(0);
				} else {
					area.add(trapezoid.getArea());
				}
				break;
			}
		}
	}

	boolean validate() {
		return true;
	}

	void sort(ArrayList<Double> area) {
		for (int i = 0; i < area.size() - 1; i++) {
			for (int j = 0; j < area.size() - 1 - i; j++) {
				if (area.get(j) < area.get(j + 1)) {
					double temp = area.get(j);
					area.set(j, area.get(j + 1));
					area.set(j + 1, temp);
				}
			}
		}
	}

	void showResult(ArrayList<Integer> list) {
		ArrayList<Double> Circlearea = new ArrayList<Double>();
		ArrayList<Double> Rectanglearea = new ArrayList<Double>();
		ArrayList<Double> Trianglearea = new ArrayList<Double>();
		ArrayList<Double> Trapezoidarea = new ArrayList<Double>();
		System.out.println("The original list:");
		int i = 0;
		System.out.print("[");
		for (Object object : area) {
			switch (list.get(i++)) {
			case 1:
				System.out.print("Circle:");
				Circlearea.add((Double) object);
				break;
			case 2:
				System.out.print("Rectangle:");
				Rectanglearea.add((Double) object);
				break;
			case 3:
				System.out.print("Triangle:");
				Trianglearea.add((Double) object);
				break;
			case 4:
				System.out.print("Trapezoid:");
				Trapezoidarea.add((Double) object);
				break;
			}
			System.out.print(String.format("%.2f", object) + " ");
		}
		System.out.print("]");
		System.out.println("\nThe Separated List:");
		System.out.print("[");
		for (Object object : Circlearea)
			System.out.print("Circle:" + String.format("%.2f", object) + " ");
		System.out.print("][");
		for (Object object : Rectanglearea)
			System.out.print("Rectangle:" + String.format("%.2f", object) + " ");
		System.out.print("][");
		for (Object object : Trianglearea)
			System.out.print("Triangle:" + String.format("%.2f", object) + " ");
		System.out.print("][");
		for (Object object : Trapezoidarea)
			System.out.print("Trapezoid:" + String.format("%.2f", object) + " ");
		System.out.print("]");
		System.out.println("\nThe Separated sorted List:");
		sort(Circlearea);
		sort(Rectanglearea);
		sort(Trianglearea);
		sort(Trapezoidarea);
		System.out.print("[");
		for (Object object : Circlearea)
			System.out.print("Circle:" + String.format("%.2f", object) + " ");
		System.out.print("][");
		for (Object object : Rectanglearea)
			System.out.print("Rectangle:" + String.format("%.2f", object) + " ");
		System.out.print("][");
		for (Object object : Trianglearea)
			System.out.print("Triangle:" + String.format("%.2f", object) + " ");
		System.out.print("][");
		for (Object object : Trapezoidarea)
			System.out.print("Trapezoid:" + String.format("%.2f", object) + " ");
		System.out.print("]");
		double allarea[] = new double[4];
		allarea[0] = getarea(Circlearea);
		allarea[1] = getarea(Rectanglearea);
		allarea[2] = getarea(Trianglearea);
		allarea[3] = getarea(Trapezoidarea);
		for (i = 0; i < allarea.length; i++) {
			if (allarea[0] <= allarea[i])
				allarea[0] = allarea[i];
		}
		System.out.print("\nThe max area:" + String.format("%.2f", allarea[0]));
	}

}

class Card implements Comparable<Card> {
	private Shape shape;

	public Shape getShape() {
		return shape;
	}

	public void setShape(Shape shape) {
		this.shape = shape;
	}

	public Card() {
	}

	public Card(Shape shape) {
		this.shape = shape;
	}

	@Override
	public int compareTo(Card card) {
		return -(int) (shape.getArea() - card.getShape().getArea());
	}
}

class Shape {// 形状
	Scanner in = new Scanner(System.in);

	public String toString(double Area) {// 返回面积信息
		if (Area == -1)
			return "Wrong Format";
		else
			return Double.toString(Area);
	}

	public boolean validate(double num) {// 检测输入是否有误
		if (num > 0)
			return true;
		else
			return false;
	}

	public double getArea() {// 返回面积
		return 0.0;
	}
}

class Circle extends Shape {
	double radius = 0;

	public double getArea() {// 返回面积

		if (validate(radius))
			return Math.PI * radius * radius;
		else
			return -1;
	}
}

class Rectangle extends Shape {// 矩形
	double length = 0;
	double width = 0;

	public double getArea() {
		if (validate(length) && validate(width))
			return length * width;
		else
			return -1;
	}

}

class Triangle extends Shape {// 三角形
	double a = 0;
	double b = 0;
	double c = 0;

	public double getArea() {
		if (validate(a) && validate(b) && validate(c) && a + b > c && a + c > b && b + c > a) {
			double p = (a + b + c) / 2;
			return Math.sqrt(p * (p - a) * (p - b) * (p - c));
		} else
			return -1;
	}
}

class Trapezoid extends Shape {// 梯形
	double up = 0;
	double dowm = 0;
	double h = 0;

	public double getArea() {
		if (validate(up) && validate(dowm) && validate(h))
			return (up + dowm) * h / 2;
		else
			return -1;
	}
}

分析结果如7-1分析所示。

该代码将数据以arraylist的形式储存,在原来7-1的基础上修改输出格式(其实用重构tostring方法可能更为优雅但笔者那个时候还不会),最后多次排序实现游戏功能。

7-3 ATM机类结构设计(一) (100 分)
 

设计ATM仿真系统,具体要求参见作业说明。 OO作业8-1题目说明.pdf

输入格式:

每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:

  • 存款、取款功能输入数据格式: 卡号 密码 ATM机编号 金额(由一个或多个空格分隔), 其中,当金额大于0时,代表取款,否则代表存款。
  • 查询余额功能输入数据格式: 卡号

输出格式:

①输入错误处理

  • 如果输入卡号不存在,则输出Sorry,this card does not exist.
  • 如果输入ATM机编号不存在,则输出Sorry,the ATM's id is wrong.
  • 如果输入银行卡密码错误,则输出Sorry,your password is wrong.
  • 如果输入取款金额大于账户余额,则输出Sorry,your account balance is insufficient.
  • 如果检测为跨行存取款,则输出Sorry,cross-bank withdrawal is not supported.

②取款业务输出

输出共两行,格式分别为:

[用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

③存款业务输出

输出共两行,格式分别为:

[用户姓名]在[银行名称]的[ATM编号]上存款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

④查询余额业务输出

¥[金额]

金额保留两位小数。

输入样例1:

在这里给出一组输入。例如:

6222081502001312390 88888888 06 -500.00
#
 
结尾无空行
 

输出样例1:

在这里给出相应的输出。例如:

张无忌在中国工商银行的06号ATM机上存款¥500.00
当前余额为¥10500.00
 
结尾无空行
 

输入样例2:

在这里给出一组输入。例如:

6217000010041315709  88888888 02 3500.00
#
 
结尾无空行
 

输出样例2:

在这里给出相应的输出。例如:

杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥6500.00
 
结尾无空行
 

输入样例3:

在这里给出一组输入。例如:

6217000010041315715
#
 
结尾无空行
 

输出样例3:

在这里给出相应的输出。例如:

¥10000.00
 
结尾无空行
 

输入样例4:

在这里给出一组输入。例如:

6222081502001312390 88888888 06 -500.00
6222081502051320786 88888888 06 1200.00
6217000010041315715 88888888 02 1500.00
6217000010041315709  88888888 02 3500.00
6217000010041315715
#
 
结尾无空行
 

输出样例4:

在这里给出相应的输出。例如:

张无忌在中国工商银行的06号ATM机上存款¥500.00
当前余额为¥10500.00
韦小宝在中国工商银行的06号ATM机上取款¥1200.00
当前余额为¥8800.00
杨过在中国建设银行的02号ATM机上取款¥1500.00
当前余额为¥8500.00
杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥5000.00
¥5000.00
 
结尾无空行
代码如下:
查看代码
//package week12;

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

public class Main {
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String data = in.nextLine();
        //模式匹配
        String regstr = "(\\d{19})\\s+(\\d{8})\\s+(\\d{2})\\s+(-?\\d+\\.?\\d{2})";
        String smallregstr = "\\d{19}";
        Pattern pattern = Pattern.compile(regstr);
        Pattern smallpattern = Pattern.compile(smallregstr);
        //原始用户数据
        Account RootUser[]= new Account[10];
        RootUser[0]=new Account("6217000010041315709","杨过");
        RootUser[1]=new Account("6217000010041315715","杨过");
        RootUser[2]=new Account("6217000010041315718","杨过");
        RootUser[3]=new Account("6217000010051320007","郭靖");
        RootUser[4]=new Account("6222081502001312389","张无忌");
        RootUser[5]=new Account("6222081502001312390","张无忌");
        RootUser[6]=new Account("6222081502001312399","张无忌");
        RootUser[7]=new Account("6222081502001312400","张无忌");
        RootUser[8]=new Account("6222081502051320785","韦小宝");
        RootUser[9]=new Account("6222081502051320786","韦小宝");
        String[] IDsum= new String[]{"6217000010041315709","6217000010041315715","6217000010041315718","6217000010051320007",
                "6222081502001312389","6222081502001312390","6222081502001312399","6222081502001312400","6222081502051320785","6222081502051320786"};
        while(!data.equals("#")){
            Matcher matcher = pattern.matcher(data);
            int IDflag=0;
            if(matcher.find())//全匹配
            {
                for(int i=0;i<RootUser.length;i++){
                    String Bank="中国建设银行";
                    if(i>4)
                        Bank="中国工商银行";
                    String id=matcher.group(1);
                    //System.out.println(id);
                    if(Objects.equals(id, IDsum[i])){//卡号正确
                        //System.out.println(matcher.group(2));
                        if(Double.parseDouble(matcher.group(2))==88888888){//密码正确
                            if(Integer.parseInt(matcher.group(3))>6||Integer.parseInt(matcher.group(3))<1){
                                //System.out.println(Integer.parseInt(matcher.group(3)));
                                System.out.println("Sorry,the ATM's id is wrong.");
                                break;
                            }
                            if((i<=3&&Integer.parseInt(matcher.group(3))>4)||(i>3&&Integer.parseInt(matcher.group(3))<=4)){
                                System.out.println("Sorry,cross-bank withdrawal is not supported.");
                                break;
                            }
                            else{//ATM机正确
                                if(RootUser[i].updatemoney(Double.parseDouble(matcher.group(4)))){
                                    double money=0;
                                    if(Double.parseDouble(matcher.group(4))<0){
                                        money =-Double.parseDouble(matcher.group(4));
                                    }
                                    else{
                                        money =Double.parseDouble(matcher.group(4));
                                    }

                                    System.out.println(RootUser[i].Name+"在"+Bank+"的"+matcher.group(3)+"号ATM机上"+RootUser[i].accessmoney+"¥"+String.format("%.2f",money));
                                    System.out.println("当前余额为¥"+String.format("%.2f",RootUser[i].balance));
                                    if(i==0){
                                        RootUser[1].balance=RootUser[i].balance;
                                    }
                                    if(i==1){
                                        RootUser[0].balance=RootUser[i].balance;
                                    }
                                    if(i==6){
                                        RootUser[7].balance=RootUser[i].balance;
                                    }
                                    if(i==7){
                                        RootUser[6].balance=RootUser[i].balance;
                                    }
                                    break;
                                }
                            }
                        }
                        else {
                            System.out.println("Sorry,your password is wrong.");
                            break;
                        }
                    }
                    else{
                        IDflag++;
                    }
                    if(IDflag==10){
                        IDflag=0;
                        System.out.println("Sorry,this card does not exist.");
                        break;
                    }
                }
            } else {
                Matcher smallmatcher = smallpattern.matcher(data);
                if(smallmatcher.find())//卡号匹配
                {
                    //System.out.println(smallmatcher.group());
                    String id=smallmatcher.group(0);
                    for(int i=0;i<RootUser.length;i++){
                        if(Objects.equals(id, IDsum[i])){
                           System.out.println("¥"+String.format("%.2f",RootUser[i].balance));
                        }
                        else {
                            IDflag++;
                        }
                        if(IDflag==10){
                            IDflag=0;
                            System.out.println("Sorry,this card does not exist.");
                            break;
                        }
                    }
                }
            }
            data=in.nextLine();
        }
    }

}
class User{
    String IDcard;
    String Name;
}
class Account extends User{
    double balance=10000;//余额
    String accessmoney="";
    public Account(String IDcard,String Name){
        this.IDcard=IDcard;
        this.Name=Name;
    }
    public boolean updatemoney(double money){
        if(this.balance>=money){
            if(money>0){
                accessmoney="取款";
            }
            else{
                accessmoney="存款";
            }
            this.balance=this.balance-money;
            return true;
        }
        else{
            System.out.println("Sorry,your account balance is insufficient.");
            return false;
        }
    }
}

分析结果:

其实题目挺简单的,定义用户数组存入数据分别用正则表达式判断就行。

7-1 ATM机类结构设计(二) (100 分)
 

设计ATM仿真系统,具体要求参见作业说明。 OO作业9-1题目说明.pdf

输入格式:

每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:

  • 取款功能输入数据格式: 卡号 密码 ATM机编号 金额(由一个或多个空格分隔)
  • 查询余额功能输入数据格式: 卡号

输出格式:

①输入错误处理

  • 如果输入卡号不存在,则输出Sorry,this card does not exist.
  • 如果输入ATM机编号不存在,则输出Sorry,the ATM's id is wrong.
  • 如果输入银行卡密码错误,则输出Sorry,your password is wrong.
  • 如果输入取款金额大于账户余额,则输出Sorry,your account balance is insufficient.

②取款业务输出

输出共两行,格式分别为:

业务:取款 [用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

③查询余额业务输出

业务:查询余额 ¥[金额]

金额保留两位小数。

输入样例1:

在这里给出一组输入。例如:

6222081502001312390 88888888 06 500.00
#
 
结尾无空行
 

输出样例1:

在这里给出相应的输出。例如:

业务:取款 张无忌在中国工商银行的06号ATM机上取款¥500.00
当前余额为¥9500.00
 
结尾无空行
 

输入样例2:

在这里给出一组输入。例如:

6217000010041315709  88888888 06 3500.00
#
 
结尾无空行
 

输出样例2:

在这里给出相应的输出。例如:

业务:取款 杨过在中国工商银行的06号ATM机上取款¥3500.00
当前余额为¥6395.00
 
结尾无空行
 

输入样例3:

在这里给出一组输入。例如:

6217000010041315715
#
 
结尾无空行
 

输出样例3:

在这里给出相应的输出。例如:

业务:查询余额 ¥10000.00
 
结尾无空行
 

输入样例4:

在这里给出一组输入。例如:

6222081502001312390 88888888 01 500.00
6222081502051320786 88888888 06 1200.00
6217000010041315715 88888888 02 1500.00
6217000010041315709  88888888 02 3500.00
6217000010041315715
#
 
结尾无空行
 

输出样例4:

在这里给出相应的输出。例如:

业务:取款 张无忌在中国建设银行的01号ATM机上取款¥500.00
当前余额为¥9490.00
业务:取款 韦小宝在中国工商银行的06号ATM机上取款¥1200.00
当前余额为¥8800.00
业务:取款 杨过在中国建设银行的02号ATM机上取款¥1500.00
当前余额为¥8500.00
业务:取款 杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥5000.00
业务:查询余额 ¥5000.00
 
结尾无空行
 

输入样例5:

在这里给出一组输入。例如:

6640000010045442002 88888888 09 3000
6640000010045442002 88888888 06 8000
6640000010045442003 88888888 01 10000
6640000010045442002
#
 
结尾无空行
 

输出样例5:

在这里给出相应的输出。例如:

业务:取款 张三丰在中国农业银行的09号ATM机上取款¥3000.00
当前余额为¥6880.00
业务:取款 张三丰在中国工商银行的06号ATM机上取款¥8000.00
当前余额为¥-1416.00
业务:取款 张三丰在中国建设银行的01号ATM机上取款¥10000.00
当前余额为¥-11916.00
业务:查询余额 ¥-11916.00
 
结尾无空行
 
代码如下:
查看代码
//package week13;
import java.util.Objects;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.System.*;
public class Main {
    static Account[] RootUser = new Account[10+5];
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String data = in.nextLine();
        //模式匹配
        String regstr = "(\\d{19})\\s+(\\d{8})\\s+(\\d{2})\\s+(-?\\d{0,5}\\.?\\d{0,2})";
        String smallregstr = "\\d{19}";
        Pattern pattern = Pattern.compile(regstr);
        Pattern smallpattern = Pattern.compile(smallregstr);
        //借记账号
        RootUser[0]=new Account("中国建设银行","6217000010041315709","杨过");
        RootUser[1]=new Account("中国建设银行","6217000010041315715","杨过");
        RootUser[2]=new Account("中国建设银行","6217000010041315718","杨过");
        RootUser[3]=new Account("中国建设银行","6217000010051320007","郭靖");
        RootUser[4]=new Account("中国工商银行","6222081502001312389","张无忌");
        RootUser[5]=new Account("中国工商银行","6222081502001312390","张无忌");
        RootUser[6]=new Account("中国工商银行","6222081502001312399","张无忌");
        RootUser[7]=new Account("中国工商银行","6222081502001312400","张无忌");
        RootUser[8]=new Account("中国工商银行","6222081502051320785","韦小宝");
        RootUser[9]=new Account("中国工商银行","6222081502051320786","韦小宝");
        RootUser[10]=new Account("中国建设银行","6640000010045442002","张三丰");
        RootUser[11]=new Account("中国建设银行","6640000010045442003","张三丰");
        RootUser[12]=new Account("中国工商银行","6640000010045441009","令狐冲");
        RootUser[13]=new Account("中国农业银行","6630000010033431001","乔峰");
        RootUser[14]=new Account("中国农业银行","6630000010033431008","洪七公");
        String[] IDsum= new String[]{"6217000010041315709","6217000010041315715","6217000010041315718","6217000010051320007","6222081502001312389","6222081502001312390","6222081502001312399","6222081502001312400","6222081502051320785","6222081502051320786","6640000010045442002","6640000010045442003","6640000010045441009","6630000010033431001","6630000010033431008"};
        while(!data.equals("#")){
            Matcher matcher = pattern.matcher(data);
            int IDflag=0;
            if(matcher.find())//全匹配
            {
                for(int i=0;i<RootUser.length;i++){
                    String id=matcher.group(1);
                    if(Objects.equals(id, IDsum[i])){//卡号正确
                        if(Double.parseDouble(matcher.group(2))==88888888){//密码正确
                            if(Integer.parseInt(matcher.group(3))>11||Integer.parseInt(matcher.group(3))<1){
                                out.print("Sorry,the ATM's id is wrong.");
                                return;
                            }
                            else {//ATM机正确
                                String Bank="中国建设银行";
                                if(Integer.parseInt(matcher.group(3))>4)
                                    Bank="中国工商银行";
                                if(Integer.parseInt(matcher.group(3))>6)
                                    Bank="中国农业银行";
                                double rate=0;
                                String IDcardBank=RootUser[i].Bank;
                                if(IDcardBank!=Bank){
                                    switch(Bank){
                                        case "中国建设银行": rate=0.02;break;
                                        case "中国工商银行": rate=0.03;break;
                                        case "中国农业银行": rate=0.04;break;
                                    }
                                }
                                    if (RootUser[i].updatemoney(i,Double.parseDouble(matcher.group(4)),rate)) {
                                        double money;
                                        if (Double.parseDouble(matcher.group(4)) < 0)
                                            money = -Double.parseDouble(matcher.group(4));
                                        else
                                            money = Double.parseDouble(matcher.group(4));
                                        out.println("业务:"+RootUser[i].accessmoney+" "+RootUser[i].Name + "在" + Bank + "的" + matcher.group(3) + "号ATM机上" + RootUser[i].accessmoney + "¥" + String.format("%.2f", money));
                                        out.println("当前余额为¥" + String.format("%.2f", RootUser[i].balance));
                                        synchronization(i);//余额同步
                                    }else return;
                            }
                        }
                        else {
                            out.print("Sorry,your password is wrong.");
                            return;
                        }
                    }
                    else IDflag++;
                    if(IDflag==15){
                        System.out.print("Sorry,this card does not exist.");
                        return;
                    }
                }
            } else {
                Matcher smallmatcher = smallpattern.matcher(data);
                if(smallmatcher.find())//卡号匹配
                {
                    //System.out.println(smallmatcher.group());
                    String id=smallmatcher.group(0);
                    for(int i=0;i<RootUser.length;i++){
                        if(Objects.equals(id, IDsum[i]))
                            out.println("业务:查询余额 ¥"+String.format("%.2f",RootUser[i].balance));
                         else IDflag++;
                        if(IDflag==15){
                            out.print("Sorry,this card does not exist.");
                            return;
                        }
                    }
                }
            }
            data=in.nextLine();
        }
    }
    static void synchronization(int i){
        if (i == 0)
            RootUser[1].balance = RootUser[i].balance;
        if (i == 1)
            RootUser[0].balance = RootUser[i].balance;
        if (i == 6)
            RootUser[7].balance = RootUser[i].balance;
        if (i == 7)
            RootUser[6].balance = RootUser[i].balance;
        if (i == 10)
            RootUser[11].balance = RootUser[i].balance;
        if (i == 11)
            RootUser[10].balance = RootUser[i].balance;
    }
}
class User{
    String IDcard;
    String Name;
}
class Account extends User {
    double balance=10000;//余额
    String accessmoney="";
    String Bank;
    public Account(String Bank,String IDcard,String Name){
        this.Bank=Bank;
        this.IDcard=IDcard;
        this.Name=Name;
    }

    public boolean updatemoney(int i,double money,double rate){
        double borrowmoney=0;
        double borrowrate=0.05;
        if(i>9)
            borrowmoney=50000;
        if(this.balance+borrowmoney>=money*(1+rate)){
            if(money>0){
                accessmoney="取款";
                    if(this.balance-money*(1+rate)>=0){//余额够
                        this.balance=this.balance-money*(1+rate);
                    }
                    else{//余额不够,贷记
                        if(this.balance>=0) {
                            double Money = money - this.balance;
                            if(this.balance+borrowmoney>=money*(1+rate)+Money * borrowrate) {
                                this.balance = this.balance - money * (1 + rate) - Money * borrowrate;
                            }
                            else{
                                out.print("Sorry,your account balance is insufficient.");
                                return false;
                            }
                        }
                        else {
                            if(this.balance+borrowmoney>=money*(1+rate+borrowrate)) {
                                this.balance -= money*(1+rate+borrowrate);
                            }
                            else{
                                out.print("Sorry,your account balance is insufficient.");
                                return false;
                            }
                        }
                    }
            }
            if(money<=0){
                accessmoney="存款";
                this.balance=this.balance-money;
            }
            return true;
        }
        else{
            out.print("Sorry,your account balance is insufficient.");
            return false;
        }
    }
}

 分析结果:

本题仅仅改动了一小部分,将借记卡和贷记卡区别对待,其他的内容原封不动就好。

三、踩坑“心得”

一开始ATM设计的时候我少复制数据了一直报错,想了好久一直没头绪,后来看看,啊洪七公在另外一页,然后坑就跳出去了。

还有前面的Main.input啥的,一开始在IEDA上正常跑,PTA就怎么样都不行,后来发现原来是Main没有一起改,老师给的避免踩坑建议让我踩坑了还行。

四、改进建议

复用!多态!用起来!我的代码虽然不长但是冗余还是很严重,一定要改掉这一点。

五、总结

       面向对象程序设计学习也告一段落了,课程诚然是一门专业课,给我很多专业知识以及专业技能上的提升,同时又是一门讲道课,一门辩思课,给了我许多道,给了我很多思,给了我莫大的空间。同时,设计让我感触很深。使我对抽象的理论有了具体的认识。

       我认为,在这学期的实验中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。这对于我们的将来也有很大的帮助。以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。

       回顾起此课程设计,至今我仍感慨颇多,从理论到实践,在这段日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,但可喜的是最终都得到了解决。

posted @ 2021-12-18 19:41  LoseYoung  阅读(89)  评论(0)    收藏  举报