读书人

【输入帖】小弟我写了一个关于根据读入

发布时间: 2013-07-01 12:33:04 作者: rapoo

【输入求助帖】我写了一个关于根据读入参数不同判断的程序
本帖最后由 qingling_1979 于 2013-04-27 09:36:37 编辑 这是题目:
   编写一个程序,用于根据用户输入的命令行参数数量来计算长方形、正方形、三角形的面积。如果输入的参数为一个、二个、三个则它们应分别对应正方形、长方形、三角形,如果没有参数,则通过异常处理方法显示错误消息。??? 提示:定义一个抽象的父类,并提供一个抽象的方法area(). 再派生出三个子类,重写area()方法,然后在main方法中编写测试逻辑。
这是我编写的程序:
import java.util.*;
import java.math.*;
import java.io.*;
abstract class area{
abstract double getArea();
}
class Zfx extends area{
double a;
double getArea(){
return a*a;
}
void getA(double a){
this.a=a;
}
}

class Cfx extends area{
double a,b;
double getArea(){
return a*b;
}
void getA(double a,double b){
this.a=a;
this.b=b;
}
}

class Sjx extends area{
double a,b,c;
double getArea(){
doublep=(a+b+c)/2.0;
return Math.sqrt(p*(p-a)*(p-b)*(p-c));
}
void getA(double a,double b,double c){
this.a=a;
this.b=b;
this.c=c;
}
}

class SRException extends Exception{
String message="输入参数错误。请重新输入。";
String warnMess(){
return message;
}
}

public class MianJi{
public static void main(String args[])throws SRException{
try { Scanner scanner=new Scanner(System.in);
int count=-1;
double Main=0;
Vector<Double> a=new Vector<Double>();
for(int i=0;scanner.hasNext();i++)
a.add(scanner.nextDouble());
/* scanner.nextLine();*/ //这行是后来加上去的。没起什么作用。
if(a.size()>3||a.size()<1) throw new SRException();

switch(a.size()){
case 1:Zfx zfx=new Zfx(); zfx.getA(a.elementAt(0));Main=zfx.getArea();break;
case 2:Cfx cfx=new Cfx(); cfx.getA(a.elementAt(0),a.elementAt(1));Main=cfx.getArea();break;
case 3:Sjx sjx=new Sjx(); sjx.getA(a.elementAt(0),a.elementAt(1),a.elementAt(2));Main=sjx.getArea();break;
}
System.out.println("图形面积为"+Main);
}

catch(SRException e){
System.out.println(e.warnMess());
}
}
}
编译通过,运行输入无法结束。求大神帮忙解下面2,3问题。感激不尽。

遇到问题:
三角形如何判断是否是合法三角形
如何结束输入
如果用抽象父类就利用上转型变量,而上转型变量只能调用父类或重写方法,而参数传递(参数个数不一样)如何使得上转型可以调用这个,抽象父类怎么写能解决参数不一的问题。
[解决办法]
1. 合法三角形三边不在一条直线上,所以只要看是不是有三个相同的x或y坐标即可


2. Ctrl + C。。。或者定义一个结束命令,输入"quit"就退出程序
3. 其实没怎么看懂你这问题,不过一般会写成这样:

abstract class Shape {
public abstract double area();
}
class Square extends Shape{
private double edge;
public Square (double aEdge) {
edge = aEdge;
}
@Override
public double area() {
return edge*edge;
}
}

class Rectangle extends Shape {
//自己实现了
}

public void main (String [] args) {
...

if (input.length == 1) {
output: new Square(input[0]).area();
} else if (input.length == 2) {
output: new Rectangle(input[0], input[1]).area();
}
else if...
...

我是真不明白这里为什么要用抽象继承。。
[解决办法]
纯个人理解,仅供参考!

1,输入问题
hasNext系方法就是通过判断结束标志来返回true or false的。
System.in与文件读入是不同的,文件有确定的文件尾,而System.in的结束标志呢?
我认为,System.in的Scanner不可以用hasNext系方法来判断,因为你可以无穷无尽的输入。
所以,如果是确定个数的输入(比如输入两个),用相应确定个数的next即可(比如两个nextInt())
如果是不确定个数的输入,一种方法是第一个输入指定了个数,然后其余的输入用for来读入(因为第一个输入已经指定了剩下的个数)
或者,自己定义一个结束符(比如输入若干正数规定0是结束标志),用while循环读入直到读到结束标志。

然而,你的程序却产生了一个逻辑方面的问题:
因为你的程序是为了确定用户的输入是否合理,所以以上两种方法不能用了(用户可以第一个数不作为个数,也可以不输入结束标志!)

所以,为了解决上述问题,一种方法是从文件读入,而另一种方法更为推荐:给main方法传递参数!楼上的input.length就成了args.length吧。。。

2.三角形问题
一般来说,构成三角形是三边为正数且任两边之和大于第三边!
但是,我觉得并不需要显式的判断它,因为如果你要计算面积,假设三个数不能构成,那么这就是一个虚三角形,你计算面积的时候就会出现问题(比如三点共线面积为0)。下面我以海伦公式为例说明一下。

假设在平面内,有一个三角形,边长分别为a、b、c,三角形的面积S可由以下公式求得:
S=√[p(p-a)(p-b)(p-c)]
而公式里的p为半周长:
p=(a+b+c)/2

如果你输入的三个数不能构成三角形,不妨设a<b<c且a+b<c,那么p-c=(a+b-c)/2<(c-c)/2<0而(p-a)(p-b)=p(c-(a+b))/2+ab>0,所以p(p-a)(p-b)(p-c)<0,这个三角形面积是一个虚数,调用Math.sqrt()的时候会返回NaN,此时再throw你定义的那个异常就行了。
(如果不能构成三角形,面积会求出来等于0或者NaN,判断这个就行)

3.上转型问题

Zfx zfx=new Zfx();
Cfx cfx=new Cfx();
Sjx sjx=new Sjx();


如果这样就没有意义了吧!
上转型就是就是 父类引用 指向 子类对象嘛
应该定义一个Area型的引用,然后它根据参数个数不同:

Area ar;
if(...)ar=new Zfx();
if(...)ar=new Cfx();
if(...)ar=new Sjx();

[解决办法]
1.三角形的判断:a+b>c&&a+c>b&&b+c>a就行了
2.exit(0);可以退出程序
3.一般来说,这个求面积的数据类型都会用double的

读书人网 >J2SE开发

热点推荐