JAVA后三次PTA作业总结
一、前言
第三阶段的PTA大作业作业相比之前,更加贴合面向对象,实现少部分代码通过增、删、改、查而大体代码结构、框架甚至内容都不改变,却能完成用户所需的功能(前提是你一开始框架要搭建的足够好)。同时,本次题目的关联性较高,都是同一种逻辑走向,并在一定基础上实现更多的功能,尽管题目并不难但是各种设计以及一些小细节的处理还是相对来说比较耗时的。
二、作业概况
第七次作业
第七次作业的题目分别是:
-
- 7-1 卡片排序游戏
- 7-2 卡片分组游戏
运用知识点:
-
- ArrayList数组的运用
- Comparable 接口compareTo方法
- toString()方法使用
- 类的继承与封装
- 构造父类和子类,并使用this及super等关键字
题目难度:
第七次作业总共分为两道题题,和前面的几次作业对比,这三次的作业都是紧贴面向对象进行设计的。题目集七中第一题 图形卡片排序游戏 根据接口Comparable,同时将数据存入ArrayList中,最后将面积从大到小进行排序并在此基础上改变list中的对应图形的对应面积顺序。总的来说,本题类中方法的搭建,以及关于list内部图形和面积的排序是本题的难点所在,解决完这两个问题,其他问题也就迎刃而解了。
第二题图形卡片分组游戏在上一题的基础上加入了新的ArrayList。这里将不同的图形分类放入同一个组,同时在该组中进行从大到小的分类。即思路为:参数全部放入Shape的动态数组中,在根据图形进行分组存入新的动态数组中对应图形的动态数组中。大致思路构建完问题便解决了。但是在7-1的基础上修改的话容易造成代码长度超长注意减少代码量。
第八次作业
第八次作业的题目分别是:
-
- 7-3 ATM机类结构设计(一)
运用知识点:
-
- ArrayList数组使用
- 类的结构设计与嵌套
- split()方法的使用
- equals()的运用
题目难度:
本题ATM机类结构设计(一)多处运用ArrayList将所需数据按类分别存储在List中,同时十分贴合面向对象,结合了实际生活中的应用。第一次接触时,面对给出的功能在没有类图的情况下需要学生自己构建所需类图以用于代码的框架书写,难度略大,进行了多次设计和改写,同时,这是第一次接触多个不同的类相互关联,关系错综复杂,调用数据时需要明确自己将它存在了哪里。
第九次作业
第九次作业的题目分别是:
-
- 7-1 ATM机类结构设计(二)
运用知识点:
-
- ArrayList数组使用
- 类的结构设计与嵌套
- split()方法的使用
- equals()的运用
题目难度:
此题ATM机类结构设计(二)还是和上一题大体一致,只是增加了跨行和透支的余额的功能。同时,本次题目思路不变,但代码书写换了一种写法,大体不影响。此代码将所有数据封装,调用数据时会更加方便。同时在处理输入数据时,采用了split()方法和简单的正则进行数据的切割和处理。但是需要注意的是,此题和上一题的结构设计相关,上一题的类和方法结构等的设计不够好的情况下,修改起来十分麻烦。
三、作业分析(包括设计分析,踩坑心得和改进建议)
题目集7(7-1)、(7-2)两道题目的递进式设计分析总结
第七次题目集:7-1:卡片排序游戏
1、 设计与分析
(1)设计:
源代码
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Comparator;
/* e1.compareTo(e2)
- 返回 负整数 即 e1.compareTo(e2) < 0 表示e1 < e2
- 返回 正整数 即 e1.compareTo(e2) > 0 表示e1 > e2
- 返回 0 即 e1.compareTo(e2) == 0 表示e1==e2*/
import java.util.Collections;//排序
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>();//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();
input.close();
}
}
class DealCardList {//这个类是将输入的数据存入到卡片中
ArrayList<Card> cardList = new ArrayList<Card>();
public DealCardList() {
}
public DealCardList(ArrayList<Integer> list) {
for(int i=0;i<list.size();i++) {
if(i<=0&&i>4){
System.out.println("Wrong Format");
System.exit(0);
}
switch(list.get(i)) {
case 1:{
Card card=new Card(new Circle(Main.input.nextDouble()));
card.getShape().setShapeName("Circle:");
cardList.add(card);
break;
}
case 2:{
Card card=new Card(new Rectangle(Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Rectangle:");
cardList.add(card);
break;
}
case 3:{
Card card=new Card(new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Triangle:");
cardList.add(card);
break;
}
case 4:{
Card card=new Card(new Trapezoid(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Trapezoid:");
cardList.add(card);
break;
}
}
}
}
public boolean validate() {//判断正确性
boolean validate = true;
for (int i = 0; i < cardList.size(); i++) {
if (cardList.get(i).getShape().validate() == false) {
validate = false;
break;
}
}
return validate;
}
public void cardSort() {
int i, j;
Card temp;
for (i = 1;i < cardList.size();i++){
temp = cardList.get(i);
for (j = i - 1; j >= 0 && cardList.get(j).compareTo(temp) >0; j--){
cardList.set(j + 1, cardList.get(j));
}
cardList.set(j + 1, temp);
}
System.out.printf("\nThe sorted list:\n");
for(int m = 0; m < cardList.size(); m++) {
System.out.print(cardList.get(m).getShape().toString()+ " ");
}
}
public double getAllArea() {//算总面积
double all = 0;
for(int i = 0; i < cardList.size(); i++) {
all += cardList.get(i).getShape().getArea();
}
return all;
}
public void showResult() {//展示结果
System.out.println("The original list:");
for(int i = 0; i < cardList.size(); i++) {
System.out.print(cardList.get(i).getShape().toString()+ " ");
}
cardSort();
System.out.printf("\nSum of area:%.2f",getAllArea());
}
}
interface Comparable {
public int compareTo(Card card);
}
class Card implements Comparable {
private Shape shape;
public Card () {
}
public Card (Shape shape) {
this.shape = shape;
}
public Shape getShape() {
return shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
@Override
public int compareTo (Card card) {
if(this.shape.getArea() < card.getShape().getArea()) {
return 1;
}else if(this.shape.getArea() > card.getShape().getArea()){
return -1;
}else {
return 0;
}
}
}
abstract class Shape{
private String shapeName;
public Shape() {
}
public Shape(String shapeName) {
this.shapeName = shapeName;
}
public String getShapeName() {
return shapeName;
}
public void setShapeName(String shapeName) {
this.shapeName = shapeName;
}
public abstract double getArea() ;
public abstract boolean validate() ;
public abstract String toString() ;
}
class Circle extends Shape{//圆
private double radius;
public Circle() {
super();
}
public Circle(double radius) {
super();
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getArea() {
return radius*radius*Math.PI ;
}
@Override
public boolean validate() {
boolean validate = false;
if (radius > 0) {
validate = true;
getArea();
} else {
validate = false;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
class Rectangle extends Shape {//矩形
private double width;
private double length;
public Rectangle() {
super();
}
public Rectangle(double width, double length) {
super();
this.width = width;
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getArea() {
return length * width;
}
@Override
public boolean validate() {
boolean validate = false;
if (length >= 0 && width >= 0) {
validate = true;
getArea();
} else {
validate = false;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
class Triangle extends Shape {//三角形
private double side1;
private double side2;
private double side3;
public Triangle() {
super();
}
public Triangle(double side1, double side2, double side3) {
super();
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
public double getSide1() {
return side1;
}
public void setSide1(double side1) {
this.side1 = side1;
}
public double getSide2() {
return side2;
}
public void setSide2(double side2) {
this.side2 = side2;
}
public double getSide3() {
return side3;
}
public void setSide3(double side3) {
this.side3 = side3;
}
public double getArea() {
double num = (side1 + side2 + side3) / 2;
return Math.sqrt(num * (num - side1) * (num - side2) * (num - side3));
}
@Override
public boolean validate() {
boolean validate = false;
if (side1 < 0 || side2 < 0 || side3 < 0 || (side1 + side2 <= side3) || (side2 + side3 <= side1) || (side1 + side3 <= side2))
validate = false;
else {
getArea();
validate = true;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
class Trapezoid extends Shape {//梯形
private double topSide;
private double bottomSide;
private double height;
public Trapezoid() {
super();
// TODO Auto-generated constructor stub
}
public Trapezoid(double topSide, double bottomSide, double height) {
super();
this.topSide = topSide;
this.bottomSide = bottomSide;
this.height = height;
}
public double getTopSide() {
return topSide;
}
public void setTopSide(double topSide) {
this.topSide = topSide;
}
public double getBottomSide() {
return bottomSide;
}
public void setBottomSide(double bottomSide) {
this.bottomSide = bottomSide;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getArea() {
return (topSide+bottomSide)*height/2;
}
@Override
public boolean validate() {
boolean validate=true;
if(topSide>0&&bottomSide>0&&height>0) {
validate=true;
getArea();
}
else{
validate=false;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
输入格式:
- 首先,在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0 - 然后根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边不能组成三角形),则输出
Wrong Format。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格; - 排序后的各图形类型及面积,格式同排序前的输出;
- 所有图形的面积总和,格式为
Sum of area:总面积值。
主类中用于处理选择图形样式的数据,后根据类图构建好大体框架后开始增加方法。这里在DealCardList类中构建ArrayList<Card> cardList = new ArrayList<Card>();键盘输入数字进行图形的选择以及输入图形的参数,将其存入动态数组用于后续的排序以及输出。
class DealCardList {//这个类是将输入的数据存入到卡片中
ArrayList<Card> cardList = new ArrayList<Card>();
public DealCardList() {
}
public DealCardList(ArrayList<Integer> list) {
for(int i=0;i<list.size();i++) {
if(i<=0&&i>4){
System.out.println("Wrong Format");
System.exit(0);
}
switch(list.get(i)) {
case 1:{
Card card=new Card(new Circle(Main.input.nextDouble()));
card.getShape().setShapeName("Circle:");
cardList.add(card);
break;
}
case 2:{
Card card=new Card(new Rectangle(Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Rectangle:");
cardList.add(card);
break;
}
case 3:{
Card card=new Card(new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Triangle:");
cardList.add(card);
break;
}
case 4:{
Card card=new Card(new Trapezoid(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Trapezoid:");
cardList.add(card);
break;
}
}
}
}
这里对接口的compareTo方法进行了复写,用于面积排序。
public int compareTo (Card card) {
if(this.shape.getArea() < card.getShape().getArea()) {
return 1;
}else if(this.shape.getArea() > card.getShape().getArea()){
return -1;
}else {
return 0;
}
}
抽象父类Shape加入抽象方法便于之后的类对其进行调用。
abstract class Shape{
private String shapeName;
public Shape() {
}
public Shape(String shapeName) {
this.shapeName = shapeName;
}
public String getShapeName() {
return shapeName;
}
public void setShapeName(String shapeName) {
this.shapeName = shapeName;
}
public abstract double getArea() ;
public abstract boolean validate() ;
public abstract String toString() ;
}
此处的由于是用动态数组来存储计算的各图形面积的,除了单纯排序,还得注意调整面积对应的图形顺序是否一致。如果列表中的前一个小于后一个,则这里将cardList.get(i+1)放入List中i对应的位置,cardList.get(i)放在i+1对应的位置上,实现顺序的调换。
public void cardSort() {
int i, j;
Card temp;
for (i = 1;i < cardList.size();i++){
temp = cardList.get(i);
for (j = i - 1; j >= 0 && cardList.get(j).compareTo(temp) >0; j--){
cardList.set(j + 1, cardList.get(j));
}
cardList.set(j + 1, temp);
}
System.out.printf("\nThe sorted list:\n");
for(int m = 0; m < cardList.size(); m++) {
System.out.print(cardList.get(m).getShape().toString()+ " ");
}
}
public double getAllArea() {//算总面积
double all = 0;
for(int i = 0; i < cardList.size(); i++) {
all += cardList.get(i).getShape().getArea();
}
return all;
}
(2)分析:
PowerDesigner的类图显示

SourceMonitor 复杂度分析


2、踩坑心得:(1)计算凡是有涉及圆周率的均用Math.PI才可过测试点而不能用3.14进行计算。
(2)在题目集7的题目中,对于接口Comparable<>,在编写代码的过程中尚不熟悉继承该接口后所能提供的方法。因此,在完成了重写该接口所需的compareTo()方法后,却不知道应该使用哪个排序函数。
(3)这里在传入不同图形的各个参数时,代码的书写修改了很多次,但最后还是先将个参数放入图形类中new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble())
3、改进建议:虽然排序交换过程思路较为清晰,但实现较为复杂,借用List中的Collections.swap方法会使代码更加简洁。
第七次题目集:7-2:卡片分组游戏
1、 设计与分析
(1)设计:
源代码
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Comparator;
/* e1.compareTo(e2)
- 返回 负整数 即 e1.compareTo(e2) < 0 表示e1 < e2
- 返回 正整数 即 e1.compareTo(e2) > 0 表示e1 > e2
- 返回 0 即 e1.compareTo(e2) == 0 表示e1==e2*/
import java.util.Collections;//排序
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>();//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();
input.close();
}
}
class DealCardList {//这个类是将输入的数据存入到卡片中
ArrayList<Card> cardList = new ArrayList<Card>();
public DealCardList() {
}
public DealCardList(ArrayList<Integer> list) {
for(int i=0;i<list.size();i++) {
if(i<=0&&i>4){
System.out.println("Wrong Format");
System.exit(0);
}
switch(list.get(i)) {
case 1:{
Card card=new Card(new Circle(Main.input.nextDouble()));
card.getShape().setShapeName("Circle:");
cardList.add(card);
break;
}
case 2:{
Card card=new Card(new Rectangle(Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Rectangle:");
cardList.add(card);
break;
}
case 3:{
Card card=new Card(new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Triangle:");
cardList.add(card);
break;
}
case 4:{
Card card=new Card(new Trapezoid(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Trapezoid:");
cardList.add(card);
break;
}
}
}
}
public boolean validate() {//判断正确性
boolean validate = true;
for (int i = 0; i < cardList.size(); i++) {
if (cardList.get(i).getShape().validate() == false) {
validate = false;
break;
}
}
return validate;
}
public void cardSort() {
int i, j;
Card temp;
for (i = 1;i < cardList.size();i++){
temp = cardList.get(i);
for (j = i - 1; j >= 0 && cardList.get(j).compareTo(temp) >0; j--){
cardList.set(j + 1, cardList.get(j));
}
cardList.set(j + 1, temp);
}
System.out.printf("\nThe sorted list:\n");
for(int m = 0; m < cardList.size(); m++) {
System.out.print(cardList.get(m).getShape().toString()+ " ");
}
}
public double getAllArea() {//算总面积
double all = 0;
for(int i = 0; i < cardList.size(); i++) {
all += cardList.get(i).getShape().getArea();
}
return all;
}
public void showResult() {//展示结果
System.out.println("The original list:");
for(int i = 0; i < cardList.size(); i++) {
System.out.print(cardList.get(i).getShape().toString()+ " ");
}
cardSort();
System.out.printf("\nSum of area:%.2f",getAllArea());
}
}
interface Comparable {
public int compareTo(Card card);
}
class Card implements Comparable {
private Shape shape;
public Card () {
}
public Card (Shape shape) {
this.shape = shape;
}
public Shape getShape() {
return shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
@Override
public int compareTo (Card card) {
if(this.shape.getArea() < card.getShape().getArea()) {
return 1;
}else if(this.shape.getArea() > card.getShape().getArea()){
return -1;
}else {
return 0;
}
}
}
abstract class Shape{
private String shapeName;
public Shape() {
}
public Shape(String shapeName) {
this.shapeName = shapeName;
}
public String getShapeName() {
return shapeName;
}
public void setShapeName(String shapeName) {
this.shapeName = shapeName;
}
public abstract double getArea() ;
public abstract boolean validate() ;
public abstract String toString() ;
}
class Circle extends Shape{//圆
private double radius;
public Circle() {
super();
}
public Circle(double radius) {
super();
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getArea() {
return radius*radius*Math.PI ;
}
@Override
public boolean validate() {
boolean validate = false;
if (radius > 0) {
validate = true;
getArea();
} else {
validate = false;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
class Rectangle extends Shape {//矩形
private double width;
private double length;
public Rectangle() {
super();
}
public Rectangle(double width, double length) {
super();
this.width = width;
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getArea() {
return length * width;
}
@Override
public boolean validate() {
boolean validate = false;
if (length >= 0 && width >= 0) {
validate = true;
getArea();
} else {
validate = false;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
class Triangle extends Shape {//三角形
private double side1;
private double side2;
private double side3;
public Triangle() {
super();
}
public Triangle(double side1, double side2, double side3) {
super();
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
public double getSide1() {
return side1;
}
public void setSide1(double side1) {
this.side1 = side1;
}
public double getSide2() {
return side2;
}
public void setSide2(double side2) {
this.side2 = side2;
}
public double getSide3() {
return side3;
}
public void setSide3(double side3) {
this.side3 = side3;
}
public double getArea() {
double num = (side1 + side2 + side3) / 2;
return Math.sqrt(num * (num - side1) * (num - side2) * (num - side3));
}
@Override
public boolean validate() {
boolean validate = false;
if (side1 < 0 || side2 < 0 || side3 < 0 || (side1 + side2 <= side3) || (side2 + side3 <= side1) || (side1 + side3 <= side2))
validate = false;
else {
getArea();
validate = true;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
class Trapezoid extends Shape {//梯形
private double topSide;
private double bottomSide;
private double height;
public Trapezoid() {
super();
// TODO Auto-generated constructor stub
}
public Trapezoid(double topSide, double bottomSide, double height) {
super();
this.topSide = topSide;
this.bottomSide = bottomSide;
this.height = height;
}
public double getTopSide() {
return topSide;
}
public void setTopSide(double topSide) {
this.topSide = topSide;
}
public double getBottomSide() {
return bottomSide;
}
public void setBottomSide(double bottomSide) {
this.bottomSide = bottomSide;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getArea() {
return (topSide+bottomSide)*height/2;
}
@Override
public boolean validate() {
boolean validate=true;
if(topSide>0&&bottomSide>0&&height>0) {
validate=true;
getArea();
}
else{
validate=false;
}
return validate;
}
@Override
public String toString() {
return String.format(getShapeName()+"%.2f",this.getArea());
}
}
输入格式:
- 在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0 - 根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出
Wrong Format。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ],注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前; - 输出分组后的图形类型及面积,格式为
[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积],各组内格式为图形名称:面积值。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出; - 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
- 各组中面积之和的最大值输出,格式为
The max area:面积值。
我实现在DealCardList类中建立了五个ArrayList动态数组来存储输入的图形及其各个参数。
ArrayList<Card> cardList = new ArrayList<Card>(); ArrayList<Card> circleList = new ArrayList<Card>(); ArrayList<Card> rectangleList = new ArrayList<Card>(); ArrayList<Card> triangleList = new ArrayList<Card>(); ArrayList<Card> trapezoidList = new ArrayList<Card>();
再通过键盘的输入将数据进行导入。
public DealCardList(ArrayList<Integer> list) {
for(int i=0;i<list.size();i++) {
if(list.get(i)<=0&&i>4){
System.out.println("Wrong Format");
System.exit(0);
}
switch(list.get(i)) {
case 1:{
Card card=new Card(new Circle(Main.input.nextDouble()));
card.getShape().setShapeName("Circle:");
circleList.add(card);
cardList.add(card);
break;
}
case 2:{
Card card=new Card(new Rectangle(Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Rectangle:");
rectangleList.add(card);
cardList.add(card);
break;
}
case 3:{
Card card=new Card(new Triangle(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Triangle:");
triangleList.add(card);
cardList.add(card);
break;
}
case 4:{
Card card=new Card(new Trapezoid(Main.input.nextDouble(),Main.input.nextDouble(),Main.input.nextDouble()));
card.getShape().setShapeName("Trapezoid:");
trapezoidList.add(card);
cardList.add(card);
break;
}
}
}
}
利用复写的compareTo接口方法进行排序。
int i, j;
Card temp;
for (i = 1;i < cardList.size();i++){
temp = cardList.get(i);
for (j = i - 1; j >= 0 && cardList.get(j).compareTo(temp) >0; j--){
cardList.set(j + 1, cardList.get(j));
}
cardList.set(j + 1, temp);
}
通过将各个图形的总面积和放入一个数组,然后找出其中的最大值。
public double getmaxArea() {
double sum[] = {getAllArea(circleList),getAllArea(rectangleList),getAllArea(triangleList),getAllArea(trapezoidList)};
Arrays.sort(sum);
return sum[sum.length - 1];
}
其他部分思想与上一题基本相同因此便不再赘述。
(2)分析:

SourceMonitor 复杂度分析


2、踩坑心得:(1)一开始有些不知所措,不知道改怎么表示,后来思考了一下可以用四个数组分别存储不同的图形然后对其锦绣输出,问题便迎刃而解。
(2)题目的输出运算是真的繁琐,处理了许久。
3、改进建议:排序和输出方面还可以再进行优化。
总而言之,相对题目一而言,在题目二中,我通过创建其各个子类的列表,将其率先向下转型分好类别,然后再对各个列表操作。
在很好利用多态批量化规范化操作的前提下又能非常合适的完成目标并极大的减少了工作量。此题也使我对动态数组ArrayList的使用和了解大大提高。
题目集8(7-3)、题目集9(7-1)两种ATM机类结构设计
第八次题目集:7-3 ATM机类结构设计(一)
1、 设计与分析
(1)设计:
源代码
import java.util.*; public class Main { static Bankunion union = new Bankunion(); public static void main(String[] args) { Data data = new Data(); data.play(); } } class Data { static Bankunion union = new Bankunion(); Data() { Account account1 = new Account("杨过", "3217000010041315709", 10000.00); Account account2 = new Account("杨过", "3217000010041315715", 10000.00); Account account3 = new Account("郭靖", "3217000010051320007", 10000.00); Account account4 = new Account("张无忌", "3222081502001312389", 10000.00); Account account5 = new Account("张无忌", "3222081502001312390", 10000.00); Account account6 = new Account("张无忌", "3222081502001312399", 10000.00); Account account7 = new Account("韦小宝", "3222081502051320785", 10000.00); Account account8 = new Account("韦小宝", "3222081502051320786", 10000.00); account1.getCard().add(new Card("6217000010041315709", "88888888")); account1.getCard().add(new Card("6217000010041315715", "88888888")); account2.getCard().add(new Card("6217000010041315718", "88888888")); account3.getCard().add(new Card("6217000010051320007", "88888888")); account4.getCard().add(new Card("6222081502001312389", "88888888")); account5.getCard().add(new Card("6222081502001312390", "88888888")); account6.getCard().add(new Card("6222081502001312399", "88888888")); account6.getCard().add(new Card("6222081502001312400", "88888888")); account7.getCard().add(new Card("6222081502051320785", "88888888")); account8.getCard().add(new Card("6222081502051320786", "88888888")); Bank bank1 = new Bank("中国建设银行"); bank1.getAccount().add(account1); bank1.getAccount().add(account2); bank1.getAccount().add(account3); union.addBank(bank1); Bank bank2 = new Bank("中国工商银行"); bank2.getAccount().add(account4); bank2.getAccount().add(account5); bank2.getAccount().add(account6); bank2.getAccount().add(account7); bank2.getAccount().add(account8); union.addBank(bank2); for (int i = 1; i <= 6; i++) { if (i <= 4) { bank1.addATM(new ATM("0" + i)); } else { bank2.addATM(new ATM("0" + i)); } } union.addBank(bank1); union.addBank(bank2); } public void play(){ Scanner input = new Scanner(System.in); String str=input.nextLine(); while(!str.equals("#")) { String[] s = str.split("\\s+"); if (s.length == 1) { //当前余额 double balance = 0; for (int i = 0; i < union.getList().size(); i++) { for (int j = 0; j < union.getList().get(i).getAccount().size(); j++) { for (int k = 0; k < union.getList().get(i).getAccount().get(j).getCard().size(); k++) { if (union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(str)) { balance = union.getList().get(i).getAccount().get(j).getBalance(); } } } } System.out.printf("¥%.2f", balance); System.out.print("\n"); } else { //存取款 double money = 0; double nowbalance = 0; String username = null; String bankname = null; //每分割一行处理一行 vaildCard(s[0]); vaildCardCode(s[1]); vaildATM(s[2]); getmoney(Double.valueOf(s[3]));//String转化成double money = Double.valueOf(s[3]); Bank bank = null; for (int i = 0; i < union.getList().size(); i++) { for (int j = 0; j < union.getList().get(i).getAccount().size(); j++) { for (int k = 0; k < union.getList().get(i).getAccount().get(j).getCard().size(); k++) { if (union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(s[0])) { nowbalance = union.getList().get(i).getAccount().get(j).getBalance(); username = union.getList().get(i).getAccount().get(j).getname(); bankname = union.getList().get(i).getBankName(); bank = union.getList().get(i); } } } } if (!vaild(s[0], s[1], s[2], Double.valueOf(s[3]), nowbalance, bank)) { System.exit(0); } else{ business(Double.parseDouble(s[3]), nowbalance, s[0]); System.out.print(username + "在" + bankname + "的" + s[2] + "号ATM机"); if (getmoney(money)) {//存钱 System.out.printf("上存款¥%.2f\n", money * (-1)); System.out.printf("当前余额为¥%.2f\n", (nowbalance + money * (-1))); } else { System.out.printf("上取款¥%.2f\n", money); System.out.printf("当前余额为¥%.2f\n", (nowbalance - money)); } } } str=input.nextLine(); } } public void business(double money,double nowbalance,String cardnumber){//存取款 for(int i = 0;i < union.getList().size();i++) { for(int j = 0;j< union.getList().get(i).getAccount().size();j++) { for(int k = 0;k < union.getList().get(i).getAccount().get(j).getCard().size();k++) { if(union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(cardnumber)) { union.getList().get(i).getAccount().get(j).setBalance(nowbalance+money*(-1)); } } } } } public static boolean vaild(String cardnumber, String cardcode, String atmid, double money, double nowbalance, Bank bank){ if(vaildCard(cardnumber)==false) { System.out.println("Sorry,this card does not exist."); return false; } if(vaildCardCode(cardcode)==false) { System.out.println("Sorry,your password is wrong."); return false; } if(vaildATM(atmid)==false) { System.out.println("Sorry,the ATM's id is wrong."); return false; } if(getmoney(money)==false) { if(nowbalance<money) { System.out.println("Sorry,your account balance is insufficient."); return false; } } if(permission(atmid,bank)==true) { System.out.println("Sorry,cross-bank withdrawal is not supported."); return false; } return true; } public static boolean permission(String atmid, Bank bank) {//判断是否跨银行取款 for(int i = 0;i < bank.getAtms().size();i++) { if(atmid.equals(bank.getAtms().get(i).getAtm())) { return false; } } return true; } public static boolean vaildCard(String cardnumber) {//判断卡号正确 for(int a = 0;a < union.getList().size();a++) { for(int b = 0;b < union.getList().get(a).getAccount().size();b++) { for(int c = 0;c < union.getList().get(a).getAccount().get(b).getCard().size();c++) { if(cardnumber.equals(union.getList().get(a).getAccount().get(b).getCard().get(c).getCardNumber())) { return true; } } } } return false; } public static boolean vaildCardCode(String cardcode) {//判断密码是否正确 if(cardcode.equals("88888888")) { return true; } return false; } public static boolean vaildATM(String atmid){//判断ATM机编号是否正确 for(int a=0;a<union.getList().size();a++) { for(int b=0;b<union.getList().get(a).getAtms().size();b++) { if(atmid.equals(union.getList().get(a).getAtms().get(b).getAtm())) { return true; } } } return false; } public static boolean getmoney(double money) {//判断存取款 if(money>0){ return false;//取款 }else{ return true;//存款 } } } /*class check{//输入校验 } class business{//存取款 } class Inquire{//查余额 } */ class Bankunion{//存ATM private ArrayList<Bank> list = new ArrayList<Bank>(); public Bankunion() { } public ArrayList<Bank> getList() { return list; } public void setList(ArrayList<Bank> list) { this.list = list; } public void addBank(Bank bank) { list.add(bank); } } class ATM{ private String atm; public ATM(String atm) { this.atm = atm; } public String getAtm() { return atm; } public void setAtm(String atm) { this.atm = atm; } } class Bank{//银行存账号 private String BankName; private ArrayList<Account> account= new ArrayList<Account>(); private ArrayList<ATM> list = new ArrayList<ATM>(); public Bank(String BankName) { this.BankName = BankName; } public String getBankName() { return BankName; } public void setBankName(String BankName) { this.BankName = BankName; } public ArrayList<Account> getAccount() { return account; } public void setAccount(ArrayList<Account> account) { this.account = account; } public ArrayList<ATM> getAtms() { return list; } public void setAtms(ArrayList<ATM> atms) { this.list = atms; } public void addATM(ATM atm) { list.add(atm); } } class Account{//账户存卡号,密码,用户名字,余额,账号 private String name = null;//户主名字 private String accountNumber= null;//账户 private ArrayList<Card> card= new ArrayList<Card>(); private double balance= 10000.00;//余额 public Account(String name, String accountNumber,double balance) { this.name = name; this.accountNumber = accountNumber; this.balance = balance; } public ArrayList<Card> getCard() { return card; } public void setCard(ArrayList<Card> card) { this.card = card; } public String getname() { return name; } public void setname(String name) { this.name = name; } public String getaccountNumber() { return accountNumber; } public void setaccountNumber(String accountNumber) { this.accountNumber = accountNumber; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } } class Card{ private String CardNumber = null;//卡号 private String CardCode = "88888888";//密码 private Account account = null; public Card( String CardNumber,String CardCode) { this.CardNumber = CardNumber; this.CardCode = CardCode; } public String getCardNumber() { return CardNumber; } public void setCardNumber(String CardNumber) { this.CardNumber = CardNumber; } public String getCardCode() { return CardCode; } public void setCardCode(String CardCode) { this.CardCode = CardCode; } public Account getaccount() { return account; } public void setBankaccount(Account account) { this.account = account; } }
输入格式:
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
-
- 存款、取款功能输入数据格式:
卡号 密码 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编号]上存款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
④查询余额业务输出
¥[金额]
金额保留两位小数。
由于此次的作业没有给我题目设计的类图,让自己根据题目的需求来设计,因此一开始我想的过于简单,直接把全部的数据都存在一起放在一个ArrayList数组中,但是后来发现存在一起体现不出多态的思想并且功能代码书写起来相对来说也复杂了许多,后来经过了多次思考并且根据题目给的要求重写对整体的结构进行了设计。

在银联类Bankunion类存储银行类Bank
class Bankunion{//
private ArrayList<Bank> list = new ArrayList<Bank>();
public Bankunion() {
}
public ArrayList<Bank> getList() {
return list;
}
public void setList(ArrayList<Bank> list) {
this.list = list;
}
public void addBank(Bank bank) {
list.add(bank);
}
}
在ATM类用于存储ATM机的编号。
class ATM{
private String atm;
public ATM(String atm) {
this.atm = atm;
}
public String getAtm() {
return atm;
}
public void setAtm(String atm) {
this.atm = atm;
}
}
在银行类Bank中存储银行的名字,银行账户,不同银行所拥有的ATM机编号。
class Bank{//银行存账号
private String BankName;
private ArrayList<Account> account= new ArrayList<Account>();
private ArrayList<ATM> list = new ArrayList<ATM>();
public Bank(String BankName) {
this.BankName = BankName;
}
public String getBankName() {
return BankName;
}
public void setBankName(String BankName) {
this.BankName = BankName;
}
public ArrayList<Account> getAccount() {
return account;
}
public void setAccount(ArrayList<Account> account) {
this.account = account;
}
public ArrayList<ATM> getAtms() {
return list;
}
public void setAtms(ArrayList<ATM> atms) {
this.list = atms;
}
public void addATM(ATM atm) {
list.add(atm);
}
}
账户类中存储户主姓名,账户号码,银行卡以及账户余额。
class Account{//账户存卡号,密码,用户名字,余额,账号
private String name = null;//户主名字
private String accountNumber= null;//账户
private ArrayList<Card> card= new ArrayList<Card>();
private double balance= 10000.00;//余额
public Account(String name, String accountNumber,double balance) {
this.name = name;
this.accountNumber = accountNumber;
this.balance = balance;
}
public ArrayList<Card> getCard() {
return card;
}
public void setCard(ArrayList<Card> card) {
this.card = card;
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getaccountNumber() {
return accountNumber;
}
public void setaccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
银行卡类中存储卡号和密码。
class Card{
private String CardNumber = null;//卡号
private String CardCode = "88888888";//密码
public Card( String CardNumber,String CardCode) {
this.CardNumber = CardNumber;
this.CardCode = CardCode;
}
public String getCardNumber() {
return CardNumber;
}
public void setCardNumber(String CardNumber) {
this.CardNumber = CardNumber;
}
public String getCardCode() {
return CardCode;
}
public void setCardCode(String CardCode) {
this.CardCode = CardCode;
}
}
然后就是在数据类Data中将数据存入然后不断套娃。
static Bankunion union = new Bankunion();
Data() {
Account account1 = new Account("杨过", "3217000010041315709", 10000.00);
Account account2 = new Account("杨过", "3217000010041315715", 10000.00);
Account account3 = new Account("郭靖", "3217000010051320007", 10000.00);
Account account4 = new Account("张无忌", "3222081502001312389", 10000.00);
Account account5 = new Account("张无忌", "3222081502001312390", 10000.00);
Account account6 = new Account("张无忌", "3222081502001312399", 10000.00);
Account account7 = new Account("韦小宝", "3222081502051320785", 10000.00);
Account account8 = new Account("韦小宝", "3222081502051320786", 10000.00);
account1.getCard().add(new Card("6217000010041315709", "88888888"));
account1.getCard().add(new Card("6217000010041315715", "88888888"));
account2.getCard().add(new Card("6217000010041315718", "88888888"));
account3.getCard().add(new Card("6217000010051320007", "88888888"));
account4.getCard().add(new Card("6222081502001312389", "88888888"));
account5.getCard().add(new Card("6222081502001312390", "88888888"));
account6.getCard().add(new Card("6222081502001312399", "88888888"));
account6.getCard().add(new Card("6222081502001312400", "88888888"));
account7.getCard().add(new Card("6222081502051320785", "88888888"));
account8.getCard().add(new Card("6222081502051320786", "88888888"));
Bank bank1 = new Bank("中国建设银行");
bank1.getAccount().add(account1);
bank1.getAccount().add(account2);
bank1.getAccount().add(account3);
union.addBank(bank1);
Bank bank2 = new Bank("中国工商银行");
bank2.getAccount().add(account4);
bank2.getAccount().add(account5);
bank2.getAccount().add(account6);
bank2.getAccount().add(account7);
bank2.getAccount().add(account8);
union.addBank(bank2);
for (int i = 1; i <= 6; i++) {
if (i <= 4) {
bank1.addATM(new ATM("0" + i));
} else {
bank2.addATM(new ATM("0" + i));
}
}
union.addBank(bank1);
union.addBank(bank2);
}
解决了类的设计问题,接下来的输出遇上了大麻烦,我不晓得怎么连续输入然后对不同的账户分别进行业务的操作,后来上网查询了一下,将字符串进行分割,如果分割出来的字符串长度等于1则进行查询业务否则则进行存取款业务。然后对分割出来的存取款业务的输入数据放在数组中的不同位置然后与相应的已存入数据进行对比查询操作。
while(!str.equals("#")) {
String[] s = str.split("\\s+");
if (s.length == 1) {
//当前余额
double balance = 0;
for (int i = 0; i < union.getList().size(); i++) {
for (int j = 0; j < union.getList().get(i).getAccount().size(); j++) {
for (int k = 0; k < union.getList().get(i).getAccount().get(j).getCard().size(); k++) {
if (union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(str)) {
balance = union.getList().get(i).getAccount().get(j).getBalance();
}
}
}
}
System.out.printf("¥%.2f", balance);
System.out.print("\n");
} else {
//存取款
double money = 0;
double nowbalance = 0;
String username = null;
String bankname = null;
//每分割一行处理一行
vaildCard(s[0]);
vaildCardCode(s[1]);
vaildATM(s[2]);
getmoney(Double.valueOf(s[3]));//String转化成double
money = Double.valueOf(s[3]);
Bank bank = null;
for (int i = 0; i < union.getList().size(); i++) {
for (int j = 0; j < union.getList().get(i).getAccount().size(); j++) {
for (int k = 0; k < union.getList().get(i).getAccount().get(j).getCard().size(); k++) {
if (union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(s[0])) {
nowbalance = union.getList().get(i).getAccount().get(j).getBalance();
username = union.getList().get(i).getAccount().get(j).getname();
bankname = union.getList().get(i).getBankName();
bank = union.getList().get(i);
}
}
}
}
if (!vaild(s[0], s[1], s[2], Double.valueOf(s[3]), nowbalance, bank)) {
System.exit(0);
}
else{
business(Double.parseDouble(s[3]), nowbalance, s[0]);
System.out.print(username + "在" + bankname + "的" + s[2] + "号ATM机");
if (getmoney(money)) {//存钱
System.out.printf("上存款¥%.2f\n", money * (-1));
System.out.printf("当前余额为¥%.2f\n", (nowbalance + money * (-1)));
} else {
System.out.printf("上取款¥%.2f\n", money);
System.out.printf("当前余额为¥%.2f\n", (nowbalance - money));
}
}
}
str=input.nextLine();
}
(2)分析:
根据PowerDesigner的类图显示,该题只有六个类,一个main类,shape作为circle和rectangle的父类,而circle和rectangle分别作为ball和box的父类:

SourceMonitor 复杂度分析


2、踩坑心得:(1)设计类图还是一件得严肃处理的事情,很多地方不能想的太过于简单粗暴。
(2)一开始思考怎么在一长串输入中分别对不同的输入进行不同的操作实属吃尽苦头,后来发现可以简单通过长度以及数组的存储位置进行判断问题便简单了起来。
3、改进建议:类设计的还是不够好不够完全,业务处理也可以设计出一个类来执行相应的方法,尤其是业务操作的部分,比如存取款偷了点懒,很多地方还是处理的较为简单,比如账户每次存取款的余额方面以及输出方面,于是到了接 下来的PTA作业九便开始多重折磨。
第九次题目集:7-1 ATM机类结构设计(二)
1、 设计与分析
(1)设计:
源代码
import java.util.*;
/*银行账户分为借记账户和贷记账户两种,其中,借记账户不能够透支
取款,而贷记账户可以透支取款(可能需要支付手续费)。
且允许跨行办理相关业务
*/
public class Main {
static Bankunion union = new Bankunion();
public static void main(String[] args) {
Data data = new Data();
data.play();
}
}
class Data {
static Bankunion union = new Bankunion();
Data() {
Account account1 = new Account("杨过", "3217000010041315709","借记账号" ,10000.00);
Account account2 = new Account("杨过", "3217000010041315715","借记账号" , 10000.00);
Account account3 = new Account("郭靖", "3217000010051320007", "借记账号" ,10000.00);
Account account4 = new Account("张无忌", "3222081502001312389","借记账号" , 10000.00);
Account account5 = new Account("张无忌", "3222081502001312390","借记账号" , 10000.00);
Account account6 = new Account("张无忌", "3222081502001312399", "借记账号" ,10000.00);
Account account7 = new Account("韦小宝", "3222081502051320785", "借记账号" ,10000.00);
Account account8 = new Account("韦小宝", "3222081502051320786", "借记账号" ,10000.00);
Account account9 = new Account("张三丰", "3640000010045442002", "贷记账号" ,10000.00);
Account account10 = new Account("令狐冲", "3640000010045441009","贷记账号" , 10000.00);
Account account11 = new Account("乔峰", "3630000010033431001", "贷记账号" ,10000.00);
Account account12 = new Account("洪七公", "3630000010033431008","贷记账号" , 10000.00);
account1.getCard().add(new Card("6217000010041315709", "88888888"));
account1.getCard().add(new Card("6217000010041315715", "88888888"));
account2.getCard().add(new Card("6217000010041315718", "88888888"));
account3.getCard().add(new Card("6217000010051320007", "88888888"));
account4.getCard().add(new Card("6222081502001312389", "88888888"));
account5.getCard().add(new Card("6222081502001312390", "88888888"));
account6.getCard().add(new Card("6222081502001312399", "88888888"));
account6.getCard().add(new Card("6222081502001312400", "88888888"));
account7.getCard().add(new Card("6222081502051320785", "88888888"));
account8.getCard().add(new Card("6222081502051320786", "88888888"));
account9.getCard().add(new Card("6640000010045442002", "88888888"));
account9.getCard().add(new Card("6640000010045442003", "88888888"));
account10.getCard().add(new Card("6640000010045441009", "88888888"));
account11.getCard().add(new Card("6630000010033431001", "88888888"));
account12.getCard().add(new Card("6630000010033431008", "88888888"));
Bank bank1 = new Bank("中国建设银行",0.02);
bank1.getAccount().add(account1);
bank1.getAccount().add(account2);
bank1.getAccount().add(account3);
bank1.getAccount().add(account9);
union.addBank(bank1);
Bank bank2 = new Bank("中国工商银行",0.03);
bank2.getAccount().add(account4);
bank2.getAccount().add(account5);
bank2.getAccount().add(account6);
bank2.getAccount().add(account7);
bank2.getAccount().add(account8);
bank2.getAccount().add(account10);
union.addBank(bank2);
Bank bank3 = new Bank("中国农业银行",0.04);
bank3.getAccount().add(account11);
bank3.getAccount().add(account12);
union.addBank(bank3);
for (int i = 1; i <= 11; i++) {
if (i <= 4) {
bank1.addATM(new ATM("0" + i));
}
if(i <= 6&&i>4){
bank2.addATM(new ATM("0" + i));
}
if(i <= 9&&i>6) {
bank3.addATM(new ATM("0" + i));
}
else{
bank3.addATM(new ATM("1" + (i-10)));
}
}
union.addBank(bank1);
union.addBank(bank2);
union.addBank(bank3);
}
public void play(){
Scanner input = new Scanner(System.in);
String str=input.nextLine();
while(!str.equals("#")) {
String[] s = str.split("\\s+");
if (s.length == 1) {
//当前余额
double balance = 0;
for (int i = 0; i < union.getList().size(); i++) {
for (int j = 0; j < union.getList().get(i).getAccount().size(); j++) {
for (int k = 0; k < union.getList().get(i).getAccount().get(j).getCard().size(); k++) {
if (union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(str)) {
balance = union.getList().get(i).getAccount().get(j).getBalance();
}
}
}
}
System.out.printf("业务:查询余额 ¥%.2f", balance);
System.out.print("\n");
} else {
//存取款
double money = 0;
double nowbalance = 0;
String username = null;
String bankname = null;//通过卡号找到银行名字
String cardtype = null;
//每分割一行处理一行
vaildCard(s[0]);
vaildCardCode(s[1]);
vaildATM(s[2]);
getmoney(Double.valueOf(s[3]));//String转化成double
money = Double.valueOf(s[3]);
Bank bank = null;
for (int i = 0; i < union.getList().size(); i++) {
for (int j = 0; j < union.getList().get(i).getAccount().size(); j++) {
for (int k = 0; k < union.getList().get(i).getAccount().get(j).getCard().size(); k++) {
if (union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(s[0])) {
nowbalance = union.getList().get(i).getAccount().get(j).getBalance();
username = union.getList().get(i).getAccount().get(j).getname();
cardtype = union.getList().get(i).getAccount().get(j).gettype();
bankname = union.getList().get(i).getBankName();
bank = union.getList().get(i);
}
}
}
}
//通过ATM编号找到银行名字,对两个名字进行对比,判断跨行手续费
String Bankname = null;//通过ATM找到银行名字
for (int i = 0; i < union.getList().size(); i++) {
for (int j = 0; j < union.getList().get(i).getAtms().size(); j++) {
if (union.getList().get(i).getAtms().get(j).getAtm().equals(s[2])) {
Bankname = union.getList().get(i).getBankName();
}
}
}
if (!Vaild(s[0], s[1], s[2], Double.valueOf(s[3]), nowbalance, bank)) {
System.exit(0);
}
business1(username,s[2],bank,Double.parseDouble(s[3]), nowbalance, s[0],Bankname,cardtype);
}
str=input.nextLine();
}
}
public void business1(String username,String atmid, Bank bank, double money, double nowbalance, String cardnumber, String Bankname, String banktype){//存取款
int q = 0;
for(int i = 0;i < union.getList().size();i++) {
for(int j = 0;j< union.getList().get(i).getAccount().size();j++) {
for(int k = 0;k < union.getList().get(i).getAccount().get(j).getCard().size();k++) {
if(union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(cardnumber)) {
q++;
if(permission(atmid,bank)) {
switch (Bankname) {
case "中国建设银行":
union.getList().get(i).setRate(0.02);
break;
case "中国工商银行":
union.getList().get(i).setRate(0.03);
break;
case "中国农业银行":
union.getList().get(i).setRate(0.04);
break;
}
}
else{
union.getList().get(i).setRate(0);
}
double r=0;
double ba=0;
r=union.getList().get(i).getRate();
ba=union.getList().get(i).getAccount().get(j).getBalance();
double realmoney1 = money + r*money;
double realmoney2 = money + r*money + money*0.05;
if(nowbalance <=0){
realmoney2 = money + r*money + money*0.05;
}else{
realmoney2 = money + r*money + (money - nowbalance)*0.05;
}
if(banktype.equals("借记账号")){
if (realmoney1 > nowbalance) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
}
else if(banktype.equals("贷记账号")){
if (nowbalance-realmoney2<-50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
}
if(/*banktype.equals.equals(" 借记账号 " )&&*/realmoney1 <= nowbalance){
union.getList().get(i).getAccount().get(j).setBalance(nowbalance - realmoney1);//取款更新余额操作
}else if(banktype.equals("贷记账号") && money>nowbalance && nowbalance>0 /*&&amount*0.05<=50000&&amount>balance*/){
union.getList().get(i).getAccount().get(j).setBalance(nowbalance - realmoney2);//取款更新余额操作
}else if(banktype.equals("贷记账号")&&nowbalance<=0){
union.getList().get(i).getAccount().get(j).setBalance(nowbalance - realmoney2);//取款更新余额操作
}
if(q == 2)
show(username,Bankname,atmid,money,ba);
}
}
}
}
}
public void show(String username,String Bankname,String atmid,double money,double balance){
System.out.print("业务:取款 " + username + "在" + Bankname + "的" + atmid + "号ATM机");
System.out.printf("上取款¥%.2f\n", money);
System.out.printf("当前余额为¥%.2f\n",balance);
}
public static boolean vaild(String cardnumber, String cardcode, String atmid, double money, double nowbalance, Bank bank){
if(vaildCard(cardnumber)==false) {
System.out.println("Sorry,this card does not exist.");
return false;
}
if(vaildCardCode(cardcode)==false) {
System.out.println("Sorry,your password is wrong.");
return false;
}
if(vaildATM(atmid)==false) {
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
if(getmoney(money)==false) {
if(nowbalance<money) {
System.out.println("Sorry,your account balance is insufficient.");
return false;
}
}
/*if(permission(atmid,bank)==true) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
return false;
}*/
return true;
}
public static boolean Vaild(String cardnumber, String cardcode, String atmid, double money, double nowbalance, Bank bank){
if(vaildCard(cardnumber)==false) {
System.out.println("Sorry,this card does not exist.");
return false;
}
if(vaildCardCode(cardcode)==false) {
System.out.println("Sorry,your password is wrong.");
return false;
}
if(vaildATM(atmid)==false) {
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
/*if(getmoney(money)==false) {
if(nowbalance-money<-50000.00) {
System.out.println("Sorry,your account balance is insufficient.");
return false;
}
}*/
/*if(permission(atmid,bank)==true) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
return false;
}*/
return true;
}
public static boolean permission(String atmid, Bank bank) {//判断是否跨银行取款
for(int i = 0;i < bank.getAtms().size();i++) {
if(atmid.equals(bank.getAtms().get(i).getAtm())) {
return false;
}
}
return true;
}
public static boolean vaildCard(String cardnumber) {//判断卡号正确
for(int a = 0;a < union.getList().size();a++) {
for(int b = 0;b < union.getList().get(a).getAccount().size();b++) {
for(int c = 0;c < union.getList().get(a).getAccount().get(b).getCard().size();c++) {
if(cardnumber.equals(union.getList().get(a).getAccount().get(b).getCard().get(c).getCardNumber())) {
return true;
}
}
}
}
return false;
}
public static boolean vaildCardCode(String cardcode) {//判断密码是否正确
if(cardcode.equals("88888888")) {
return true;
}
return false;
}
public static boolean vaildATM(String atmid){//判断ATM机编号是否正确
for(int a=0;a<union.getList().size();a++) {
for(int b=0;b<union.getList().get(a).getAtms().size();b++) {
if(atmid.equals(union.getList().get(a).getAtms().get(b).getAtm())) {
return true;
}
}
}
return false;
}
public static boolean getmoney(double money) {//判断存取款
if(money>0){
return false;//取款
}else{
return true;//存款
}
}
}
class Bankunion{//存ATM
private ArrayList<Bank> list = new ArrayList<Bank>();
public Bankunion() {
}
public ArrayList<Bank> getList() {
return list;
}
public void setList(ArrayList<Bank> list) {
this.list = list;
}
public void addBank(Bank bank) {
list.add(bank);
}
}
class ATM{
private String atm;
public ATM(String atm) {
this.atm = atm;
}
public String getAtm() {
return atm;
}
public void setAtm(String atm) {
this.atm = atm;
}
}
class Bank{//银行存账号
private String BankName;
private ArrayList<Account> account= new ArrayList<Account>();
private ArrayList<ATM> list = new ArrayList<ATM>();
private double Rate;
public Bank(String BankName,double Rate) {
this.BankName = BankName;
this.Rate = Rate;
}
public String getBankName() {
return BankName;
}
public void setBankName(String BankName) {
this.BankName = BankName;
}
public double getRate() {
return Rate;
}
public void setRate(double Rate) {
this.Rate = Rate;
}
public ArrayList<Account> getAccount() {
return account;
}
public void setAccount(ArrayList<Account> account) {
this.account = account;
}
public ArrayList<ATM> getAtms() {
return list;
}
public void setAtms(ArrayList<ATM> atms) {
this.list = atms;
}
public void addATM(ATM atm) {
list.add(atm);
}
}
class Account{//账户存卡号,密码,用户名字,余额,账号
private String name = null;//户主名字
private String accountNumber= null;//账户
private ArrayList<Card> card= new ArrayList<Card>();
private double balance= 10000.00;//余额
private String type = null;//账户种类
public Account(String name, String accountNumber,String type,double balance) {
this.name = name;
this.accountNumber = accountNumber;
this.type = type;
this.balance = balance;
}
public ArrayList<Card> getCard() {
return card;
}
public void setCard(ArrayList<Card> card) {
this.card = card;
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getaccountNumber() {
return accountNumber;
}
public void setaccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public String gettype() {
return type;
}
public void settype(String type) {
this.type = type;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
class Card{
private String CardNumber = null;//卡号
private String CardCode = "88888888";//密码
private Account account = null;
public Card( String CardNumber,String CardCode) {
this.CardNumber = CardNumber;
this.CardCode = CardCode;
}
public String getCardNumber() {
return CardNumber;
}
public void setCardNumber(String CardNumber) {
this.CardNumber = CardNumber;
}
public String getCardCode() {
return CardCode;
}
public void setCardCode(String CardCode) {
this.CardCode = CardCode;
}
public Account getaccount() {
return account;
}
public void setBankaccount(Account account) {
this.account = account;
}
}
输入格式:
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
-
- 取款功能输入数据格式:
卡号 密码 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编号]上取款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③查询余额业务输出
业务:查询余额 ¥[金额]
金额保留两位小数。
此次的作业与上次的作业类似,只是添加了贷款,支持跨行取款的操作,贷款利息跨行取款利息的处理。

根据用户相关数据表,我先把账户种类放到Account类中。
class Account{//账户存卡号,密码,用户名字,余额,账号
private String name = null;//户主名字
private String accountNumber= null;//账户
private ArrayList<Card> card= new ArrayList<Card>();
private double balance= 10000.00;//余额
private String type = null;//账户种类
public Account(String name, String accountNumber,String type,double balance) {
this.name = name;
this.accountNumber = accountNumber;
this.type = type;
this.balance = balance;
}
public ArrayList<Card> getCard() {
return card;
}
public void setCard(ArrayList<Card> card) {
this.card = card;
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getaccountNumber() {
return accountNumber;
}
public void setaccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public String gettype() {
return type;
}
public void settype(String type) {
this.type = type;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
并且在银行类中加入利率属性。
class Bank{//银行存账号
private String BankName;
private ArrayList<Account> account= new ArrayList<Account>();
private ArrayList<ATM> list = new ArrayList<ATM>();
private double Rate;
public Bank(String BankName,double Rate) {
this.BankName = BankName;
this.Rate = Rate;
}
public String getBankName() {
return BankName;
}
public void setBankName(String BankName) {
this.BankName = BankName;
}
public double getRate() {
return Rate;
}
public void setRate(double Rate) {
this.Rate = Rate;
}
public ArrayList<Account> getAccount() {
return account;
}
public void setAccount(ArrayList<Account> account) {
this.account = account;
}
public ArrayList<ATM> getAtms() {
return list;
}
public void setAtms(ArrayList<ATM> atms) {
this.list = atms;
}
public void addATM(ATM atm) {
list.add(atm);
}
}
然后前面的部分大体与作业八一致,但是因为支持跨银行取款于是对ATM的输出进行了修改,因为上一题是根据银行账户找到银行名字在找到ATM机器去对输入的ATM机判断是否跨行取款,这一题是支持跨行取款,所以是通过ATM机号码找到银行再找到账户从而判断你输入的卡号是否在跨行取款来确定利率。
//通过ATM编号找到银行名字,对两个名字进行对比,判断跨行手续费
String Bankname = null;//通过ATM找到银行名字
for (int i = 0; i < union.getList().size(); i++) {
for (int j = 0; j < union.getList().get(i).getAtms().size(); j++) {
if (union.getList().get(i).getAtms().get(j).getAtm().equals(s[2])) {
Bankname = union.getList().get(i).getBankName();
}
}
}
因为跨行存取款以及贷款存在利率问题并且不同用户跨行取款的利率不同,并且贷记账户存在透支上限一说,因此之前那种简单粗暴的的余额处理肯定是不行的,一开始只是在原来的存取款代码进行添加以及修正,但是我最后发现因为之前的类和方法设计的不够好,尤其是我的之前每次存取款的余额那个地方完全不好修改,于是我便额外写了一个方法来进行存取款的业务操作(本来应该是写一个类来的,但是时间问题便偷懒另外写了一个方法来执行)。
public void business1(String username,String atmid, Bank bank, double money, double nowbalance, String cardnumber, String Bankname, String banktype){//存取款
int q = 0;
for(int i = 0;i < union.getList().size();i++) {
for(int j = 0;j< union.getList().get(i).getAccount().size();j++) {
for(int k = 0;k < union.getList().get(i).getAccount().get(j).getCard().size();k++) {
if(union.getList().get(i).getAccount().get(j).getCard().get(k).getCardNumber().equals(cardnumber)) {
q++;
if(permission(atmid,bank)) {
switch (Bankname) {
case "中国建设银行":
union.getList().get(i).setRate(0.02);
break;
case "中国工商银行":
union.getList().get(i).setRate(0.03);
break;
case "中国农业银行":
union.getList().get(i).setRate(0.04);
break;
}
}
else{
union.getList().get(i).setRate(0);
}
double r=0;
double ba=0;
r=union.getList().get(i).getRate();
ba=union.getList().get(i).getAccount().get(j).getBalance();
double realmoney1 = money + r*money;
double realmoney2 = money + r*money + money*0.05;
if(nowbalance <=0){
realmoney2 = money + r*money + money*0.05;
}else{
realmoney2 = money + r*money + (money - nowbalance)*0.05;
}
if(banktype.equals("借记账号")){
if (realmoney1 > nowbalance) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
}
else if(banktype.equals("贷记账号")){
if (nowbalance-realmoney2<-50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
}
if(/*banktype.equals.equals(" 借记账号 " )&&*/realmoney1 <= nowbalance){
union.getList().get(i).getAccount().get(j).setBalance(nowbalance - realmoney1);//取款更新余额操作
}else if(banktype.equals("贷记账号") && money>nowbalance && nowbalance>0 /*&&amount*0.05<=50000&&amount>balance*/){
union.getList().get(i).getAccount().get(j).setBalance(nowbalance - realmoney2);//取款更新余额操作
}else if(banktype.equals("贷记账号")&&nowbalance<=0){
union.getList().get(i).getAccount().get(j).setBalance(nowbalance - realmoney2);//取款更新余额操作
}
if(q == 2)
show(username,Bankname,atmid,money,ba);
}
}
}
}
}
(2)分析:
PowerDesigner的类图显示:

SourceMonitor 复杂度分析


2、踩坑心得:(1)类以及方法的设计要注意细节以及要明确什么人该做什么事的思想,如果一个类把事情全部都做完了,那如果事情变多了或者不同的事发生了变化变化了,那个类要修改的地方会很多,类的负担也会很重,并且小细节多 了根本无从下手的处理。
(2)逻辑思维还是存在问题,尤其是在存取款代码找账户的地方,三重循环应该会找到两次一样的,这就代表输出的时候你会多输出一次,就是你的结果是岔开的,因为时间问题以及精力问题无力再去解决这个地方,只能在多定义了一个变量q,使结果在q=2,也就是第二次找到账户的时候才进行输出,也算是自己代码的一个bug之处。
3、改进建议:我觉得时间允许的话,可以给业务单独写一个类出来执行自己的功能,存取款业务的三重循环也可以修改优化使其不会多找到一次一样的东西,逻辑思维还是需要一定的开拓。
四、总结
本阶段的作业谈的不再是难点,而是更加贴合实际的功能实现。这一阶段的题目所涉及的知识点则是前面学习的多种知识点进行串联而成,故此次的代码自己将类等结构的构造规划好之后,代码的书写也变得通畅许多。
这三次题目集的作业量明显变少,加在一起也一共只有6道题目,但题目各有各的特点做起来有循序渐进的感觉。题目集7通过对Comparable接口的继承以及compareTo方法的实现,利用父类列表ArrayList<Shape>,完成对不同子类图形的排序,利用继承与多态完成批量化规范操作。题目集8、9则是核心在于对面向对象规范化设计的考察,从一开始的给类图让你实现到自己进行类的设计,总体上对类职责的分配与调用。较为自由的要求反而更加锻炼的整体上的设计思想,和面向对象的设计。
其次,ATM的题目让我熟悉掌握了ArrayList泛型为类的使用方法,也学会了多个类一起相互关联的用处所在。同时自己从一开始的对最基本的语法尚不熟悉,到第一阶段结束时逐步掌握Java的如继承、多态等特性以及不同方法的使用,和声明式编程内容正则表达式等,再到现在进一步了解更多如接口,以及更多面向对象思想和设计原则如开闭原则等等,对Java的理解的的确确是在不断加深的。
浙公网安备 33010602011771号