免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3231 | 回复: 7
打印 上一主题 下一主题

[C] [20分求解答]求解此问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-03 22:13 |只看该作者 |倒序浏览
20可用积分
本帖最后由 CU达人 于 2011-11-03 22:22 编辑

请问如何使用C来解决这样的问题:


1/2= 0.5
1/3= 0.(3)
1/4= 0.25
1/5= 0.2
1/6= 0.1(6)
1/7= 0.(142857)
1/8= 0.125
1/9= 0.(1)
1/10= 0.1


比如1/7=0.(142857)就是说()里面的是个循环体,
分子是1, 分母是1到1000

请教各位达人,谢谢....

最佳答案

查看完整内容

本帖最后由 nketc 于 2011-11-04 09:25 编辑 (看6楼OW,这儿和上面的不对,想改改来,OW都贴出来了,俺保留自己错误吧。)胡乱写的,vim里排版挺好的。 语言学家请直走。(语言学家说用链表。能给链个不?)俺自爆吧:1)用goto了2)变量命名不好3)没用链表(realloc行不)4)。。。下面是改进版:

论坛徽章:
5
技术图书徽章
日期:2013-11-07 13:21:58技术图书徽章
日期:2013-12-07 10:34:46技术图书徽章
日期:2014-04-23 08:50:31双鱼座
日期:2014-09-16 09:12:34亥猪
日期:2015-01-23 13:37:49
2 [报告]
发表于 2011-11-03 22:13 |只看该作者
本帖最后由 nketc 于 2011-11-04 09:25 编辑

(看6楼OW,这儿和上面的不对,想改改来,OW都贴出来了,俺保留自己错误吧。)
胡乱写的,vim里排版挺好的。 语言学家请直走。(语言学家说用链表。能给链个不?)
俺自爆吧:
1)用goto了
2)变量命名不好
3)没用链表(realloc行不)
4)。。。

下面是改进版:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main(int argc, char *argv[]) {
  4.     int  i  = 0, s = 0, t  = 1, n, r, k;
  5.     int *d  = NULL;
  6.     int  c  = 100;

  7.     n = atoi(argv[1]);
  8.     d = malloc(c * sizeof(int));

  9.     do {
  10.         if (i + 1 >= c) {
  11.             c += i;
  12.             d = realloc(d, c * sizeof(int));
  13.         }
  14.         while(t < n) {
  15.             t *= 10;
  16.             d[++i] = 0;
  17.         }
  18.         while (t >= n) {
  19.             t -= n;
  20.             d[i] += 1;
  21.         }
  22.         if (t == 0) break;
  23.         if (s == t) {
  24.             if (d[i] == d[r]) break;
  25.             else r = i;
  26.         }
  27.         if (s == 0) {
  28.             s = t;
  29.             r = i;
  30.         }
  31.     }while(1);

  32.     if (t == 0) r = ++i;
  33.     printf("1/%d=0.", n);
  34.     for(k=1; k<i; k++) {
  35.         if (k == r) printf("(");
  36.         printf("%d", d[k]);
  37.     }
  38.     if (t != 0) printf(")");
  39.     printf("\n");

  40.     free(d);
  41.     return 0;
  42. }
复制代码

论坛徽章:
5
技术图书徽章
日期:2013-11-07 13:21:58技术图书徽章
日期:2013-12-07 10:34:46技术图书徽章
日期:2014-04-23 08:50:31双鱼座
日期:2014-09-16 09:12:34亥猪
日期:2015-01-23 13:37:49
3 [报告]
发表于 2011-11-03 23:50 |只看该作者
  1. int main(int argc, char *argv[]) {
  2. int i;
  3. int d[100];
  4. int t;
  5. int n;
  6. int k;
  7. int w[100];
  8. int wi;

  9. n = atoi(argv[1]);

  10. wi= 0;
  11. i = 0;
  12. t = 1;
  13. do {
  14.     while(t < n) {
  15.         t *= 10;
  16.                 d[++i] = 0;
  17.         }
  18.     while (t >= n) {
  19.             t -= n;
  20.                 d[i] += 1;
  21.         }
  22.     for (k=0; k<wi; k++) {
  23.             if (w[k] == t) goto out;
  24.         }
  25.         w[wi++] = t;
  26. }while(t != 0);

  27. out:
  28. if (t == 0) printf("1/%d=0.", n);
  29. else printf("1/%d=0.(", n);
  30. for(k=1; k<=i; k++) {
  31.     printf("%d", d[k]);
  32. }
  33. if (t != 0) printf(")");
  34. printf("\n");

  35. return 0;
  36. }

复制代码

论坛徽章:
5
技术图书徽章
日期:2013-11-07 13:21:58技术图书徽章
日期:2013-12-07 10:34:46技术图书徽章
日期:2014-04-23 08:50:31双鱼座
日期:2014-09-16 09:12:34亥猪
日期:2015-01-23 13:37:49
4 [报告]
发表于 2011-11-03 23:53 |只看该作者
楼主给分。我真是闲的d疼。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
5 [报告]
发表于 2011-11-04 00:17 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
6 [报告]
发表于 2011-11-04 08:37 |只看该作者
回复 1# CU达人

1. 循环节一定存在
相同余数会产生相同后续序列,而余数的取值范围是有限的: [0,分母) 。
一位一位取就是了……
直到遇见相同余数,或余数为0。

2. 有尽小数
只要除数的质因子中只有2与5,就能除尽。
可通过这个判断是否需要"()"记号。

3. 进制
虽然最终是按十进制输出,但内部进制不一定必须是十进制或字符。
内部进制大一些可以减少一些计算, 输出时注意 leading 与 tailing 零就行。
只是对本例子来说作用不明显, 还会加大找循环节的难度……
所以代码中只对有尽小数使用……

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int terminating_decimal(int divisor)
  4. {
  5.       while (divisor%2u==0) divisor/=2u;
  6.       while (divisor%5u==0) divisor/=5u;
  7.       return divisor==1;
  8. }

  9. int main(int argc, char* argv[])
  10. {
  11.       int dividend,divisor,remainder;

  12.       dividend = argc>1? atoi(argv[1]): 1;
  13.       divisor = argc>2? atoi(argv[2]): 1;
  14.       if (dividend<0 || divisor<=0) {
  15.             fprintf(stderr, "for simplification supports positive only\n" );
  16.             return EXIT_FAILURE;
  17.       }

  18.       printf("%d", dividend/divisor);
  19.       remainder = dividend%divisor;
  20.       if (!remainder)
  21.             return 0;
  22.       printf(".");

  23.       if (!terminating_decimal(divisor))
  24.       {
  25.             char* digits = (char*)malloc(divisor);
  26.             int i = 0, j;
  27.             int* met = (int*)calloc(divisor,sizeof(int));

  28.             do {
  29.                   int dividend = remainder*10u;
  30.                   int quotient = dividend/divisor;
  31.                   digits[i] = quotient+'0';
  32.                   met[remainder] = ++i;
  33.                   remainder = dividend % divisor;
  34.             } while (!met[remainder]);

  35.             j = met[remainder]-1;
  36.             printf("%.*s(%.*s)", j, digits, i-j, digits+j);

  37.             free(met);
  38.             free(digits);
  39.       }
  40.       else
  41.       {
  42. #define RADIX 100u
  43. #define EXPONENT 2
  44. #define STR(x) STR_(x)
  45. #define STR_(x) #x

  46.             int quotient,i;

  47.             for (; dividend = remainder*RADIX
  48.                  , quotient = dividend/divisor
  49.                  , remainder = dividend%divisor
  50.                  , remainder
  51.                  ; printf("%0" STR(EXPONENT) "d", quotient) ) ;

  52.             for (i=RADIX/10; quotient; quotient%=i, i/=10u)
  53.                   putchar(quotient/i+'0');
  54.       }

  55.       printf("\n");
  56.       return 0;
  57. }
复制代码
最后附加一份测试代码

  1. #!/usr/bin/env python

  2. import sys
  3. import re
  4. from fractions import Fraction

  5. p = re.compile(r'[ ]*([0-9]*)\.?([0-9]*)(\(([0-9]*)\))?')
  6. for line in sys.stdin :
  7.     m = p.match(line)
  8.     i,f,_,r = m.groups()
  9.     w = 10**len(f)
  10.     result = (int(i) if i else 0) \
  11.            + (Fraction(int(f),w) if f else 0) \
  12.            + (Fraction(int(r),10**len(r)-1)/w if r else 0)
  13.     expect = line[m.end():].strip()
  14.     expect = Fraction(expect) if expect else result
  15.     print line[:m.end()],result
  16.     if expect!=result : print >>sys.stderr, line[:m.end()],expect,result
复制代码

  1. for ((i=1;i<=1212;++i)) do echo $(fraction2decimal 1 $i) 1/$i; done | decimal2fraction.py >/dev/null
复制代码

论坛徽章:
0
7 [报告]
发表于 2011-11-05 16:23 |只看该作者
回复 4# nketc


   谢谢各位的解答

论坛徽章:
5
技术图书徽章
日期:2013-11-07 13:21:58技术图书徽章
日期:2013-12-07 10:34:46技术图书徽章
日期:2014-04-23 08:50:31双鱼座
日期:2014-09-16 09:12:34亥猪
日期:2015-01-23 13:37:49
8 [报告]
发表于 2011-11-05 17:53 |只看该作者
回复 1# CU达人


    楼主还没测试吧,我这个是有问题的。6楼,OW的才是正确的。
----------------------
ps 怎么把分还给你?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP