题目集7-9的分析及总结
一. 前言
首先,总结一下这三次题目集的我的个人感受及做题情况。从题量上看,三次题目集的题量都只有1到2题;从题目质量和难度上看,题目质量个人感觉是整体质量不错,尤其是有些测试点的位置比较巧妙,难度相对看不是很难,只要设计的巧妙就可以避免很多不必要的繁琐;从知识点看,这三次题目集,第一次题目集主要考察的是继承和多态的使用,以及Arraylist类的灵活应用,第二次题目集和第三次题目集都是编写一个银行ATM机的模拟程序,我个人感觉更多的考验自己设计程序结构的能力以及多态继承方面的灵活应用。
二. 设计与分析
-
题目集7(7-1)、(7-2)俩道题目的递进式设计分析总结
这俩个题目内容比较相似,7-1是图形卡片排序,7-2是图形卡片分组排序:
7-1:

7-2:

7-1源码
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author:everglow
* @data 2021/11/17 20:44
*/
public class Main{
ArrayList<Shape> test = new ArrayList<>();
Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
Main f = new Main();
f.input();
f.show_messages();
}
public void input() {
int a = sc.nextInt();
int[] as = new int[100];
int i = 0;
while (a != 0) {
as[i] = a;
i++;
a = sc.nextInt();
}
for(int j=0;j<i;j++){
if(as[j]<0||as[j]>4){
System.out.println("Wrong Format");
System.exit(0);
}
}
for(int j=0;j<i;j++) {
switch (as[j]) {
case 1:
Shape x = new Circle(sc.nextDouble());
if (!x.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(x);
break;
case 2:
Shape y = new Rectangle(sc.nextDouble(), sc.nextDouble());
if (!y.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(y);
break;
case 3:
Shape z = new Triangle(sc.nextDouble(), sc.nextDouble(), sc.nextDouble());
if (!z.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(z);
break;
case 4:
Shape m = new Trapezoid(sc.nextDouble(), sc.nextDouble(), sc.nextDouble());
if (!m.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(m);
break;
default:
System.out.println("Wrong Format");
System.exit(0);
break;
}
}
}
public void show_messages() {
double sum = 0;
System.out.println("The original list:");
for (int i = 0; i < test.size(); i++) {
sum = sum + test.get(i).getArea();
if (i == test.size() - 1) {
System.out.printf(test.get(i).set_name()+"%.2f ", test.get(i).getArea());
break;
}
System.out.printf(test.get(i).set_name()+"%.2f ", test.get(i).getArea());
}
System.out.println();
for (int i = 0; i < test.size() - 1; i++) {
for (int j = 1; j < test.size(); j++) {
if (test.get(j - 1).getArea() < test.get(j).getArea()) {
Shape temp = test.get(j);
test.set(j, test.get(j - 1));
test.set(j - 1, temp);
}
}
}
System.out.println("The sorted list:");
for (int i = 0; i < test.size(); i++) {
if (i == test.size() - 1) {
System.out.printf(test.get(i).set_name()+"%.2f ", test.get(i).getArea());
break;
}
System.out.printf(test.get(i).set_name()+"%.2f ", test.get(i).getArea());
}
System.out.println();
System.out.printf("Sum of area:%.2f\n", sum);
}
}
abstract class Shape{
abstract double getArea();
abstract boolean validate();
abstract String set_name();
}
class Circle extends Shape {
String name;
private double radius;
Circle(double radius){
name="Circle:";
this.radius=radius;
}
@Override
double getArea(){
return Math.PI*radius*radius;
}
@Override
boolean validate(){
if(radius>0){
return true;
}
return false;
}
@Override
String set_name(){
return name;
}
}
class Rectangle extends Shape {
String name;
private double width;
private double length;
Rectangle(double width,double length){
name="Rectangle:";
this.width=width;
this.length=length;
}
@Override
double getArea(){
return width*length;
}
@Override
boolean validate(){
if(width>=0&&length>=0){
return true;
}
return false;
}
@Override
String set_name(){
return name;
}
}
class Triangle extends Shape {
String name;
private double side1;
private double side2;
private double side3;
Triangle(double side1,double side2,double side3){
name="Triangle:";
this.side1=side1;
this.side2=side2;
this.side3=side3;
}
@Override
double getArea(){
double p=(side1+side2+side3)/2;
return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
}
@Override
boolean validate(){
if(side1>=0&&side2>=0&&side3>=0&&side1+side2>side3
&&side3+side2>side1
&&side1+side3>side2){
return true;
}
return false;
}
@Override
String set_name(){
return name;
}
}
class Trapezoid extends Shape{
String name;
private double up;
private double down;
private double high;
Trapezoid(double up,double down,double high){
name="Trapezoid:";
this.up=up;
this.down=down;
this.high=high;
}
@Override
boolean validate(){
if(up>0&&down>0&&high>0){
return true;
}
return false;
}
@Override
double getArea(){
return (up+down)*high/2;
}
@Override
String set_name(){
return name;
}
}
7-2源码
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
/**
* @author:everglow
* @data 2021/11/17 22:30
*/
public class Main {
ArrayList<Shape> test = new ArrayList<>();
ArrayList<Shape> test1 = new ArrayList<>();
ArrayList<Shape> test2 = new ArrayList<>();
ArrayList<Shape> test3 = new ArrayList<>();
ArrayList<Shape> test4 = new ArrayList<>();
Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
Main f = new Main();
f.input();
f.show_messages();
}
public void input() {
int a = sc.nextInt();
int[] as = new int[100];
int i = 0;
while (a != 0) {
as[i] = a;
i++;
a = sc.nextInt();
}
if(i==0){
System.out.println("Wrong Format");
System.exit(0);
}
for(int j=0;j<i;j++){
if(as[j]<0||as[j]>4){
System.out.println("Wrong Format");
System.exit(0);
}
}
for(int j=0;j<i;j++) {
switch (as[j]) {
case 1:
Shape x = new Circle(sc.nextDouble());
if (!x.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(x);
test1.add(x);
break;
case 2:
Shape y = new Rectangle(sc.nextDouble(), sc.nextDouble());
if (!y.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(y);
test2.add(y);
break;
case 3:
Shape z = new Triangle(sc.nextDouble(), sc.nextDouble(), sc.nextDouble());
if (!z.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(z);
test3.add(z);
break;
case 4:
Shape m = new Trapezoid(sc.nextDouble(), sc.nextDouble(), sc.nextDouble());
if (!m.validate()) {
System.out.println("Wrong Format");
System.exit(0);
}
test.add(m);
test4.add(m);
break;
default:
System.out.println("Wrong Format");
System.exit(0);
break;
}
}
}
public void show_messages() {
double sum1 = 0,sum2=0,sum3=0,sum4=0;
System.out.println("The original list:");
System.out.print("[");
for (int i = 0; i < test.size(); i++) {
System.out.printf(test.get(i).set_name()+"%.2f ", test.get(i).getArea());
}
System.out.println("]");
System.out.println("The Separated List:");
System.out.print("[");
for (int i = 0; i < test1.size(); i++) {
sum1 = sum1 + test1.get(i).getArea();
System.out.printf(test1.get(i).set_name()+"%.2f ", test1.get(i).getArea());
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < test2.size(); i++) {
sum2 = sum2 + test2.get(i).getArea();
System.out.printf(test2.get(i).set_name()+"%.2f ", test2.get(i).getArea());
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < test3.size(); i++) {
sum3 = sum3 + test3.get(i).getArea();
System.out.printf(test3.get(i).set_name()+"%.2f ", test3.get(i).getArea());
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < test4.size(); i++) {
sum4 = sum4 + test4.get(i).getArea();
System.out.printf(test4.get(i).set_name()+"%.2f ", test4.get(i).getArea());
}
System.out.println("]");
Collections.sort(test1);
Collections.sort(test2);
Collections.sort(test3);
Collections.sort(test4);
System.out.println("The Separated sorted List:");
System.out.print("[");
for (int i = 0; i < test1.size(); i++) {
System.out.printf(test1.get(i).set_name()+"%.2f ", test1.get(i).getArea());
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < test2.size(); i++) {
System.out.printf(test2.get(i).set_name()+"%.2f ", test2.get(i).getArea());
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < test3.size(); i++) {
System.out.printf(test3.get(i).set_name()+"%.2f ", test3.get(i).getArea());
}
System.out.print("]");
System.out.print("[");
for (int i = 0; i < test4.size(); i++) {
System.out.printf(test4.get(i).set_name()+"%.2f ", test4.get(i).getArea());
}
System.out.println("]");
System.out.printf("The max area:%.2f\n", Math.max(Math.max(sum1,sum2),Math.max(sum3,sum4)));
}
}
abstract class Shape implements Comparable<Shape>{
abstract double getArea();
abstract boolean validate();
abstract String set_name();
}
class Circle extends Shape implements Comparable<Shape>{
String name;
private double radius;
Circle(double radius){
name="Circle:";
this.radius=radius;
}
@Override
double getArea(){
return Math.PI*radius*radius;
}
@Override
boolean validate(){
if(radius>0){
return true;
}
return false;
}
@Override
String set_name(){
return name;
}
@Override
public int compareTo(Shape o){
if(this.getArea()>o.getArea()){
return -1;
}
else if(this.getArea()<o.getArea()){
return 1;
}
return 0;
}
}
class Rectangle extends Shape implements Comparable<Shape>{
String name;
private double width;
private double length;
Rectangle(double width,double length){
name="Rectangle:";
this.width=width;
this.length=length;
}
@Override
double getArea(){
return width*length;
}
@Override
boolean validate(){
if(width>=0&&length>=0){
return true;
}
return false;
}
@Override
String set_name(){
return name;
}
@Override
public int compareTo(Shape o){
if(this.getArea()>o.getArea()){
return -1;
}
else if(this.getArea()<o.getArea()){
return 1;
}
return 0;
}
}
class Triangle extends Shape implements Comparable<Shape>{
String name;
private double side1;
private double side2;
private double side3;
Triangle(double side1,double side2,double side3){
name="Triangle:";
this.side1=side1;
this.side2=side2;
this.side3=side3;
}
@Override
double getArea(){
double p=(side1+side2+side3)/2;
return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
}
@Override
boolean validate(){
if(side1>=0&&side2>=0&&side3>=0&&side1+side2>side3
&&side3+side2>side1
&&side1+side3>side2){
return true;
}
return false;
}
@Override
String set_name(){
return name;
}
@Override
public int compareTo(Shape o){
if(this.getArea()>o.getArea()){
return -1;
}
else if(this.getArea()<o.getArea()){
return 1;
}
return 0;
}
}
class Trapezoid extends Shape implements Comparable<Shape>{
String name;
private double up;
private double down;
private double high;
Trapezoid(double up,double down,double high){
name="Trapezoid:";
this.up=up;
this.down=down;
this.high=high;
}
@Override
boolean validate(){
if(up>0&&down>0&&high>0){
return true;
}
return false;
}
@Override
double getArea(){
return (up+down)*high/2;
}
@Override
String set_name(){
return name;
}
@Override
public int compareTo(Shape o){
if(this.getArea()>o.getArea()){
return -1;
}
else if(this.getArea()<o.getArea()){
return 1;
}
return 0;
}
}
度量:(方法和类)
7-1复杂度分析:
| Method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| seventhpta.Circle.Circle(double) | 0 | 1 | 1 | 1 |
| seventhpta.Circle.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Circle.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Circle.validate() | 1 | 2 | 1 | 2 |
| seventhpta.First.input() | 20 | 1 | 9 | 14 |
| seventhpta.First.main(String[]) | 0 | 1 | 1 | 1 |
| seventhpta.First.show_messages() | 12 | 5 | 8 | 8 |
| seventhpta.Rectangle.Rectangle(double,double) | 0 | 1 | 1 | 1 |
| seventhpta.Rectangle.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Rectangle.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Rectangle.validate() | 2 | 2 | 1 | 3 |
| seventhpta.Trapezoid.Trapezoid(double,double,double) | 0 | 1 | 1 | 1 |
| seventhpta.Trapezoid.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Trapezoid.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Trapezoid.validate() | 2 | 2 | 1 | 4 |
| seventhpta.Triangle.Triangle(double,double,double) | 0 | 1 | 1 | 1 |
| seventhpta.Triangle.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Triangle.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Triangle.validate() | 2 | 2 | 1 | 7 |
| Class | OCavg | OCmax | WMC | |
| seventhpta.Circle | 1.25 | 2 | 5 | |
| seventhpta.First | 7.67 | 14 | 23 | |
| seventhpta.Rectangle | 1.25 | 2 | 5 | |
| seventhpta.Shape | n/a | n/a | 0 | |
| seventhpta.Trapezoid | 1.25 | 2 | 5 | |
| seventhpta.Triangle | 1.25 | 2 | 5 |
7-2复杂度分析:
| Method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| seventhpta.Circle.Circle(double) | 0 | 1 | 1 | 1 |
| seventhpta.Circle.compareTo(Shape) | 2 | 3 | 2 | 3 |
| seventhpta.Circle.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Circle.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Circle.validate() | 1 | 2 | 1 | 2 |
| seventhpta.Main.input() | 21 | 1 | 10 | 15 |
| seventhpta.Main.main(String[]) | 0 | 1 | 1 | 1 |
| seventhpta.Main.show_messages() | 9 | 1 | 10 | 10 |
| seventhpta.Rectangle.Rectangle(double,double) | 0 | 1 | 1 | 1 |
| seventhpta.Rectangle.compareTo(Shape) | 2 | 3 | 2 | 3 |
| seventhpta.Rectangle.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Rectangle.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Rectangle.validate() | 2 | 2 | 1 | 3 |
| seventhpta.Trapezoid.Trapezoid(double,double,double) | 0 | 1 | 1 | 1 |
| seventhpta.Trapezoid.compareTo(Shape) | 2 | 3 | 2 | 3 |
| seventhpta.Trapezoid.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Trapezoid.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Trapezoid.validate() | 2 | 2 | 1 | 4 |
| seventhpta.Triangle.Triangle(double,double,double) | 0 | 1 | 1 | 1 |
| seventhpta.Triangle.compareTo(Shape) | 2 | 3 | 2 | 3 |
| seventhpta.Triangle.getArea() | 0 | 1 | 1 | 1 |
| seventhpta.Triangle.set_name() | 0 | 1 | 1 | 1 |
| seventhpta.Triangle.validate() | 2 | 2 | 1 | 7 |
| Class | OCavg | OCmax | WMC | |
| seventhpta.Circle | 1.6 | 3 | 8 | |
| seventhpta.Main | 8.67 | 15 | 26 | |
| seventhpta.Rectangle | 1.6 | 3 | 8 | |
| seventhpta.Shape | n/a | n/a | 0 | |
| seventhpta.Trapezoid | 1.6 | 3 | 8 | |
| seventhpta.Triangle | 1.6 | 3 | 8 |
UML类图:
7-1类图:

7-2类图:

递进式设计分析总结:
7-1跟7-2设计思路相近,总体来看7-2是7-1的升级版本,很多在7-1设计时没有考虑的因素都需要在7-2上使用。
先看类图:
7-1与7-2都是各种图形继承Shape抽象类,Main类聚合Shape类,类图上最大的区别就是7-2相较于7-1使用了Comparable接口用来实现排序,而我7-1实现排序的使用的冒泡排序没有使用接口,当时在做7-1时自己就考虑到排序应该如何相对简便,而是用自己最熟悉的方法去排序,这样当需要完成7-2的需求的时就会需要改动比较大,而通过使用Comparable接口,可以直接使用内部排序方法,让排序变得更为简单,缩短代码量,程序逻辑性也更高。
再看复杂度分析:
根据IDEA的分析复杂度工具显示可以看到,由于俩道题目设计思路相近,所以复杂度差异不会很大,这也从侧面上验证使用虽然7-2比7-1题目需求更为复杂一些,而且还使用了接口,但是复杂度增加的不明显,并且还使代码更为简洁,足以见得使用接口可以让我们更为轻松方便的完成想要的需求。
递进式设计总结:
这俩个题目JAVA的继承和多态,每种图形作为一个类,然后去继承一个Shape类,然后再创建对象时使用多态,这样能提高代码的可复用性和可维护性。虽然我没有在第一个题目使用Comparable接口,但是我后一题根据题目提示改进自己的代码,使用到Comparable接口,而不是去使用以前的冒泡排序法、插入排序法等,这样提高了代码的简洁性,减小了圈复杂度,这也更加告诉我们,以后在遇到类似的问题时,可以优先考虑是否可以使用接口去实现需求。这俩道题在存储类上面都使用到了ArrayList类,通过使用ArrayList可以让程序在需要增加类时随意增加,而不需要考虑吧存储空间的不够之类的问题,动态扩增大小,提高代码的复用性。
-
题目集8和题目集9俩道ATM仿真题目的设计思路分析总结
这俩道题目时做一个ATM仿真程序:题目集9相对于题目集8增加了一些功能,画话不多说,看题目内容:
题目集8:

题目集9:

题目集8 ATM仿真题目源码
package eighthpta;
import java.lang.ref.PhantomReference;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author:everglow
* @data 2021/11/23 13:48
*/
public class Main {
ArrayList<ATM> atms=new ArrayList<>();
Scanner sc=new Scanner(System.in);
StringBuffer s=new StringBuffer();
String test1;
String[] IDS=new String[]{"6217000010041315709","6217000010041315715","6217000010041315718",
"6217000010051320007","6222081502001312389","6222081502001312390",
"6222081502001312399","6222081502001312400",
"6222081502051320785","6222081502051320786"};
Main(){
atms.add(new ATM("01","中国建设银行"));
atms.add(new ATM("02","中国建设银行"));
atms.add(new ATM("03","中国建设银行"));
atms.add(new ATM("04","中国建设银行"));
atms.add(new ATM("05","中国工商银行"));
atms.add(new ATM("06","中国工商银行"));
}
public static void main(String[] args) {
Main test=new Main();
test.input();
test.format();
}
public void input(){
String a=sc.nextLine();
while(!a.equals("#")){
s.append(a).append("\n");
a=sc.nextLine();
}
test1=String.valueOf(s);
}
public void format(){
String[] tests=test1.split("\n");
for (int i=0;i<tests.length;i++)
{
String s=tests[i].toString();
String[] a=s.split("[' ']+");
switch (a.length) {
case 1:
idvalidate(a[0]);
for(int j=0;j<atms.get(0).users.size();j++){
int k=0;
for (k=0;k<atms.get(0).users.get(j).cardsID.size();k++) {
if(atms.get(0).users.get(j).cardsID.get(k).equals(a[0])){
System.out.print("¥"+String.format("%.2f",atms.get(0).users.get(j).getPrimarymoney()));
}
}
}
for(int j=0;j<atms.get(4).users.size();j++){
int k=0;
for (k=0;k<atms.get(4).users.get(j).cardsID.size();k++) {
if(atms.get(4).users.get(j).cardsID.get(k).equals(a[0])){
System.out.print("¥"+String.format("%.2f",atms.get(4).users.get(j).getPrimarymoney()));
}
}
}
break;
case 4:
String id=a[0];
String pass=a[1];
String at=a[2];
String money=a[3];
idvalidate(id);
atmvalidata(at);
passvalidate(pass);
int j;
for(j=0;j<atms.size();j++){
if(at.equals(atms.get(j).getSerialNumber())){
break;
}
}
int m;
int flag=0;
for(m=0;m<atms.get(j).users.size();m++){
int k=0;
for (k=0;k<atms.get(j).users.get(m).cardsID.size();k++){
if(atms.get(j).users.get(m).cardsID.get(k).equals(id)){
flag=1;
double money1=Double.parseDouble(money);
atms.get(j).users.get(m).setMoney(money1);
if(money1>0) {
if(money1>atms.get(j).users.get(m).getPrimarymoney()){
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.println(atms.get(j).users.get(m).getUserName() + "在" +
atms.get(j).users.get(m).getBankName() + "的"
+ atms.get(j).getSerialNumber() + "号ATM机上取款¥" + String.format("%.2f",money1));
System.out.print("当前余额为¥" + String.format("%.2f",atms.get(j).users.get(m).getPrimarymoney()));
update(m,atms.get(j).users.get(m).getPrimarymoney(),atms.get(j).getBankName());
}
else {
System.out.println(atms.get(j).users.get(m).getUserName() + "在" +
atms.get(j).users.get(m).getBankName() + "的"
+ atms.get(j).getSerialNumber() + "号ATM机上存款¥" + String.format("%.2f",money1*-1));
System.out.print("当前余额为¥" + String.format("%.2f",atms.get(j).users.get(m).getPrimarymoney()));
update(m,atms.get(j).users.get(m).getPrimarymoney(),atms.get(j).getBankName());
}
}
}
}
if(flag==0){
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
break;
default:
break;
}
if(i<=tests.length-2){
System.out.print("\n");
}
}
}
public void update(int temp,double x,String s){
for(int i=0;i<atms.size();i++){
if(atms.get(i).getBankName().equals(s)){
atms.get(i).users.get(temp).update(x);
}
}
}
public void passvalidate(String pass){
if(!pass.equals("88888888")){
System.out.println("Sorry,your password is wrong.");
System.exit(0);
}
}
public void atmvalidata(String at){
if(!at.matches("0[1-6]")){
System.out.println("Sorry,the ATM's id is wrong.");
System.exit(0);
}
}
public void idvalidate(String id) {
for (int i1=0;i1<IDS.length;i1++){
if(id.equals(IDS[i1])){
break;
}
if(i1== IDS.length-1){
System.out.println("Sorry,this card does not exist.");
System.exit(0);
}
}
}
}
class Account{
private double primarymoney;
private String ID;
private String userName;
LinkedList<String> cardsID=new LinkedList<>();
private String bankName;
private String password;
Account(String ID,String userName,String cardID,String bankName){
this.bankName=bankName;
this.cardsID.add(cardID);
this.ID=ID;
this.primarymoney=10000;
this.userName=userName;
this.password="88888888";
}
String getID(){
return ID;
}
void setID(String ID){
this.ID=ID;
}
String getUserName(){
return userName;
}
void setUserName(String userName){
this.userName=userName;
}
LinkedList<String> getCardID(){
return cardsID;
}
void setCardID(LinkedList cardID){
this.cardsID=cardID;
}
String getBankName(){
return bankName;
}
void setBankName(String bankName){
this.bankName=bankName;
}
void setMoney(double primarymoney){
if(primarymoney>0) {
this.primarymoney -= primarymoney;
}
else {
this.primarymoney -= primarymoney;
}
}
void update(double x){
this.primarymoney=x;
}
double getPrimarymoney(){
return primarymoney;
}
}
class ATM{
ArrayList<Account> users=new ArrayList<>();
private String serialNumber;
private String bankName;
ATM(String serialNumber,String bankName){
this.bankName=bankName;
this.serialNumber=serialNumber;
if(this.bankName.equals("中国建设银行")){
users.add(new Account("3217000010041315709","杨过",
"6217000010041315715","中国建设银行"));
users.get(0).cardsID.add("6217000010041315709");
users.add(new Account("3217000010041315715","杨过",
"6217000010041315718","中国建设银行"));
users.add(new Account("3217000010051320007","郭靖",
"6217000010051320007","中国建设银行"));
}
if(this.bankName.equals("中国工商银行")){
users.add(new Account("3222081502001312389","张无忌",
"6222081502001312389","中国工商银行"));
users.add(new Account("3222081502001312390","张无忌",
"6222081502001312390","中国工商银行"));
users.add(new Account("3222081502001312399","张无忌",
"6222081502001312399","中国工商银行"));
users.get(2).cardsID.add("6222081502001312400");
users.add(new Account("3222081502051320785","韦小宝",
"6222081502051320785","中国工商银行"));
users.add(new Account("3222081502051320786","韦小宝",
"6222081502051320786","中国工商银行"));
}
}
String getBankName(){
return bankName;
}
void setBankName(String bankName){
this.bankName=bankName;
}
String getSerialNumber(){
return serialNumber;
}
void setSerialNumber(String serialNumber){
this.serialNumber=serialNumber;
}
}
题目集9 ATM仿真题目源码
package ninthpta;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author:everglow
* @data 2021/11/30 14:19
*/
public class Main{
Scanner sc=new Scanner(System.in);
StringBuffer s=new StringBuffer();
String test1;
ArrayList<Bank> banks=new ArrayList<>();
public static void main(String[] args) {
Main test=new Main();
test.input();
test.format();
}
Main(){
banks.add(new Bank("中国建设银行"));
banks.add(new Bank("中国工商银行"));
banks.add(new Bank("中国农业银行"));
}
public void input(){
String a=sc.nextLine();
while(!a.equals("#")){
s.append(a).append("\n");
a=sc.nextLine();
}
test1=String.valueOf(s);
}
public void format(){
String[] tests=test1.split("\n");
for (int i=0;i<tests.length;i++)
{
int[] ids=new int[4];
String s=tests[i].toString();
String[] a=s.split("[' ']+");
switch (a.length) {
case 1:
ids=findid(a[0]);
if(ids[0]==99){
System.out.println("Sorry,this card does not exist.");
System.exit(0);
}
System.out.println("业务:查询余额 ¥"+
String.format("%.2f",banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).getmoney()));
break;
case 4:
String id=a[0];
String pass=a[1];
String at=a[2];
String money=a[3];
Double moneyx=Double.parseDouble(money);
ids=findid(a[0]);
if(ids[0]==99){
System.out.println("Sorry,this card does not exist.");
System.exit(0);
}
atmvalidata(at);
int x=findatm(at);
passvalidate(pass);
if(banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).kind==true){
if(banks.get(ids[0]).name.equals(banks.get(x).name)){
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).takemoney(moneyx);
System.out.println("业务:取款 "+banks.get(ids[0]).users.get(ids[1]).name+"在"+banks.get(x).name+"的"+at+"号ATM机上取款¥"
+String.format("%.2f",moneyx));
System.out.println("当前余额为¥"+String.format("%.2f",
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).getmoney()));
}
else {
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).takemoney(moneyx,banks.get(x).fee);
System.out.println("业务:取款 "+banks.get(ids[0]).users.get(ids[1]).name+"在"+banks.get(x).name+"的"+at+"号ATM机上取款¥"
+String.format("%.2f",moneyx));
System.out.println("当前余额为¥"+String.format("%.2f",
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).getmoney()));
}
}
else {
if(banks.get(ids[0]).name.equals(banks.get(x).name)){
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).takemoney(moneyx);
System.out.println("业务:取款 "+banks.get(ids[0]).users.get(ids[1]).name+"在"+banks.get(x).name+"的"+at+"号ATM机上取款¥"
+String.format("%.2f",moneyx));
System.out.println("当前余额为¥"+String.format("%.2f",
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).getmoney()));
}
else {
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).takemoney(moneyx,banks.get(x).fee);
System.out.println("业务:取款 "+banks.get(ids[0]).users.get(ids[1]).name+"在"+banks.get(x).name+"的"+at+"号ATM机上取款¥"
+String.format("%.2f",moneyx));
System.out.println("当前余额为¥"+String.format("%.2f",
banks.get(ids[0]).users.get(ids[1]).accounts.get(ids[2]).getmoney()));
}
}
break;
default:
break;
}
}
}
public int findatm(String atm){
for(int i=0;i<banks.size();i++){
for(int j=0;j<banks.get(i).atms.size();j++){
if(banks.get(i).atms.get(j).serialNumber.equals(atm)){
return i;
}
}
}
return 0;
}
public void passvalidate(String pass){
if(!pass.equals("88888888")){
System.out.println("Sorry,your password is wrong.");
System.exit(0);
}
}
public void atmvalidata(String at){
if(!at.matches("0[1-9]|1[0-1]")){
System.out.println("Sorry,the ATM's id is wrong.");
System.exit(0);
}
}
public int[] findid(String id){
int[] ids=new int[]{99,99,99,99};
for(int i=0;i<banks.size();i++){
for(int j=0;j<banks.get(i).users.size();j++){
for(int k=0;k<banks.get(i).users.get(j).accounts.size();k++){
for(int l=0;l<banks.get(i).users.get(j).accounts.get(k).cards.size();l++){
if(banks.get(i).users.get(j).accounts.get(k).cards.get(l).id.equals(id)){
ids[0]=i;
ids[1]=j;
ids[2]=k;
ids[3]=l;
return ids;
}
}
}
}
}
return ids;
}
}
class Bank{
String name;
ArrayList<ATM> atms=new ArrayList<>();
ArrayList<User> users=new ArrayList<>();
double fee;
double tofee=0.05;
Bank(String name){
this.name=name;
if(this.name.equals("中国建设银行")){
atms.add(new ATM("01"));
atms.add(new ATM("02"));
atms.add(new ATM("03"));
atms.add(new ATM("04"));
users.add(new User("杨过"));
users.add(new User("郭靖"));
users.add(new User("张三丰"));
fee=0.02;
}
if(this.name.equals("中国工商银行")){
atms.add(new ATM("05"));
atms.add(new ATM("06"));
users.add(new User("张无忌"));
users.add(new User("韦小宝"));
users.add(new User("令狐冲"));
fee=0.03;
}
if(this.name.equals("中国农业银行")){
atms.add(new ATM("07"));
atms.add(new ATM("08"));
atms.add(new ATM("09"));
atms.add(new ATM("10"));
atms.add(new ATM("11"));
users.add(new User("乔峰"));
users.add(new User("洪七公"));
fee=0.04;
}
}
}
class User{
ArrayList<Account> accounts=new ArrayList<>();
String name;
User(String name){
this.name=name;
if(this.name.equals("杨过")){
accounts.add(new Account("3217000010041315709",false));
accounts.add(new Account("3217000010041315715",false));
}
if(this.name.equals("郭靖")){
accounts.add(new Account("3217000010051320007",false));
}
if(this.name.equals("张无忌")){
accounts.add(new Account("3222081502001312389",false));
accounts.add(new Account("3222081502001312390",false));
accounts.add(new Account("3222081502001312399",false));
}
if(this.name.equals("韦小宝")){
accounts.add(new Account("3222081502051320785",false));
accounts.add(new Account("3222081502051320786",false));
}
if(this.name.equals("张三丰")){
accounts.add(new Account("3640000010045442002",true));
}
if(this.name.equals("令狐冲")){
accounts.add(new Account("3640000010045441009",true));
}
if(this.name.equals("乔峰")){
accounts.add(new Account("3630000010033431001",true));
}
if(this.name.equals("洪七公")){
accounts.add(new Account("3630000010033431008",true));
}
}
}
class Account{
boolean kind;
String id;
ArrayList<Card> cards=new ArrayList<>();
double money;
Account(String id,boolean kind){
money=10000;
this.id=id;
this.kind=kind;
if(this.id.equals("3217000010041315709")){
cards.add(new Card("6217000010041315709"));
cards.add(new Card("6217000010041315715"));
}
if(this.id.equals("3217000010041315715")){
cards.add(new Card("6217000010041315718"));
}
if(this.id.equals("3217000010051320007")){
cards.add(new Card("6217000010051320007"));
}
if(this.id.equals("3222081502001312389")){
cards.add(new Card("6222081502001312389"));
}
if(this.id.equals("3222081502001312390")){
cards.add(new Card("6222081502001312390"));
}
if(this.id.equals("3222081502001312399")){
cards.add(new Card("6222081502001312399"));
cards.add(new Card("6222081502001312400"));
}
if(this.id.equals("3222081502051320785")){
cards.add(new Card("6222081502051320785"));
}
if(this.id.equals("3222081502051320786")){
cards.add(new Card("6222081502051320786"));
}
if(this.id.equals("3640000010045442002")){
cards.add(new Card("6640000010045442002"));
cards.add(new Card("6640000010045442003"));
}
if(this.id.equals("3640000010045441009")){
cards.add(new Card("6640000010045441009"));
}
if(this.id.equals("3630000010033431001")){
cards.add(new Card("6630000010033431001"));
}
if(this.id.equals("3630000010033431008")){
cards.add(new Card("6630000010033431008"));
}
}
void takemoney(double x){
if((x>this.money&&kind==false)||(kind==true&&(x*1.05-money)>50000)) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
if(x>money){
if(money>0){
x=x-money;
this.money=0;
this.money-=x*1.05;
}
else {
this.money-=x*1.05;
}
}
else {
this.money -= x;
}
}
void takemoney(double x,double fee){
if((x*(1+fee)>this.money&&kind==false)||(kind==true&&(x*1.05-money)>50000)) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
if(x>money){
if(money>0){
double z=money;
double y=x*(1+fee)-money;
this.money=0;
this.money-=(y+(x-z)*0.05);
}
else {
this.money-=(x*1.05+x*fee);
}
}
else {
this.money -= x*(1+fee);
}
}
double getmoney(){
return money;
}
}
class Card{
String id;
Card(String id){
this.id=id;
}
}
class ATM{
String serialNumber;
ATM(String id){
this.serialNumber=id;
}
}
度量:(方法和类)
题目集8复杂度分析:
| Method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| eighthpta.ATM.ATM(String,String) | 2 | 1 | 3 | 3 |
| eighthpta.ATM.getBankName() | 0 | 1 | 1 | 1 |
| eighthpta.ATM.getSerialNumber() | 0 | 1 | 1 | 1 |
| eighthpta.ATM.setBankName(String) | 0 | 1 | 1 | 1 |
| eighthpta.ATM.setSerialNumber(String) | 0 | 1 | 1 | 1 |
| eighthpta.Account.Account(String,String,String,String) | 0 | 1 | 1 | 1 |
| eighthpta.Account.getBankName() | 0 | 1 | 1 | 1 |
| eighthpta.Account.getCardID() | 0 | 1 | 1 | 1 |
| eighthpta.Account.getID() | 0 | 1 | 1 | 1 |
| eighthpta.Account.getPrimarymoney() | 0 | 1 | 1 | 1 |
| eighthpta.Account.getUserName() | 0 | 1 | 1 | 1 |
| eighthpta.Account.setBankName(String) | 0 | 1 | 1 | 1 |
| eighthpta.Account.setCardID(LinkedList) | 0 | 1 | 1 | 1 |
| eighthpta.Account.setID(String) | 0 | 1 | 1 | 1 |
| eighthpta.Account.setMoney(double) | 2 | 1 | 1 | 2 |
| eighthpta.Account.setUserName(String) | 0 | 1 | 1 | 1 |
| eighthpta.Account.update(double) | 0 | 1 | 1 | 1 |
| eighthpta.Main.Main() | 0 | 1 | 1 | 1 |
| eighthpta.Main.atmvalidata(String) | 1 | 1 | 2 | 2 |
| eighthpta.Main.format() | 65 | 4 | 16 | 19 |
| eighthpta.Main.idvalidate(String) | 5 | 3 | 3 | 4 |
| eighthpta.Main.input() | 1 | 1 | 2 | 2 |
| eighthpta.Main.main(String[]) | 0 | 1 | 1 | 1 |
| eighthpta.Main.passvalidate(String) | 1 | 1 | 2 | 2 |
| eighthpta.Main.update(int,double,String) | 3 | 1 | 3 | 3 |
| Class | OCavg | OCmax | WMC | |
| eighthpta.ATM | 1.4 | 3 | 7 | |
| eighthpta.Account | 1.08 | 2 | 13 | |
| eighthpta.Main | 4.38 | 20 | 35 |
题目集9复杂度分析:
| Method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| ninthpta.ATM.ATM(String) | 0 | 1 | 1 | 1 |
| ninthpta.Account.Account(String,boolean) | 12 | 1 | 13 | 13 |
| ninthpta.Account.getmoney() | 0 | 1 | 1 | 1 |
| ninthpta.Account.takemoney(double) | 9 | 1 | 2 | 7 |
| ninthpta.Account.takemoney(double,double) | 9 | 1 | 2 | 7 |
| ninthpta.Bank.Bank(String) | 3 | 1 | 4 | 4 |
| ninthpta.Card.Card(String) | 0 | 1 | 1 | 1 |
| ninthpta.Main.Main() | 0 | 1 | 1 | 1 |
| ninthpta.Main.atmvalidata(String) | 1 | 1 | 2 | 2 |
| ninthpta.Main.findatm(String) | 6 | 4 | 3 | 4 |
| ninthpta.Main.findid(String) | 15 | 6 | 5 | 6 |
| ninthpta.Main.format() | 23 | 1 | 7 | 9 |
| ninthpta.Main.input() | 1 | 1 | 2 | 2 |
| ninthpta.Main.main(String[]) | 0 | 1 | 1 | 1 |
| ninthpta.Main.passvalidate(String) | 1 | 1 | 2 | 2 |
| ninthpta.User.User(String) | 8 | 1 | 9 | 9 |
| Class | OCavg | OCmax | WMC | |
| ninthpta.ATM | 1 | 1 | 1 | |
| ninthpta.Account | 5.5 | 13 | 22 | |
| ninthpta.Bank | 4 | 4 | 4 | |
| ninthpta.Card | 1 | 1 | 1 | |
| ninthpta.Main | 3.5 | 10 | 28 | |
| ninthpta.User | 9 | 9 | 9 |
UML类图:
题目集8类图:

题目集9类图:

设计思路分析总结:
这俩个题目都是设计ATM仿真系统,题目集8相较于题目集9不仅可以取钱还可以存钱,而题目集9相较于题目8支持跨行取钱并且贷款:
先看类图:
显而易见,题目集8的类图设计的有点糟糕,感觉这也是我踩的比较大的一个坑后面我再分析,题目集8的类图包含的类相对单薄,抛去MAIN类,只有Accout和ATM类,虽然逻辑也清晰,但是从大的方向看并不满足单一职责,但是符合开闭原则,再看题目集9,题目集9是我根据题目集8踩坑后设计的类图,个人觉得合理了很多,看起来也相对舒服,也应该符合单一职责,银行聚合ATM和用户,用户拥有账户,账户可以开卡,MAIN类完成运行,整个类图看起来也丰富了很多,不会显得单薄,存储类这俩题用的还是ArrayList类,用于存储信息。
再看复杂度分析:
题目集8由于类图设计的相对简单,导致MAIN类的圈复杂度比题目集9的还高,这是因为太多的方法实现在MAIN类所导致的复杂度增高,而题目就分散了职责实现,在实现更多功能的情况下反而复杂度比题目8的复杂度更低,可见一个好的类图设计对于整个代码的实现尤为重要,题目集8的format()方法复杂度过高,同样是处理数据,题目集9的format()方法圈复杂度却只有23(相较于题目集8 的65)。
设计思路总结:
首先谈我最初设计题目集8的设计思路,我当时想的是同一个银行的ATM机应该存储他所在银行的用户信息,于是我就用ATM去聚合Account,而账户有多张卡,所以让账户去聚合卡,然后在Account类里实现存钱取钱查询余额;
再看我题目集9 的设计思路,由于我在题目集8根据同一账户不同卡的数据还需要额外更新这一个bug,我在设计题目集9 的时候就充分考虑这个问题,首先是把职责细分,不再是只有2个类,更多的把银行也划分为类,然后银行里面存放透支手续费率,跨行取款费率,银行聚合ATM和用户,用户可以开账户,账户可以开卡,账户里面存放金额,账户用来取钱查询余额,取钱重写俩次,一个是透支消费取钱,一个正常取钱;
存储类这俩题使用的都是ArrayList类,便于随时扩充代码内容,提高代码的简洁性,提高代码的复用性;
俩题的MAIN类功能差不多,都是要对数据进行处理和检验正确性,处理数据用到了正则表达式去判断ATM机号是否正确,判断卡号是否存在使用到findid()方法去找卡号,密码检验则是简单的字符串判断是否相等,然后是根据输入的数据,先逐行截取(split),再根据空格截取每一行每一段字,对其进行判断操作,并输出相应的内容,出现不合法问题停止当前程序输出Wrong Format。
做完这俩题,我感觉得到的收获就是设计代码结构时应该考虑清楚,不要写完才发现自己什么什么地方没有考虑到,首先就是要把职责细分,细分到每一个实体,然后就是考虑开闭原则,保持类的封装性,然后就是根据题目需求把每一个职责细分到自己设计的每一个类,如果需要添加类,就添加不要犹豫,可以自己再脑子里试运行一下整个结构看一下自己是否还有其他纰漏。总之仿真类题目设计时应该做到设计需求大于实际需求,以防出现不可预知的BUG。
三. 踩坑心得
-
第一个踩坑的就是日常格式问题,7-1关键是我找这个坑还找了很久很久,明明知道是格式问题,但是用测试数据测试却又都能过去,就让人挺奇怪的,后面跟室友通过的对比格式才发下,当输入0时,什么也不要做处理,它原来是输出什么,就让它输出什么,把之前多余的代码删除,重新测试,发现问题就是在这里。可见在debug的时候要灵活变通,不能死在一处地方。

-
踩的第二个坑是做题目集8 的判断银行卡是否存在时碰上的,由于我之前没有考虑怎么判断银行卡是否存在,就没有设置相应内容,后面发现有个检测就是要测试银行卡是否存在,而我此时代码结构并不能去灵活更改,所以我这个时候只能亡羊补牢:

增加一个银行卡数组,用于与输入的数据进行比对,进行比对也需要一个方法:

这个坑踩下来感觉就是自己的粗心大意问题, 导致自己要重新回去修改代码改进代码的鲁棒性。
-
第三个坑也是出现在做题目集8上,这是属于比较大的一个坑了,出现在设计问题上,还是通过测试数据才发现不对劲的,简单描述一下就是每一张银行卡初始化都是10000,但是同一账户的俩张卡并不相关联,这就会导致我取了一个账户的钱,用另一个卡号取查询余额,该账户的钱还是跟原来一样,

争对这个问题,我解决的方法就是在main类里添加一个更新数据的方法,将同一账户的卡号更新为同一内容:

心得感觉就是自己设计类图的时候要充分考虑单一职责原则,不要在测试环节才发现不可避免的错误。
-
最后一个坑是算法问题,出现在题目集9的跨行透支取款:

起初我一直以为是自己的初始化问题,对着自己初始化的地方检查了好久都没有发现问题,后面通过跟室友测试数据发现有一个测试数据跟他们不一样,测试点的描述也很坑,把我带偏了防线,测试点说是透支取款,并没有提到跨行,我就一直在非跨行透支取款里面找问题,后来结果才发现问题是在跨行透支取款里:

多算了一个手续费,经过修正后,问题得以解决。这个坑踩下来感觉就是自己还不够细心,需要再细心一点。
四. 改进建议
- 针对继承与多态这方面的使用,我觉得自己还需要多去看一些相关书籍,让自己更好的去使用,提高代码的复用性,在设计类方面,感觉自己需要提高一下自己的逻辑思维能力,思考需要缜密一点,不要停留在表面,多考虑吧指责单一原则,开闭原则。
- 在日后的日常解决题目需求的地方,我觉得可以多去使用接口,提高代码的简洁度,利用好JAVA语言的特性,而不是一成不变按照以前的编程思想去复杂地完成自己想要的效果。
五. 总结
- 这三次题目集让我对JAVA的继承、多态、抽象类以及接口有了更深的认识。通过使用继承,能够很好实现代码的重用、改进软件系统的可维护性,并且继承使得已有程序库具有清晰的层次结构关系;对于多态,我们可以理解为不同对象接受到相同的消息产生不同的动作通过使用多态,可以很好的降低程序设计时的复杂性、并且支持程序开发人员的知识重用以及增强了软件灵活性;通过使用抽象类可以实现公共特性的提取,使具体类可以从抽象类自动得到缺省实现,复用性强,并且简化了自己的代码;一个类可以实现多个接口,通过使用接口可以使这个类不仅具有主类型的行为,而且具有其他的次要行为,这样就可以完成自己其他想要的扩展需求。
- 我需要学习的点还有很多,首先就是需要提高一下自己的代码结构设计能力,不要自己给自己埋坑,然后就是需要多去了解一下JAVA的接口,哪些接口可以让我们在日常使用中更为方便简便。
- 我觉得这三次题目集重在指导意义,通过前一次和后一次的对比,可以让自己很清晰的知道自己的不足,也让自己对犯错的印象更为深刻,对于继承、多态、抽象类、接口以及代码结构设计,自己都还需要进一步去了解他们更深的概念,从根本上去掌握他们。总之,继续努力,加油!

浙公网安备 33010602011771号