A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张世威 中级黑马   /  2012-7-21 23:58  /  4333 人查看  /  15 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张世威 于 2012-7-22 15:51 编辑

有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和,
请用分数形式输出最后的结果,如  x/y  

           补充:如果javaAPI里面有分数计算的类就好了,不然直接就可以拿来用了。谁知不知道有不有第三方的Java分数计算的api呀,我想看看是怎么计算分数的。


点评

正确答案在10楼  发表于 2012-7-22 03:05

15 个回复

正序浏览
张莹莹 发表于 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中

结果算得不对,我只累加了5项,改过来就可以了
回复 使用道具 举报
  1. import java.math.BigDecimal;


  2. public class FenShuSan {
  3.         /**
  4.          * 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和,请用分数形式输出最后的结果,如  x/y
  5.          *
  6.          * 递归解决  参数3个int型的变量 除数 被除数 循环次数    当count==1时退出
  7.          */
  8.         public static void main(String[] args) {
  9.                 System.out.println("\n和为:"+new FenShuSan().getSum(2.0, 1, 20));
  10.                 System.out.println("\n和为:"+new FenShuSan().getSum(2, 1, 20));
  11.         }
  12.         /**
  13.          * @param divisor
  14.          * @param divident
  15.          * @param count
  16.          * @return
  17.          * 根据 count个分数的和
  18.          * 拿传过来的分数的商加上以后所有可能出现的商
  19.          */
  20.         private double getSum(double divisor,double divident,int count){
  21.                 System.out.println((int)divisor+"/"+(int)divident);
  22.                 if(count==1){
  23.                         return divisor/divident;
  24.                 }
  25.                 double result=divisor/divident;
  26.                 double tmp=divisor;
  27.                 divisor+=divident;
  28.                 divident=tmp;
  29.                 return result+(getSum(divisor,divident,--count));
  30.         }
  31.        
  32.         /**
  33.          * @param divisor
  34.          * @param divident
  35.          * @param count
  36.          * @return
  37.          * 算出count个分数中分子和分母的和
  38.          * 拿传过来的分子和分母分别加上以后所有可能出现的分子和分母的和
  39.          */
  40.         private String getSum(int divisor,int divident,int count){
  41.                 System.out.println(divisor+"/"+divident);
  42.                 if(count==1){
  43.                         return divisor+"/"+divident;
  44.                 }
  45.                 int tmp=divisor;
  46.                 divisor+=divident;
  47.                 divident=tmp;
  48.                 String[] sums=getSum(divisor,divident,--count).split("/");
  49.                 return tmp+Integer.parseInt(sums[0])+"/"+(divisor-divident+Integer.parseInt(sums[1]));
  50.         }
  51.        
  52. }
复制代码
运行结果
2/1
3/2
5/3
8/5
13/8
21/13
34/21
55/34
89/55
144/89
233/144
377/233
610/377
987/610
1597/987
2584/1597
4181/2584
6765/4181
10946/6765
17711/10946

和为:32.660260798641644
2/1
3/2
5/3
8/5
13/8
21/13
34/21
55/34
89/55
144/89
233/144
377/233
610/377
987/610
1597/987
2584/1597
4181/2584
6765/4181
10946/6765
17711/10946

和为:46365/28655

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
张世威 发表于 2012-7-22 15:54
用double类型计算,最后结果就不准确了,

不管怎么换,哪些基本的数据类型是无法表示出一个无理数的,我觉得通过一个分数类比较好
回复 使用道具 举报
韦念欣 发表于 2012-7-22 03:04
正确答案:
public class Demo
{

用double类型计算,最后结果就不准确了,

点评

换成BigDecimal就可以了。  发表于 2012-7-22 16:00
回复 使用道具 举报
张莹莹 发表于 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中

果然需要用一个分数类来解决问题呀,哈哈:handshake
回复 使用道具 举报
本帖最后由 郭凯敏 于 2012-7-22 05:38 编辑
韦念欣 发表于 2012-7-22 03:04
正确答案:
public class Demo
{

老大我觉得你那个有点脱离需求,所以改了一下,把你的简化修改了下....没啥技术,还是用的你的思路.....你加分我不会介意的,不加分我会介意的.....
public class Demo
{
        public static void main(String[] args)
        {
               Demo.Sum(20);
        }

       public static void Sum(int n){
                int a=2, b=1, tmp;
                int sumA=a;
                int sumB=b;
                for (int i=1; i<n; i++){
                        tmp = a;
                        a += b;
                        b = tmp;
                        sumA+=a;
                        sumB+=b;
                        String str=new String(sumA+"/"+sumB);
                        System.out.println(str);
                }
        }
}

点评

拜托,你这样改已经不符合楼主需求了。  发表于 2012-7-22 10:43
回复 使用道具 举报
正确答案:
public class Demo
{
        public static void main(String[] args)
        {
                System.out.println("sum="+Sum(20));
        }

        public static double Sum(int n){
                double a=2.0, b=1.0, tmp;
                double sum = a/b;
                for (int i=1; i<n; i++){
                        tmp = a;
                        a += b;
                        b = tmp;
                        sum += (a/b);
                                System.out.println(a+"/"+b+"="+a/b);
                }
                return sum;
        }
}
回复 使用道具 举报

class He
{
public static void main(String[] args)
{
    fenshu();
}
public static void fenshu()
{
     double x=2.0;
     double y=1.0;   
     double r;
   double[]fz=new double[5];//创建长度为5的分子数组
   double[]fm=new double[5];//创建长度为5的分母数组
   for (int i=0;i<5 ;i++ )//给前5个分数的分子、分母赋值
   {
      if(i==0)
        {
       fz[i]=x;
       fm[i]=y;
     }
            else if(i!=0)
     {   
        r=y;
        y=x;
     x=y+r;
     fz[i]=x;
     fm[i]=y;           
     }               
   }
   double Fm=fm[0]*fm[1]*fm[2]*fm[3]*fm[4];//所有分数的分母的乘积做为分数相加后的分母。

   double Fz=(fz[0]*fm[1]*fm[2]*fm[3]*fm[4])+(fz[1]*fm[0]*fm[2]*fm[3]*fm[4])+
              (fz[2]*fm[1]*fm[0]*fm[3]*fm[4])+(fz[3]*fm[0]*fm[2]*fm[1]*fm[4])+
     (fz[4]*fm[1]*fm[2]*fm[3]*fm[0]);//所有分数的分子和
  double min = Math.min(Fz, Fm);//在分子分母中选择较小的作为寻找公约数遍历的对象
        for(int t=2;t<=min;t++)
  {                                               
           if((Fz%t==0)&&(Fm%t==0))//如果该分数不是最简分数,即分子分母存在公约数
                               //则分子分母同时除以公约数,化简该分数。
      {
               Fz = Fz/t;
               Fm = Fm/t;
            }
        }
   System.out.println("分数和::"+Fz+"/"+Fm);
}
}
/*
观察该分数序列可以得到:第二个分数的分母为第一个分数的分子,而第二个分数的分子为第一个分数分子、分母的和;
于是定义一个临时对象r作为分子分母的变化的工具
由于二十个分数的分母、分子的公约数和公倍数实在太麻烦,就以前5个为例吧
*/
回复 使用道具 举报
张莹莹 发表于 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中

结果是163/60,忘记贴了
回复 使用道具 举报
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中
4.思路在项目注释中

Calc1.png (38.75 KB, 下载次数: 73)

计算类上半部分

计算类上半部分

Calc2.png (46.11 KB, 下载次数: 79)

计算类下半部分

计算类下半部分

fs.png (23.94 KB, 下载次数: 103)

分数类

分数类

Java.rar

3.84 KB, 下载次数: 256

项目文件

评分

参与人数 2技术分 +1 黑马币 +9 收起 理由
黑马张扬 + 1
张世威 + 9 很给力!

查看全部评分

回复 使用道具 举报
package cn.itcast.test;

public class Fenshu
{
        public static void main(String[] args)
        {
                long x=2,y=3,m=1,n=2;
                long p=x*n+y*m;
                long q=m*n;
                long z=0,d=0;
                for(int i=3;i<=20;i++)
                {
                        z=x+y;
                        d=m+n;
                        x=y;//前一个数的分子
                        y=z;//当前数的分子
                        m=n;//前一个数的分母
                        n=d;//当前数的分母
                        p=p*d+z*q;//前i项的序列和的分子
                        q=q*d;//前i项的序列和的分母
                        String sum=p+"/"+q;
                        System.out.println(x+"/"+m+","+y+"/"+n);
                        System.out.println(sum);//打印出前i项数列的和。
                }
        }
}

评分

参与人数 1黑马币 +3 收起 理由
张世威 + 3

查看全部评分

回复 使用道具 举报
//有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和,
//请用分数形式输出最后的结果,如  x/y  

class Test1
{
        public static void main(String[] args)
        {
                float  a=2 , b=1 ;
                float        sum=0 ; // 定义类型不要错了,要不结果就错了。int型就取整了。
                for(int x=1;x<=20;x++)
                {
                        sum += a/b ;
                        a += b;
                        b++;
                        System.out.println("前"+x+"项和:sum="+sum);
                }
               
        }
}

看明白这个就简单了:
第二个数的分子是第一个数分子和分母的和。
每个数的分母都递增1
回复 使用道具 举报
//有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和,
//请用分数形式输出最后的结果,如  x/y  

class Test1
{
        public static void main(String[] args)
        {
                float  a=2 , b=1 ;
                float        sum=0 ; // 定义类型不要错了,要不结果就错了。int型就取整了。
                for(int x=1;x<=20;x++)
                {
                        sum += a/b ;
                        a += b;
                        b++;
                        System.out.println("前"+x+"项和:sum="+sum);
                }
               
        }
}

看明白这个就简单了:
第二个数的分子是第一个数分子和分母的和。
每个数的分母都递增1
回复 使用道具 举报
package com.yydragon.ltjavatest.testmainfirst;

/**
* 编写一个java应用程序,求分数序列1/2,2/3,3/5,5/8,8/13,13/21,… 的前10项之和。
*
* @author Will
*
*/
public class TestClassTwo {
public static void main(String[] args) {
  long num1 = 1;     // 第一个分数的分子
  long den1 = 2;     // 第一个分数的分母
  long num2 = 2;     // 第一个分数的分子
  long den2 = 3;     // 第一个分数的分母
  
  // 先求得前两项之和
  System.out.print(num1 + "/" + den1 + " + " + num2 + "/" + den2);
  long[] rets = getSub(num1 * den2 + num2 * den1, den1 * den2);
  long numOfSum = rets[0];   // 最后求得的和的分子
  long denOfSum = rets[1];   // 最后求得的和的分母
  
  int interCount = 10; // 求前几项之和
  
  // 从第三项开始循环,求和
  for (int i = 2; i < interCount; i++) {
   long num3 = num1 + num2;
   long den3 = den1 + den2;
   System.out.print(" + " + num3 + "/" + den3);
   rets = getSub(num3 * denOfSum + numOfSum * den3, den3 * denOfSum);
   
   num1 = num2;
   den1 = den2;
   num2 = num3;
   den2 = den3;
  }
  
  System.out.println(" = " + numOfSum + "/" + denOfSum);
}

/**
  * 将两个数同时除以它们的最大公约数,将得到的商以数组形式返回。
  *
  * @param num
  * @param den
  * @return
  */
public static long[] getSub(long num, long den) {
  long maxCommonDivisor = getMaxCommonDivisor(num, den);
  long numret = num / maxCommonDivisor;
  long denret = den / maxCommonDivisor;
  
  return new long[]{numret, denret};
}

/**
  * 获取两个数的最大公约数。
  *
  * @param n1
  * @param n2
  * @return
  */
public static long getMaxCommonDivisor(long n1, long n2) {
  long result = 1;
  long maxer = Math.min(n1, n2);
  
  for (int i = 1; i < maxer; i++) {
   if (0==n1%i && 0==n2%i) {
    result = i;
   }
  }
  
  return result;
}
}


这是度娘来的!更详细的参考http://zhidao.baidu.com/question/58382324.html
回复 使用道具 举报
有意思,计算机和数学相结合的好题啊 呵呵
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马