黑马程序员技术交流社区

标题: 怎么计算一个分数序列的和? [打印本页]

作者: 张世威    时间: 2012-7-21 23:58
标题: 怎么计算一个分数序列的和?
本帖最后由 张世威 于 2012-7-22 15:51 编辑

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

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



作者: 黑马振鹏    时间: 2012-7-22 00:10
有意思,计算机和数学相结合的好题啊 呵呵
作者: 383105662    时间: 2012-7-22 00:41
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
作者: 朱东方    时间: 2012-7-22 00:48
//有一分数序列: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

作者: 朱东方    时间: 2012-7-22 00:48
//有一分数序列: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

作者: 李伟    时间: 2012-7-22 02:01
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项数列的和。
                }
        }
}

作者: 张莹莹    时间: 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中
4.思路在项目注释中

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

计算类上半部分

计算类上半部分

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

计算类下半部分

计算类下半部分

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

分数类

分数类

Java.rar

3.84 KB, 下载次数: 250

项目文件


作者: 张莹莹    时间: 2012-7-22 02:10
张莹莹 发表于 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中

结果是163/60,忘记贴了
作者: 尹善波    时间: 2012-7-22 02:29

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 03:04
正确答案:
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;
        }
}
作者: 郭凯敏    时间: 2012-7-22 05:36
本帖最后由 郭凯敏 于 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 15:38
张莹莹 发表于 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中

果然需要用一个分数类来解决问题呀,哈哈:handshake
作者: 张世威    时间: 2012-7-22 15:54
韦念欣 发表于 2012-7-22 03:04
正确答案:
public class Demo
{

用double类型计算,最后结果就不准确了,
作者: 张世威    时间: 2012-7-22 16:02
张世威 发表于 2012-7-22 15:54
用double类型计算,最后结果就不准确了,

不管怎么换,哪些基本的数据类型是无法表示出一个无理数的,我觉得通过一个分数类比较好
作者: 黑马罗坚    时间: 2012-7-22 17:54
  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

作者: 张莹莹    时间: 2012-7-22 18:24
张莹莹 发表于 2012-7-22 02:05
1.计算类见Calc1.png和Calc2.png
2.分数类见fs.png
3.项目文件在附件中

结果算得不对,我只累加了5项,改过来就可以了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2