参与过"一个求和的算法,算法高手请进"
http://community.csdn.net/Expert/TopicView1.asp?id=5362401
会得到额外的分算法需求
  将分数 N/M (N,M为自然数)的形式,转换为小数表示
  小数循环部分用括号表示,例如:1/3=0.(3)输入分子和分母: N,M
输出字符串输出范例
1/3=.(3)
10/3=3.(3)
1/7=.(142857)
2/8=.25
1024/17=60.(2352941176470588)private string Calc(int N, int M)
{
    // TODO
}
private void button1_Click(object sender, EventArgs ce)
{
    Text = Calc(1, 3);
}

解决方案 »

  1.   

    static void Main(string[] args)
            {
                Console.Write(Calc(1024, 17));
                Console.Read();
            }        static private string Calc(int N, int M)
            {
                // TODO
                double a = (double)((double)N / (double)M);
                string[] t = a.ToString().Split('.');
                return t[0] + ".(" + t[1] + ")";
            }
      

  2.   

    Red_angelX(当你XX你会想起谁) 
    不对
      

  3.   

    关键还是精度问题。还有遇到e和Pai那怎么输出来,无限不循环。。肯定还会有精度的限制的
      

  4.   

    Math.中没有转换吗?直接写N/M得不出小数吗?如果要纯粹自己写算法,得要分析分析,但我觉得好象不大难嘛。
      

  5.   


    //前提:求分数n/m的小数表述。
    //尝试:
    string TestCoverte(int n,int m)
    {
      List<int> il=new List<int>();
      while(用户给的精度)
      {
         if(m>n){il.Add(0);}
         else
         {
            //todo:找出n*10落在m*x或(x+1)之间(0<x<10)
            il.Add(x);
         }
      }
      //调用 一个内部方法,(private的)接受List<int>对象,并逐个将之转化为char[]然后合成string就可以了。
    }
      

  6.   

    看了一下资料(等于复习小学数学).首先:
    第一步: 分解分母,找出因数,判断分数是否是化解成循环小数.如果是:还得区分(纯循环小数,和混循环小数(判断出不循环位数))
     
      第一步是有规则条款可尊循的.第二步:
        比较分子分母,如果分子小于分母,*10 结果字符串补0,再比较,乘10补0到分子大于分母,相除,值加入结果字符串.
       余数供再重复上面操作.同判断是否循环.如果是重复几次确认.
       如果是混循环小数,就扣除不循环部份再判断.修正: 分解分母,找出质数,以质数大小大体确定可能循环的小数位数.
    没考虑清楚.....提供参考.请参阅: 小学数学课程讲解
    http://www.wm360.cn/resource/070131/004.html
      

  7.   

    Math.里面有很多函数,您看有没有一个!!
      

  8.   

    回复: cancerser(都是混饭吃,记得要结帖)
    只有2和5为因子的分母是没有循环的. 其他情况都是有循环的.不含2和5因子的分母是纯循环的(循环从第一位开始)其他情况是混循环的.
      

  9.   

    关注一下,请大家帮忙看看这个100分的问题,网址:
    http://community.csdn.net/Expert/topic/5366/5366610.xml?temp=.5854761
      

  10.   

    private string Calc(int N, int M)
    {
        string Result = "";
        int vMod = N % M;
        N = N / M;
        if (N > 0)
            Result = N.ToString() + ".";
        else Result = ".";
        List<Point> vList = new List<Point>(); // 历史分子X,和当时返回值的位置Y
        while (vMod > 0)
        {
            vList.Add(new Point(vMod, Result.Length));
            int J = 0;
            while (vMod < M) 
            {
                vMod *= 10; 
                J++;
            }
            for (; J > 1; J--) Result += "0";
            N = vMod / M;
            vMod = vMod % M;
            Result += N.ToString();
            foreach(Point vPoint in vList)
                if (vPoint.X == vMod)
                    return Result.Insert(vPoint.Y, "(") + ")";
        }    return Result;
    }private void button1_Click(object sender, EventArgs ce)
    {
        Text = Calc(45, 56);
    }
      

  11.   

    cancerser(都是混饭吃,记得要结帖) ( ) 信誉:100    Blog  2007-2-28 14:39:32  得分: 0  
     
     
       
    算法到是不难,但谁能告诉我 我怎么确定他有循环还是没有循环呢?  
     
    ------------------
    抓住关键了
      

  12.   

    main(){
    if(!分母仅含2,5因素)
      找循环节();
    }找循环节()
    {
      扩展的除法(分子,分母,小数部分)   //循环节.length < 分母
      从小数部分第一个字节开始取字符串temp, 直到分母个数个字节结束(如果有的话)
      { if(分子 -  (temp * 分母  ) =  分子/(temp.length+1))
          找到temp为循环节
      }
    }扩展的除法(分子,分母,&小数部分)
    {
      divisor= 分子%分母
      小数部分=""
      while(i<分母)
      {  小数部分*=10
         小数部分+=divisor/分母
      }  
    }MARK下,吃饭回来写程序
      

  13.   

    using System;
    using System.Text;
    using System.Collections.Generic;class App
    {
        public static void Main()
        {
            Message m = new Message(1024, 17);
            Message n = new Message(888, 53);
            Console.WriteLine(m.ToString());
            //输出 1024/17=60.(2352941176470588)括号内循环
            Console.WriteLine(n.ToString());
            //输出 888/53=16.(7547169811320)括号内循环
            Console.Read();
        }}
    class Message
    {
        public int Beichushu;//被除数
        public int Chushu;// 除数
        private int Yushu;//当前余数
        private int Xiaoshuwei=0;//记录当前小数的数位
        private int Xunhuankaishiwei;//末了用来记录循环开始于哪一位
        private int Xunhuanjieshuwei;//末了用来记录循环结束于哪一位
        private List<int> YS = new List<int>();//余数集合
        private List<int> Shang = new List<int>();//商位数集合
        public Message(int Beichushu, int Chushu)
        {
            this.Beichushu = Beichushu;
            this.Chushu = Chushu;
            Yushu = Beichushu % Chushu;
            Xunhuanjieshuwei=GetXunhuanwei();
        }
        private int GetXunhuanwei()//计算出循环结束位
        {
            
            while (true)
            {
                if (Xiaoshuwei > Chushu) return -1;//如果小数位超过除数的数值,则表示无限不循环
                Yushu = Chu(Yushu, Chushu);
                if (Yushu == 0) return -2;//表示可以除得尽
                if (YS.IndexOf(Yushu) != -1)//得到了与前面相同的余数,表示循环
                {
                    Xunhuankaishiwei = YS.IndexOf(Yushu) + 1;
                    return Xiaoshuwei;
                }
                else
                {
                    YS.Add(Yushu);
                }
                Xiaoshuwei++;
                Yushu *= 10;//"余数补0"
            }
        }
        private int Chu(int a, int b)//除法,返回余数
        {
            int shang = a / b;
            Shang.Add(shang);
            return a % b;
        }
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("{0}/{1}={2}.", Beichushu, Chushu, Beichushu / Chushu);
            for (int i = 1; i < Shang.Count; i++)//添加小数部分
            {
                if (i == Xunhuankaishiwei) sb.Append("(");
                sb.Append(Shang[i]);
            }
            sb.Append(")括号内循环");
            return sb.ToString();
        }
    }
      

  14.   

    //1/18=.05(5)应该是:.0(5)
    //这个问题已经解决了private string Calc(int N, int M)
    {
        string Result = "";
        int vMod = N % M;
        N = N / M;
        if (N > 0)
            Result = N.ToString() + ".";
        else Result = ".";
        List<Point> vList = new List<Point>(); 
        while (vMod > 0)
        {
            int J = 0;
            while (vMod < M) 
            {
                vMod *= 10; 
                J++;
            }
            for (; J > 1; J--) Result += "0";
            N = vMod / M;
            vList.Add(new Point(vMod, Result.Length));
            Result += N.ToString();
            foreach (Point vPoint in vList)
                if (vPoint.X == vMod)
                    return Result.Insert(vPoint.Y, "(") + ")";
            vMod = vMod % M;
        }    return Result;
    }
      

  15.   

    ee365ee() ( ) 信誉:100    Blog  2007-2-28 16:04:39  得分: 0  
     
     
       
    他的要求是要算到出现遁环,但是如果出现圆周率那样的东西,又没有给出一个精度,玩完!
    期待高手出现--------------------------------------------------------------------------------
    有理数都是可以化为分数形式
    圆周率是无理数
    ---------------------------------------------------------------------------- cancerser(都是混饭吃,记得要结帖) ( ) 信誉:100    Blog  2007-2-28 14:39:32  得分: 0  
     
     
       
    算法到是不难,但谁能告诉我 我怎么确定他有循环还是没有循环呢?  
    ------------------------------------这个才是难题啊
      

  16.   

    因为我们要判断的只是2和5,所以有没有循环最简单的是int i = 分母;
    while(i 是 偶数)
    {
    i>>2;
    }
    while(i 最后一位是 5)
    {
    i\=5;
    }
    if (i==1)
    没有循环
    else
    有循环
      

  17.   

    上面错了,sorry, 应该是先把 分子和分母都约成最简以后再计算.像  3/30 这样的.....要约成 1/10.然后 
    i=10;
    while第一个完 i = 5
    while第2个完 i =1所以没有循环如果是
    1/15
    i=15
    while第一个完,没执行到,i还是15
    while第2个完 i是3
    所以有循环
      

  18.   

    //总算可以安心睡觉了,上边我优化过的代码还有问题
    function Calc(N, M: Integer): string;
    var
      vMod: Integer; // 除数和余数
      vList: array of TPoint; // X:分子 Y:插入"("位置
      I, J: Integer;
    begin
      vMod := N mod M;
      N := N div M;
      Result := IntToStr(N);
      if vMod > 0 then Result := Result + '.';
      while vMod > 0 do // 余数不为0
      begin
        J := 0; // 填充的0
        vMod := vMod * 10;
        while vMod < M do
        begin
          vMod := vMod * 10;
          Inc(J);
        end;
        for I := 0 to Length(vList) - 1 do
        begin
          if vList[I].X = vMod then // 出现循环,同样的分子出现
          begin
            Insert('(', Result, vList[I].Y + 1);
            Result := Result + ')';
            Exit;
          end;
        end;
        SetLength(vList, Length(vList) + 1);
        vList[Length(vList) - 1] := Point(vMod, Length(Result));    N := vMod div M;
        Result := Result + StringOfChar('0', J) + IntToStr(N);
        vMod := vMod mod M;
      end;
    end; { Calc }//------------------------------------------------------------private string Calc(int N, int M)
    {
        string Result = "";
        int vMod = N % M;
        N = N / M;
        Result = N.ToString();
        if (vMod > 0) Result += ".";
        List<Point> vList = new List<Point>(); // X分子,Y位置
        while (vMod > 0)
        {
            vMod *= 10;
            string T = "";
            while (vMod < M)
            {
                vMod *= 10;
                T += "0";
            }
            Result += T;
            foreach (Point vPoint in vList)
                if (vPoint.X == vMod)
                    return Result.Insert(vPoint.Y, "(") + ")";
            vList.Add(new Point(vMod, Result.Length));
            N = vMod / M;
            Result += N.ToString();
            vMod = vMod % M;
        }
        return Result;
    }结果正确的给50分
    有代码和思路的给5-10分
    剩下路过的平分
      

  19.   

    syeerzy能不能给个实现
    你也是睡得够晚的,赫赫
    谢谢参与
      

  20.   

    syeerzy(快乐永远*先天下之乐而乐*后天下之忧而忧*) ( ) 信誉:95    Blog  2007-03-01 01:12:01  得分: 0  
     
     
       把分数约简已经有现成的计算机通用算法"辗转相减移位法", 在程序员杂志上有了, 只用到减法和移位等运算,连乘除都不需要.
      
     
    哦 谢谢哈
      

  21.   

    private String calc(int m, int n) 
    {
    ArrayList num = new ArrayList();
    int x = m / n; m = m % n;
    StringBuilder buff = new StringBuilder();
    while(m != 0 && !num.Contains(m)) 
    {
    num.Add(m);
    buff.Append(m * 10 / n);
    m = m * 10 % n; 
    }
    if(m != 0) 
    return x + ".(" + buff.ToString() + ")";
    else
    return x + "." + buff.ToString();
    }
      

  22.   

    错了,忘记计算从哪位开始循环了private String calc(int m, int n) 
    {
    ArrayList num = new ArrayList();
    int x = m / n; m = m % n;
    StringBuilder buff = new StringBuilder();
    while(m != 0 && !num.Contains(m)) 
    {
    num.Add(m);
    buff.Append(m * 10 / n);
    m = m * 10 % n; 
    }
    if(m != 0) 
    {
    int index = num.IndexOf(m);
    return x + "." + buff.ToString().Substring(0, index) + "(" + buff.ToString().Substring(index) + ")";

    else
    return x + "." + buff.ToString();
    }
      

  23.   

    ChDw(米)的方法也可以,但有bug,没有考虑17/28=0.60(714285)的情况
    你得到的结果是:17,28=0.(60714285)先结了
      

  24.   

    ChDw(米)最后给的代码是正确的
      

  25.   

    数学哪……大家怎么学的呀……
    说原周率和自然底数e是无理数的,站出来,补一补数学。什么是超越数? 
    如果一个实数满足形式如anx n+a(n-1)x (n-1)+a(n-2)x (n-2)+~~+a2x 2+a1x+a0=0的整数系数的代数方程,其中N自然数。an,a(n-1),a(n-2),--,a2,a1,a0都是整数,an<>0,那么,这个实数就称作代数数。在实数中除了代数数外,其余的都是超越数。 
    超越数的存在是由法国数学家柳维尔在1851年最早证明的。关于超数的存在,柳维尔写出了下面这样一个无限小数。a=0.11000100000000000000000100--,并且证明取这个a不可能满足上面所列出的整数系数方程,由此证明了它不是一个代数数,而是一个超越数。后来人们为了纪念他首次证明了超越数,所以把数A称为柳维尔数 
    柳维尔数证明手,许多数学家都致力于对超越数的研究。1873年,严肃埃尔米特又证明了自然对数底E的超越性,从而使人们对超越数的认识更为清楚。1882年,德国数学家林德曼证明了圆周率也是一个超越数。这样,实数就可以按下面的方法来分类: 
    实数 
    || 
    代数数超越数 
    || 
    有理数无理数 
    超越数的证明,给数学带来了大的变革,解决了几千年来数学上的难题--几何三大问题,即倍立方问题、三等分角问题和化方为圆问题。
      

  26.   

    public class fenshu {
    public static int N =1000;
    int left[]=new int[N];
    int dight[]=new int[N];
    int q,top,n,d,ii;
    fenshu(int n1,int d1){
    n=n1;
    d=d1;
    }
    void work(){
    while(left[top]!=0){
    top++;
    left[top]=(left[top-1]*10)%d;
    dight[top]=(left[top-1]*10)/d;

    for(int i=0;i<top;i++){
    if(left[top]==left[i]){
    ii=i;
    q=top+1;
    return;
    }
    }

    }
    }
     void init(){ 
    left[0]=n%d;
    dight[0]=n/d;
    top=0;
    q=0;
    }
     void print(){
     System.out.print("n/d=");
     if(dight[0]!=0){
     System.out.print(dight[0]);
     }else{
     System.out.print(n/d);
     }
     
     if(top>0){
     System.out.print(".");
     if(ii!=0){
     for(int i=1;i<=ii;i++){
     System.out.print(dight[i]);
     }
     }
     if(q>0){
     System.out.print("(");
     for(int i=ii+1;i<q;i++)
     System.out.print(dight[i]);
     System.out.print(")");
     }else{
     for(int i=1;i<top;i++)
     System.out.print(dight[i]);
     }
     }
     }
     public static void main(String[] args) {
    fenshu fen=new fenshu(1,15);
    fen.init();
    fen.work();
    fen.print();
    }
    }
      

  27.   

    用C语言写的:#include<stdio.h> 
    #define max 100  
    int y[max]; 
    int s[max];  
    int N,D,a,b;  xhj()  

    int i=0,j=1; 
    s[0]=N/D;y[0]=N%D;  
    b=0;a=0;  
    while(y[b]!=0&&j==1&&b<max) 

    b++;  
    s[b]=(y[b-1]*10)/D;  
    y[b]=(y[b-1]*10)%D;  for(i=0;i<=b-1;i++) 

    if(y[b]==y[i])  

    a=i+1; 
    j=0; 
    break; 
    } } 


    main()  

    int i; 
    printf("ENTER N,D:"); 
    scanf("%d %d",&N,&D); 
    xhj(); 
    printf("%d/%d=",N,D); 
    if(s[0]!=0) printf("%d",s[0]); 
    if(b>0) printf("."); 
    for(i=1;i<=b;i++) 

    if(i==a) printf("("); 
    printf("%d",s[i]); 

    if(a>0) printf(")"); 
    printf("\n");