[求助]我要崩溃了——老师给的一道小题
老师给的一道小题,搞得我很郁闷。题目如下:
输入两个数x1和x2,计算其和。
要求:
1、x1和x2可以为复数,输入格式为a+bi,其中a为实部,b为虚部。如4+9i。
2、x1和x2可以为整数,则输出为整数。
3、x1和x2可以为小数,若相加和后为整数,则不能带小数部分,如2.4+3.6=6,而不能是6.0。
4、x1和x2可以为分数,输入格式为a/b,输出格式亦为此形式,要考虑化简。
5、x1和x2可以为不同类型的数,尤其是小数与分数相加。(若精力有限,可暂时不考虑)
6、要用到继承。
现在偶已经要疯掉了。。。。。
问题点数:50、回复次数:34Top
1 楼zxh2208180(九天玄狐)回复于 2006-10-27 22:15:25 得分 0
惭愧 数学我学的莱!!Top
2 楼cosmicbomb()回复于 2006-10-28 09:30:11 得分 0
用构造函数吧`````Top
3 楼jlusdy(LOST)回复于 2006-10-28 10:14:04 得分 0
写这么个东西挺锻炼人的
楼主不妨自己试试啊
学过设计模式吧?Top
4 楼syhan(藏书人)回复于 2006-10-28 11:05:36 得分 0
这个不难,就用简单的面向对象的基础知识就可以了,无须什么设计模式之类的东西Top
5 楼changzhang(爪哇猫)回复于 2006-10-28 11:32:33 得分 0
应该不是很难吧,就像楼主说的那样,用继承吧。
定义一个主类为基类(数据)
它提供的方法除下面这些子类共有的外,再提供对象的创建方法,根据数值的不同,比如
整数和分数,生成不同的子类对象。
然后它的自类分别为,整数,分数,小数,。。。。
他们的共用方法有:计算求和,包括同类型的,不同类型的。判断是否为本类型的数值。
然后定义一个分析类,他将用户输入的表达式呢分析出来,那些是数值,那些是运算符。
然后通过数据基类把他们创建成对象,再用他们提供的方法运算就可以了吧。
没有动手去试,感觉这样应该可以了。Top
6 楼andycpp(幻瞳)回复于 2006-10-28 11:40:47 得分 0
有意思,做一个试试~~~~Top
7 楼lovelycatty(傻猫咪咪)回复于 2006-10-28 11:44:55 得分 0
我一开始也以为很简单,但后来发现Bug太多啦!
尤其是输入复数和分数,我写好几十行的代码都不够的!比如说复数中+或i号如果输入两个,怎么判断?分数中有两个/又怎么判断?另外对于小数如何去掉点后多余的0?还有一个小数一个分数如何计算?小数如何转化成分数?这些难道很简单吗?!Top
8 楼andycpp(幻瞳)回复于 2006-10-28 11:56:45 得分 0
分数中有两个/又怎么判断?
崩溃,要求这么高啊?Top
9 楼lovelycatty(傻猫咪咪)回复于 2006-10-28 12:25:49 得分 0
这个要求算高吗?
面对不同的用户,出现的问题也千奇百怪,我能想到的还只是一部分。Top
10 楼andycpp(幻瞳)回复于 2006-10-28 15:34:29 得分 0
这个要求算高吗?
面对不同的用户,出现的问题也千奇百怪,我能想到的还只是一部分。
----------------------------------------------------------------------------
照你这么考虑,对于一个复数,他的实部可以是整数的形势,小数的形式,分数的形式,计算结果不能改变这种形式哈。
再有,(1+2i)/(3+4i)也属于复数,程序应该予以处理。。。。。。。
累死人不偿命啊。。。。。。。Top
11 楼hdhmail2000(禅剑飞雪)回复于 2006-10-28 23:59:53 得分 0
我晕,你们老师仅仅考了下你们字符串的处理罢了
这个题把字符串的问题搞定,类型转换,我看基本就差不多了
比如是不是复数,你看他有没有字符i,是不是分数,你看他有没有/,我想这个应该不难吧?
关于分数问题:分数的计算是a/b+c/d=(ad+bc)/bd,化简当然是求ad+bc和bd的最大公倍数了
你可以用循环找出来,那个值肯定小于或等于他们两个中小的一个,然后就是最小的这个开始,不断减1循环与他们两个取余,一旦找到立即break;
如ab+bc<bd,那么
int findValue=1;
for(int i=(ab+bc);i>1;i--)
{
if((ab+bc)%i==0&&bd%i==0)
{
findValue=i;
break;
}
}
a/b+c/d==((ad+bc)/findValue)/(bd/findValue);//这就是化简后相加的分数,具体类型转换你自己搞了,我只是提个思想
不过倒是要考虑周全点倒是真的
楼竹有有这些思想应该不难解决Top
12 楼hdhmail2000(禅剑飞雪)回复于 2006-10-29 00:04:43 得分 0
除去第5条要求,那么其他的都容易,
复数的要考虑下a+i,xi,i这种特殊情况Top
13 楼hdhmail2000(禅剑飞雪)回复于 2006-10-29 00:19:18 得分 0
我一开始也以为很简单,但后来发现Bug太多啦!
尤其是输入复数和分数,我写好几十行的代码都不够的!比如说复数中+或i号如果输入两个,怎么判断?分数中有两个/又怎么判断?另外对于小数如何去掉点后多余的0?还有一个小数一个分数如何计算?小数如何转化成分数?这些难道很简单吗?!
-----------------------------------------------------------------------------
我觉得你们老师应该不会让你考虑i,/输入两个之类的吧?可能你考虑太多
如果连个小数加后为整数,你可以把结果中取整数部分进行比较,两个的值相等,才进行整数转换
Top
14 楼andycpp(幻瞳)回复于 2006-10-30 11:02:55 得分 50
用于测试的类:
public class AddNumber {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyNumber n1 = NumberFactory.createNumber("3+4.5i");
MyNumber n2 = NumberFactory.createNumber("1/2");
MyNumber n3 = NumberFactory.createNumber("-3/4");
MyNumber n4 = NumberFactory.createNumber("5.88");
MyNumber n5 = NumberFactory.createNumber("-3");
MyNumber n6 = NumberFactory.createNumber("4/9");
MyNumber n7 = NumberFactory.createNumber("5/9");
System.out.println(n1.add(n2));
System.out.println(n1.add(n5));
System.out.println(n2.add(n3));
System.out.println(n2.add(n4));
System.out.println(n6.add(n7));
}
}
Top
15 楼andycpp(幻瞳)回复于 2006-10-30 11:03:49 得分 0
各种数字类的父类:
public abstract class MyNumber {
public abstract MyNumber add(MyNumber n);
public abstract double getRealpart();
public abstract double getImaginarypart();
}Top
16 楼andycpp(幻瞳)回复于 2006-10-30 11:04:40 得分 0
复数类:
public class ComplexNumber extends MyNumber {
public ComplexNumber(double a, double b) {
realpart = a;
imaginarypart = b;
}
@Override
public MyNumber add(MyNumber n) {
// TODO Auto-generated method stub
if(n==null)
return null;
double a, b;
a = realpart + n.getRealpart();
b = imaginarypart + n.getImaginarypart();
MyNumber result;
if( !(DecimalNumber.isInt(b) && (int)b == 0) ) //虚部不为0,返回值为复数
result = new ComplexNumber(a, b);
else if( !DecimalNumber.isInt(a) ) //实部为小数,返回值为小数类型
result = new DecimalNumber(a);
else //实部为整数,返回整数类型
result = new IntegerNumber((int)a);
return result;
}
@Override
public double getImaginarypart() {
// TODO Auto-generated method stub
return imaginarypart;
}
@Override
public double getRealpart() {
// TODO Auto-generated method stub
return realpart;
}
@Override
public String toString() {
// TODO Auto-generated method stub
String r, i;
//确定实部是整数还是小数
if(DecimalNumber.isInt(realpart))
r = ((int)realpart) + "";
else
r = realpart + "";
//确定虚部是整数还是小数
if(!DecimalNumber.isInt(imaginarypart))
i = imaginarypart + "";
else if((int)imaginarypart == 0)
i = "";
else
i = (int)imaginarypart + "";
if(i.length() == 0)
return r;
else if(r.equals("0"))
return i + "i";
else if(i.charAt(0)!='-')
return r + " + " + i + "i";
else
return r + " - " + i.substring(1) + "i";
}
private double realpart = 0;
private double imaginarypart = 0;
}Top
17 楼ferreousbox()回复于 2006-10-30 11:13:59 得分 0
这个应该比较好说啊~
首先定义一个抽象类,该类中有各种计算和的方法,比如整数相加、浮点数相加、整数和浮点数相加、复数相加等等
然后写个类继承它不就可以了,分别实现各个方法。对于复数可以定义一个复数类,然后再实现相加就ok了~~~Top
18 楼wunan320()回复于 2006-10-30 11:33:53 得分 0
思想上不算复杂 不过实现起来可能很累人 慢慢些吧Top
19 楼andycpp(幻瞳)回复于 2006-10-30 11:38:43 得分 0
小数类
public class DecimalNumber extends MyNumber {
public DecimalNumber(double a) {
value = a;
}
@Override
public MyNumber add(MyNumber n) {
// TODO Auto-generated method stub
if(n==null)
return null;
if(n instanceof ComplexNumber)
return n.add(this);
else {
double x = value + n.getRealpart();
if( isInt(x) )
return new IntegerNumber((int)x);
else
return new DecimalNumber(x);
}
}
@Override
public double getImaginarypart() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double getRealpart() {
// TODO Auto-generated method stub
return value;
}
/**
* 判断一个浮点数是否为一个整数,精度为0.0001
* @param x - 浮点数
* @return 若是整数返回true
*/
public static boolean isInt(double x) {
if(Math.abs(x)-Math.abs((int)x)>0.0001)
return false;
else
return true;
}
@Override
public String toString() {
// TODO Auto-generated method stub
String result;
if(isInt(value))
result = ((int)value) + "";
else
result = value + "";
return result;
}
private double value=0;
}
Top
20 楼andycpp(幻瞳)回复于 2006-10-30 11:39:07 得分 0
分数类
public class FractionNumber extends MyNumber {
/**
* 构造一个分数
* @param a - 分子
* @param b - 分母
*/
public FractionNumber(int a, int b) {
int divisor = getMaxDivisor(a, b);
numerator = a/Math.abs(divisor);
denominator = b/Math.abs(divisor);
}
@Override
public MyNumber add(MyNumber n) {
// TODO Auto-generated method stub
if(n==null)
return null;
if( (n instanceof ComplexNumber) || (n instanceof DecimalNumber))
return n.add(this);
else if(n instanceof IntegerNumber)
return new FractionNumber((int)n.getRealpart()*denominator+numerator, denominator);
else{
int a = ((FractionNumber)n).getNumerator();
int b = ((FractionNumber)n).getDenominator();
int num = a*denominator + b*numerator;
int den = b*denominator;
return new FractionNumber(num, den);
}
}
@Override
public double getImaginarypart() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double getRealpart() {
// TODO Auto-generated method stub
return (double)numerator/(double)denominator;
}
@Override
public String toString() {
if(denominator==1)
return numerator + "";
else
return numerator + "/" + denominator;
}
public int getNumerator() {
return numerator;
}
public int getDenominator() {
return denominator;
}
private int getMaxDivisor(int a, int b) {
int temp;
while( (temp = a % b) != 0 ) {
a = b;
b = temp;
}
return b;
}
private int numerator = 0;
private int denominator = 1;
}
Top
21 楼andycpp(幻瞳)回复于 2006-10-30 11:40:53 得分 0
整数类和工厂类:
整数类
public class IntegerNumber extends MyNumber {
public IntegerNumber(int a) {
value = a;
}
@Override
public MyNumber add(MyNumber n) {
// TODO Auto-generated method stub
if(n==null)
return null;
return n.add(this);
}
@Override
public double getImaginarypart() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double getRealpart() {
// TODO Auto-generated method stub
return value;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return value + "";
}
int value = 0;
}
工厂类
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NumberFactory {
public static MyNumber createNumber(String s) {
//去掉所有空格
/* Pattern p1 = Pattern.compile("\\s+");
Matcher m = p1.matcher(s);
String s1 = m.replaceAll("");*/
Matcher m;
String s1 = s.replaceAll("\\s+", "");
Pattern integerPattern = Pattern.compile("[+-]?\\d+");
m = integerPattern.matcher(s1);
if(m.matches()){
String s2;
s2 = (s1.charAt(0) == '+' ? s1.substring(1) : s1);
return new IntegerNumber(Integer.parseInt(s2));
}
Pattern decimalPattern = Pattern.compile("[+-]?\\d+\\.\\d+");
m = decimalPattern.matcher(s1);
if(m.matches())
return new DecimalNumber(Double.parseDouble(s1));
Pattern fractionPattern = Pattern.compile("([+-]?\\d+)/([1-9]\\d*)");
m = fractionPattern.matcher(s1);
if(m.matches()){
String q1 = m.group(1);
q1 = q1.charAt(0) == '+' ? q1.substring(1) : q1;
return new FractionNumber(Integer.parseInt(q1), Integer.parseInt(m.group(2)));
}
Pattern complexPattern = Pattern.compile("([+-]?\\d+(\\.\\d+)?)?([+-]?\\d+(\\.\\d+)?i)");
m = complexPattern.matcher(s1);
if(m.matches()){
Pattern iord = Pattern.compile("[+-]?\\d+(\\.\\d+)?");
m = iord.matcher(s1);
double[] a = {0, 0};
int i=0;
String ss;
while(m.find()) {
ss = s1.substring(m.start(), m.end());
a[i++] = Double.parseDouble((ss = ss.indexOf(0) == '+' ? ss.substring(1, ss.length()) : ss));
}
if(i==1)
return new ComplexNumber(0, a[0]);
else
return new ComplexNumber(a[0], a[1]);
}
// return new ComplexNumber(Double.parseDouble(m.group(1)), Double.parseDouble(m.group(3)));
return null;
}
}
Top
22 楼lzmhehe(小飞飞)回复于 2006-10-30 12:57:35 得分 0
工厂模式
与策略模式搭配使用
利用多态不会复杂Top
23 楼hdhmail2000(禅剑飞雪)回复于 2006-10-30 13:48:17 得分 0
我做的分数和整数部分:
/*
* Sum.java
* 抽象加法,需要其他的在这里加抽象方法
*/
abstract class Sum
{
public abstract int add(int n1,int n2);
public abstract Fraction add(Fraction n1,Fraction n2);
}Top
24 楼hdhmail2000(禅剑飞雪)回复于 2006-10-30 13:49:03 得分 0
/*
* Fraction.java
* 分数bean
*/
public class Fraction
{
private int fenzi;
private int fenmu;
public Fraction(String fenshu)
{
int line=fenshu.indexOf("/");
if(line==0)
{
this.fenzi=Integer.parseInt(fenshu);
this.fenmu=1;
}
else
{
this.fenzi=Integer.parseInt(fenshu.substring(0,line));
this.fenmu=Integer.parseInt(fenshu.substring(line+1));
}
int min=this.fenzi<this.fenmu?this.fenzi:this.fenmu;
int ok=1;
for(int i=min;i>1;i--)
{
if(this.fenzi%i==0&&this.fenmu%i==0)
{
ok=i;
break;
}
}
this.fenzi/=ok;
this.fenmu/=ok;
}
public int getFenmu() {
return fenmu;
}
public void setFenmu(int fenmu) {
this.fenmu = fenmu;
}
public int getFenzi() {
return fenzi;
}
public void setFenzi(int fenzi) {
this.fenzi = fenzi;
}
public String toString()
{
return String.valueOf(this.fenzi)+"/"+String.valueOf(this.fenmu);
}
public static void main(String[] args)
{
Fraction fenshu1=new Fraction("3/6");
System.out.println(fenshu1.fenzi);
System.out.println(fenshu1.fenmu);
System.out.println("/".indexOf("/"));
}
}
Top
25 楼hdhmail2000(禅剑飞雪)回复于 2006-10-30 13:49:31 得分 0
/*
* SumNumber.java
* 具体实现
*/
public class SumNumber extends Sum
{
public int add(int a,int b)
{
return a+b;
}
public Fraction add(Fraction a,Fraction b)
{
int tempFenzi= (a.getFenzi()*b.getFenmu()+b.getFenzi()*a.getFenmu());
int tempFenmu=a.getFenmu()*b.getFenmu();
int min=tempFenzi<tempFenmu?tempFenzi:tempFenmu;
int ok=1;
for(int i=min;i>1;i--)
{
if(tempFenzi%i==0&&tempFenmu%i==0)
{
ok=i;
break;
}
}
String tempFenshu=String.valueOf(tempFenzi/ok)+"/"+String.valueOf(tempFenmu/ok);
return new Fraction(tempFenshu);
}
public static void main(String[] args)
{
System.out.println(new SumNumber().add(new Fraction("1/7"),new Fraction("5/6")));
}
}
Top
26 楼vtudiv(v徒弟v)回复于 2006-10-30 22:07:26 得分 0
都是高手啊,不过没有运算符重载的语法确实有点变态~~~Top
27 楼Eleve(没头脑&不高兴)回复于 2006-10-31 00:58:58 得分 0
牛人!~Top
28 楼shiliangdong(Stou)回复于 2006-10-31 08:17:17 得分 0
學習.Top
29 楼asmetoyou()回复于 2006-10-31 10:51:21 得分 0
多态……Top
30 楼hdhmail2000(禅剑飞雪)回复于 2006-10-31 11:46:49 得分 0
补充main()函数判断数据类型:
public static void main(String[] args)
{
if(args.length==2)
{
if((args[0].indexOf("/")>0)&&(args[1].indexOf("/")>0))
{
System.out.println(new SumNumber().add(new Fraction(args[0]),new Fraction(args[1])));
}
if((args[0].indexOf(".")>0)&&(args[1].indexOf(".")>0))
{
//小数相加
}
if((args[0].indexOf("i")>=0)&&(args[1].indexOf("i")>=0))
{
//复数相加
}
//........................................................
}
else
{
System.out.println("Usage: java SumNumber number1 number2");
System.out.println("Example: java SumNumber 1/3 5/6");
}
}Top
31 楼10yue(无名)回复于 2006-10-31 12:27:55 得分 0
mark一下,有空试试。Top
32 楼twenty_three(god is a girl)回复于 2006-10-31 13:44:19 得分 0
markTop
33 楼lovelycatty(傻猫咪咪)回复于 2006-11-03 10:54:23 得分 0
非常感谢andycpp(幻瞳)和hdhmail2000(禅剑飞雪),好像50分只能给一次哦~
我老师后来发现这个问题的严重性了……所以又给我们降了很多要求……Top
34 楼hdhmail2000(禅剑飞雪)回复于 2006-11-03 11:11:54 得分 0
godTop




