第三阶段Blog作业
一·前言:
题目集07:只有两道题,且第二题是第一题基础上的改进;体量不大,两题全对,由于参考了实验指导书的部分代码,习题难度适中;本次习题主要考察了继承以及大量的排序,求和的算法。
题目集08:只有一道题,算是java的一个小小的应用(虽然我是用面向过程写的);题目的测试点可能有些细节上的问题我找了很久,有一个测试点始终无法通过,最终是90分,也算不错,毕竟用面向过程写Java程序也倒别有一番风味,思路同样清晰,配合整齐的排版和适当的注释,整个程序阅读起来毫不费力;知识点倒没什么,主要是数组的灵活运用配上我巧妙的算法,使得问题迎刃而解。这次习题我使用了一个下午加晚餐时间一次性写完的,没有借助任何人的帮助或提示,自己做出那麽多测试点都通过,虽然没有满分,但心里依旧很有成就感。
题目集09:是题目集08的延续,主体上不变,修改可跨银行功能,再添加几个可借贷账户,最后增添利率的相应计算稍微改一下输出,这道题目也就出来了,我自己做的直到和测试答案一模一样为止,可是结果还是有两个测试点过不了,尝试做了很多的修改也没效果,最后就80分,我认了。虽然也只有一道题,整体难度也不大,但对于思维的锻炼确实很有帮助,不得不承认,有时候写代码比玩游戏看小说追剧要刺激。
二·设计与分析:
①题目集7(7-1)、(7-2)两道题目的递进式设计分析总结:
(7-1)中有
首先,对于第一行的输入——1,含义:相应图形的代号,即1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。2,执行:代码必须给第一行的代码予以限制,即以0结束和输入的前面数值必须为1,2,3,4.
3,后续作用:将输入的数值放到数组中,从而使得在后续过程中可以根据数值设定卡片的名称,以及求图形面积所需要输入的数据的数量。
代码实现如下:
int[] areaList=new int[100];
int count =0;
int num =Main.input.nextInt();
while(num != 0){
if(num < 0 || num > 4){
System.out.println("Wrong Format");
System.exit(0);
}
areaList[count]=num;
count++;
num=Main.input.nextInt();
}
其次,将数组循环,轮到什么图形就输入求该图形面积所需要的数据,同时调用子类对象,计算该图形的面积,并将计算得出的值储存再一个专门的数组中。
代码实现如下:
for(int i=0;i<areaList.length;i++)
{
if(areaList[i]==1)
{
double radius=Main.input.nextDouble();
Circle circle=new Circle(radius);
if(radius<=0) {
System.out.println("Wrong Format");
System.exit(0);
}
area[w]=circle.getArea();
String areaName="Circle";
w++;
}
if(areaList[i]==2) {
double length=Main.input.nextDouble();
double width=Main.input.nextDouble();
Rectangle rectangle=new Rectangle(length,width);
if(length<=0||width<=0) {
System.out.println("Wrong Format");
System.exit(0);
}
area[w]=rectangle.getArea();
w++;
}
if(areaList[i]==3) {
double d=Main.input.nextDouble();
double e=Main.input.nextDouble();
double f=Main.input.nextDouble();
Triangle triangle=new Triangle(d,e,f);
if(d<=0||e<=0||f<=0||d+e<=f||d+f<=e||e+f<=d) {
System.out.println("Wrong Format");
System.exit(0);
}
area[w]=triangle.getArea();
w++;
}
if(areaList[i]==4) {
double topSide=Main.input.nextDouble();
double bottomSide=Main.input.nextDouble();
double height=Main.input.nextDouble();
Trapezoid trapezoid=new Trapezoid(topSide,bottomSide,height);
if(topSide<=0||bottomSide<=0||height<=0) {
System.out.println("Wrong Format");
System.exit(0);
}
area[w]=trapezoid.getArea();
w++;
}
}
最后,给储存面积的数组中的面积求和,排序,并保留两位小数输出。至于子类中则各自实现各自的面积计算方法;
例如:
abstract class Shape {
public abstract double getArea();
}
class Circle extends Shape {
double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
double width;
double length;
Rectangle(double width, double length) {
this.width = width;
this.length = length;
}
@Override
public double getArea() {
return width * length;
}
}
class Triangle extends Shape {
double d, e, f;
public Triangle(double d, double e, double f) {
this.d = d;
this.e = e;
this.f = f;
}
@Override
public double getArea() {//④
double ave = (d + e + f) / 2;
return Math.sqrt(ave * (ave - d) * (ave - e) * (ave - f));
}
}
class Trapezoid extends Shape{
double topSide,bottomSide,height;
Trapezoid(double topSide,double bottomSide,double height){
this.bottomSide=bottomSide;
this.height=height;
this.topSide=topSide;
}
@Override
public double getArea() {
return (topSide+bottomSide)*height/2;
}
}
(7-2)中有
主题不变,给每个图形的面积设定独立的数组,再将得到的面积归类到相应的图形数组中
代码如下:
double[] areasOfCircle=new double[100];
int a=0;
double areaSumOne=0;
System.out.print("[");
for(m=0;m<w;m++) {
s=areaList[m];
if(s==1) {
System.out.printf(areaName[s]+":%.2f ",area[m]);
areasOfCircle[a]=area[m];
a++;
areaSumOne+=area[m];
}
}
System.out.print("]");
areaSumList[0]=areaSumOne;
double[] areasOfRectangle=new double[100];
int b=0;
double areaSumTwo=0;
System.out.print("[");
for(m=0;m<w;m++) {
s=areaList[m];
if(s==2) {
System.out.printf(areaName[s]+":%.2f ",area[m]);
areasOfRectangle[b]=area[m];
b++;
areaSumTwo+=area[m];
}
}
System.out.print("]");
areaSumList[1]=areaSumTwo;
double[] areasOfTriangle=new double[100];
int c=0;
double areaSumThree=0;
System.out.print("[");
for(m=0;m<w;m++) {
s=areaList[m];
if(s==3) {
System.out.printf(areaName[s]+":%.2f ",area[m]);
areasOfTriangle[c]=area[m];
c++;
areaSumThree+=area[m];
}
}
System.out.print("]");
areaSumList[2]=areaSumThree;
double[] areasOfTrapezoid=new double[100];
int d=0;
double areaSumFour=0;
System.out.print("[");
for(m=0;m<w;m++) {
s=areaList[m];
if(s==4) {
System.out.printf(areaName[s]+":%.2f ",area[m]);
areasOfTrapezoid[d]=area[m];
d++;
areaSumFour+=area[m];
}
}
System.out.print("]");
areaSumList[3]=areaSumFour;
最后再给各自的图形数组中的面积进行排序
代码如下:
int i,j;
double temp=0;
for(i=0;i<a-1;i++) {
for(j=i+1;j<a;j++) {
if(areasOfCircle[i]<areasOfCircle[j]) {
temp=areasOfCircle[i];
areasOfCircle[i]=areasOfCircle[j];
areasOfCircle[j]=temp;
}
}
}
System.out.print("[");
for(i=0;i<a;i++) {
System.out.printf(areaName[1]+":%.2f ",areasOfCircle[i]);
}
System.out.print("]");
for(i=0;i<b-1;i++) {
for(j=i+1;j<b;j++) {
if(areasOfRectangle[i]<areasOfRectangle[j]) {
temp=areasOfRectangle[i];
areasOfRectangle[i]=areasOfRectangle[j];
areasOfRectangle[j]=temp;
}
}
}
System.out.print("[");
for(i=0;i<b;i++) {
System.out.printf(areaName[2]+":%.2f ",areasOfRectangle[i]);
}
System.out.print("]");
for(i=0;i<c-1;i++) {
for(j=i+1;j<c;j++) {
if(areasOfTriangle[i]<areasOfTriangle[j]) {
temp=areasOfTriangle[i];
areasOfTriangle[i]=areasOfTriangle[j];
areasOfTriangle[j]=temp;
}
}
}
System.out.print("[");
for(i=0;i<c;i++) {
System.out.printf(areaName[3]+":%.2f ",areasOfTriangle[i]);
}
System.out.print("]");
for(i=0;i<d-1;i++) {
for(j=i+1;j<d;j++) {
if(areasOfTrapezoid[i]<areasOfTrapezoid[j]) {
temp=areasOfTrapezoid[i];
areasOfTrapezoid[i]=areasOfTrapezoid[j];
areasOfTrapezoid[j]=temp;
}
}
}
两题的类图如下:

②题目集8和题目集9两道ATM机仿真题目的设计思路分析总结
题目集8中
1,给账户,银行,银行卡分别设定数组存储相应的数据,其中多卡共用一个账户的情况单独设立账户。
代码如下:
double[] balance=new double[] {
10000,10000,10000,10000,10000,10000
};
double ybalance=10000,zbalance=10000;
int a,b=0;
String[] cards=new String[]{"6217000010041315709","6217000010041315715","6217000010041315718",
"6217000010051320007","6222081502001312389","6222081502001312390",
"6222081502001312399","6222081502001312400","6222081502051320785","6222081502051320786"};
String[] user=new String[] {"杨过","郭靖","张无忌","韦小宝"};
String[] bank=new String[] {"中国建设银行","中国工商银行"};
2,对于输入的数据进行识别,归类,且遇#停止输入
代码如下:
String[] string=new String[100];
for(int i=0;;i++) {
string[i]=input.next();
a=i+1;
if(string[i].equals("#"))
break;
}
//设定卡号及输入等准备工作
for(int i=0;i<a;i++) {
int card=0+4*i;
int password=card+1;
int atm=card+2;
int draw=card+3;
3,对卡号,ATM,等进行合法性检验
例如:
if(password<a&&!string[password].equals("#")&&!string[password].equals("88888888")) {
System.out.println("Sorry,your password is wrong.");
System.exit(0);
}
if(atm<a&&!string[atm].equals("#")) {
if(!string[atm].equals("01")&&!string[atm].equals("02")&&!string[atm].equals("03")&&
!string[atm].equals("04")&&!string[atm].equals("05")&&!string[atm].equals("06")) {
System.out.println("Sorry,the ATM's id is wrong.");
System.exit(0);
}
4,给每个不同的账户分区,各自计算余额并输出,其中包括是否跨银行检验
代码例如:
for(int i=0;i<a;i++) {
for(int j=0;j<2;j++) {
if(string[i].equals(cards[j])&&i+3<=a) {
if(string[i+2].equals("05")||string[i+2].equals("06")) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
double withdraw=Double.parseDouble(string[i+3]);
if(withdraw<=0) {
System.out.printf(user[0]+"在"+bank[0]+"的"+string[i+2]+"号ATM机上存款¥"+"%.2f\n",-withdraw);
ybalance-=withdraw;
System.out.printf("当前余额为¥%.2f\n",ybalance);
}
else {
if(withdraw>ybalance) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf(user[0]+"在"+bank[0]+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
ybalance-=withdraw;
System.out.printf("当前余额为¥%.2f\n",ybalance);
}
}
if(string[i].equals(cards[j])&&i+3>a){
System.out.printf("¥"+"%.2f\n",ybalance);
}
}
//杨过的账户区1
if(string[i].equals(cards[2])&&i+3<=a) {
if(string[i+2].equals("05")||string[i+2].equals("06")) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
double withdraw=Double.parseDouble(string[i+3]);
if(withdraw<=0) {
System.out.printf(user[0]+"在"+bank[0]+"的"+string[i+2]+"号ATM机上存款¥"+"%.2f\n",-withdraw);
balance[0]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[0]);
}
else {
if(withdraw>balance[0]) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf(user[0]+"在"+bank[0]+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
balance[0]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[0]);
}
}
if(string[i].equals(cards[2])&&i+3>a){
System.out.printf("¥"+"%.2f\n",balance[0]);
}
//杨过账户区2
if(string[i].equals(cards[3])&&i+3<=a) {
if(string[i+2].equals("05")||string[i+2].equals("06")) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
double withdraw=Double.parseDouble(string[i+3]);
if(withdraw<=0) {
System.out.printf(user[1]+"在"+bank[0]+"的"+string[i+2]+"号ATM机上存款¥"+"%.2f\n",-withdraw);
balance[1]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[1]);
}
else {
if(balance[1]<withdraw) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf(user[1]+"在"+bank[0]+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
balance[1]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[1]);
}
}
if(string[i].equals(cards[3])&&i+3>a){
System.out.printf("¥"+"%.2f\n",balance[1]);
}
//郭靖的账户区
for(int j=4;j<6;j++) {
if(string[i].equals(cards[j])&&i+3<=a) {
if(!string[i+2].equals("05")&&!string[i+2].equals("06")) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
double withdraw=Double.parseDouble(string[i+3]);
if(withdraw<=0) {
System.out.printf(user[2]+"在"+bank[1]+"的"+string[i+2]+"号ATM机上存款¥"+"%.2f\n",-withdraw);
balance[j-2]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[j-2]);
}
else {
if(balance[j-2]<withdraw) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf(user[2]+"在"+bank[1]+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
balance[j-2]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[j-2]);
}
}
if(string[i].equals(cards[j])&&i+3>a){
System.out.printf("¥"+"%.2f\n",balance[j-2]);
}
}
//张无忌的账户区1
for(int j=6;j<8;j++) {
if(string[i].equals(cards[j])&&i+3<=a) {
if(!string[i+2].equals("05")&&!string[i+2].equals("06")) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
double withdraw=Double.parseDouble(string[i+3]);
if(withdraw<=0) {
System.out.printf(user[2]+"在"+bank[1]+"的"+string[i+2]+"号ATM机上存款¥"+"%.2f\n",-withdraw);
zbalance-=withdraw;
System.out.printf("当前余额为¥%.2f\n",zbalance);
}
else {
if(zbalance<withdraw) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf(user[2]+"在"+bank[1]+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
zbalance-=withdraw;
System.out.printf("当前余额为¥%.2f\n",zbalance);
}
}
if(string[i].equals(cards[j])&&i+3>a){
System.out.printf("¥"+"%.2f\n",zbalance);
}
}
//张无忌账户区2
for(int j=8;j<10;j++) {
if(string[i].equals(cards[j])&&i+3<=a) {
if(!string[i+2].equals("05")&&!string[i+2].equals("06")) {
System.out.println("Sorry,cross-bank withdrawal is not supported.");
System.exit(0);
}
double withdraw=Double.parseDouble(string[i+3]);
if(withdraw<=0) {
System.out.printf(user[3]+"在"+bank[1]+"的"+string[i+2]+"号ATM机上存款¥"+"%.2f\n",-withdraw);
balance[j-4]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[j-4]);
}
else {
if(balance[j-4]<withdraw) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf(user[3]+"在"+bank[1]+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
balance[j-4]-=withdraw;
System.out.printf("当前余额为¥%.2f\n",balance[j-4]);
}
}
if(string[i].equals(cards[j])&&i+3>a){
System.out.printf("¥"+"%.2f\n",balance[j-4]);
}
}
//韦小宝的账户区
题目集9中
1,如法炮制题目集8,在各数组中添加数据,同时给ATM机编号也整一个数组
double[] balance=new double[] {
10000,10000,10000,10000,10000,10000,10000,10000,10000
};
double ybalance=10000,zbalance=10000,fbalance=10000;
int a;
String[] cards=new String[]{"6217000010041315709","6217000010041315715","6217000010041315718",
"6217000010051320007","6222081502001312389","6222081502001312390",
"622081502001312399","6222081502001312400","6222081502051320785","6222081502051320786",
"6640000010045442002","6640000010045442003","6640000010045441009","6630000010033431001",
"6630000010033431008"};
String[] user=new String[] {"杨过","郭靖","张无忌","韦小宝","张三丰","令狐冲","乔峰","洪七公"};
String[] bank=new String[] {"中国建设银行","中国工商银行","中国农业银行"};
String[] atm=new String[] {"01","02","03","04","05","06","07","08","09","10","11"};
2,添加新的账户,可借贷类型(细节见前言)
for(int j=10;j<12;j++) {
if(string[i].equals(cards[j])&&i+3<=a) {
bankName=banky.judge(string[i+2]);
double withdraw=Double.parseDouble(string[i+3]);
fee=banky.crossBank(bank[0], bankName, withdraw);
if(withdraw>fbalance&&fbalance>=0) {
fee+=(withdraw-fbalance)*0.05;
}
if(fbalance<0) {
fee+=withdraw*0.05;
}
fbalance-=(withdraw+fee);
if(fbalance<-50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf("业务:取款 "+user[4]+"在"+bankName+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
System.out.printf("当前余额为¥%.2f\n",fbalance);
}
if(string[i].equals(cards[j])&&i+3>a){
System.out.print("业务:查询余额 ");
System.out.printf("¥"+"%.2f\n",fbalance);
}
}
//张三丰的账户区
if(string[i].equals(cards[12])&&i+3<=a) {
bankName=banky.judge(string[i+2]);
double withdraw=Double.parseDouble(string[i+3]);
fee=banky.crossBank(bank[1], bankName, withdraw);
if(withdraw>balance[6]&&balance[6]>=0) {
fee+=(withdraw-balance[6])*0.05;
}
if(balance[6]<0) {
fee+=withdraw*0.05;
}
balance[6]-=(withdraw+fee);
if(balance[6]<-50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf("业务:取款 "+user[5]+"在"+bankName+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
System.out.printf("当前余额为¥%.2f\n",balance[6]);
}
if(string[i].equals(cards[12])&&i+3>a){
System.out.print("业务:查询余额 ");
System.out.printf("¥"+"%.2f\n",balance[6]);
}
//令狐冲的账户区
if(string[i].equals(cards[13])&&i+3<=a) {
bankName=banky.judge(string[i+2]);
double withdraw=Double.parseDouble(string[i+3]);
fee=banky.crossBank(bank[2], bankName, withdraw);
if(withdraw>balance[7]&&balance[6]>=0) {
fee+=(withdraw-balance[7])*0.05;
}
if(balance[7]<0) {
fee+=withdraw*0.05;
}
balance[7]-=(withdraw+fee);
if(balance[7]<-50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf("业务:取款 "+user[6]+"在"+bankName+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
System.out.printf("当前余额为¥%.2f\n",balance[7]);
}
if(string[i].equals(cards[13])&&i+3>a){
System.out.print("业务:查询余额 ");
System.out.printf("¥"+"%.2f\n",balance[7]);
}
//乔峰的账户区
if(string[i].equals(cards[14])&&i+3<=a) {
bankName=banky.judge(string[i+2]);
double withdraw=Double.parseDouble(string[i+3]);
fee=banky.crossBank(bank[2], bankName, withdraw);
if(withdraw>balance[8]&&balance[8]>=0) {
fee+=(withdraw-balance[8])*0.05;
}
if(balance[8]<0) {
fee+=withdraw*0.05;
}
balance[8]-=(withdraw+fee);
if(balance[8]<-50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
System.out.printf("业务:取款 "+user[7]+"在"+bankName+"的"+string[i+2]+"号ATM机上取款¥"+"%.2f\n",withdraw);
System.out.printf("当前余额为¥%.2f\n",balance[8]);
}
if(string[i].equals(cards[14])&&i+3>a){
System.out.print("业务:查询余额 ");
System.out.printf("¥"+"%.2f\n",balance[8]);
}
//洪七公的账户区
3,设置一个新的类,专门用于计算跨银行手续费用计算
例如:
class Bank{
String bankName;
double fee;
public String judge(String m) {
if(m.equals("01")||m.equals("02")||m.equals("03")||m.equals("04")) {
bankName="中国建设银行";
}
if(m.equals("05")||m.equals("06")) {
bankName="中国工商银行";
}
if(m.equals("07")||m.equals("08")||m.equals("09")||m.equals("10")||m.equals("11")) {
bankName="中国农业银行";
}
return bankName;
}
public double crossBank(String bank,String bankName,double withdraw) {
if(!bank.equals(bankName)) {
if(bankName.equals("中国建设银行")) {
fee=withdraw*0.02;
}
if(bankName.equals("中国工商银行")) {
fee=withdraw*0.03;
}
if(bankName.equals("中国农业银行")) {
fee=withdraw*0.04;
}
}
else
fee=0;
return fee;
}
}
两题类图如下:


由于大体采用面向过程编程所以只有一两个类,嘿嘿,献丑,献丑。
三·踩坑心得
怎么说呢,写代码的时候就一个目标,按照题目要求无限向测试用例的输出逼近,当写完以后,通过不断地使用数据测试,修改,再测试,最后达到和所有输出用例的结果都一模一样。但这仅仅是完成了一部分,因为当代码在PTA上运行的时候几乎总会有几个测试点过不去,这个时候只能根据PTA上那似有实无的提示适当修改自己的代码,也许是修改输出的位置,也许是要做到全部非法数据都要报错,这个时候就只能耐下性子,一次一次修改,希望剩下的几个测试点能过了,虽然我没那么好运,很难全对,呜呜呜。
四·改进建议
虽然面向过程思路清晰,代码简洁,很好用。但是作为面向对象这门课程,还是要尽量多多按照面向对象编程的一些原则来写代码吧。
五·总结
通过这几次,也是最后几次的作业,我深深地爱上了Java,也爱上了编程,程序设计锻炼了我的思维能力,也日记积月累地提高了我的职业技能。同时,通过这个学期的代码书写,我发现,写代码,不在乎从什么时候开始,最重要的是不要断断续续,最好用一个完整的上午,下午或晚上全神贯注,一气呵成,就能写完,写好一次的代码作业。舍不得,就结课了,罗老师下个学期,我们还会再见吗?

浙公网安备 33010602011771号