分数化为有限小数或无限循环小数(c实现)

原创 2005年05月01日 05:19:00
问题描述:
将分数转化为小数,相信很多人都会吧.那么,这里给定一个分数N/D,N为分子,D为分母(N,D均为整数),试编程求出N/D的小数形式,当然如果这个小数为无限循环小数,则把循环的部分用括号括起来,接着循环的部分则省略不写。比如:
1/3    =0.(3)
22/5=4.4
1/7    =0.(142857)
2/2    =1.0
3/8    =0.375
45/56    =0.803(571428)
输入为两个正整数N,D(1 <= N,D <= 100000),输出为对应的小数(为了对齐格式,请一行最多输出76个字符)。
样例输入:
1 3
22 5
1 7
对应输出:
0.(3)
4.4
0.(142857)

============code===================
/**
*Copyright (C) aprin at Xiamen University
*2005-04-23
*/
#include <stdio.h>
#include <string.h>
#define LEN_SHANG sizeof(struct node_shang)
#define LEN_YUSHU sizeof(struct node_yushu)

struct node_shang {/*商结点*/
  char data;
  struct node_shang *next;
} *shang_head=0, *shang_tail=0;

struct node_yushu {/*余数结点*/
  long data;
  struct node_yushu *next;
} *yushu_head=0, *yushu_tail=0;


int shang_empty(void) {/*判断商串是否空*/
  return shang_head==0;
}
int yushu_empty(void) {/*判断余数串是否空*/
  return yushu_head==0;
}
struct node_shang *new_shang_node(char ch) {/*新建商的结点*/
  struct node_shang *ptr= (struct node_shang *) malloc(LEN_SHANG);
  ptr->data=ch;
  ptr->next=0;
  return ptr;
}
struct node_yushu *new_yushu_node(long a) {/*新建余数结点*/
  struct node_yushu *ptr= (struct node_yushu *) malloc(LEN_YUSHU);
  ptr->data= a;
  ptr->next=0;
  return ptr;
}
void insert_shang(char ch) {/*插入商字符串的结点*/
  struct node_shang *newptr= new_shang_node(ch);

  if(shang_empty())
    shang_head=shang_tail=newptr;
  else {
    shang_tail->next= newptr;
    shang_tail= newptr;
  }
}
void insert_yushu(long a) {/*插入余数结点*/
  struct node_yushu *newptr= new_yushu_node(a);

  if(yushu_empty())
    yushu_head=yushu_tail=newptr;
  else {
    yushu_tail->next= newptr;
    yushu_tail= newptr;
  }
}


char *longinttostr(long a, char *str) {/*将长整型转化为字符串*/
  char temp;
  int i, j;

  i=0;
  if(a==0) {/*a=0时特别处理*/
    str[0]='0';
    i++;
  } else {
    while(a!=0) {
      str[i]=(a%10)+'0';
      a=a/10;
      i++;
    }
  }
  str[i]='/0';
  for(j=0; j<=(i-1)/2; j++) {/*倒置*/
    temp= str[j];
    str[j]= str[i-1-j];
    str[i-1-j]= temp;
  }

  return str;/*返回长度*/
}

long found_xunhuan(void) {/*通过余数是否相等判断是否出现循环节,若出现返回出现位置的指针ind(相对小数点的偏移量),若无反回-1*/
  struct node_yushu *i;
  long ind;

  for(i=yushu_head, ind=0; i->next!=0; i=i->next, ind++)
    if(yushu_tail->data==i->data)
      return ind;
  if(i->next==0)
    return -1;
}

void div(long d, long n) {/*d是被除数,n是除数*/
  long yushu, shang_zhenshu, temp, i, len_temp;
  char str[7];
  struct node_shang *j, *new_node;

  /*计算整数部分*/
  shang_zhenshu= d/n;
  d=d%n;
  insert_yushu(d);/*余数保存到余数链表*/
  longinttostr(shang_zhenshu, str);
  i=0;
  while(str[i]!='/0') {/*商保存到商链表*/
    insert_shang(str[i]);
    i++;
  }
  insert_shang('.');
  if(d==0) {/*恰好整除的情况*/
    insert_shang('0');
    return;
  }
  while((d!=0)&&((temp=found_xunhuan())==-1)) {/*当除尽或发现循环节时停止*/
    d=d*10;/*进位*/
    insert_shang((d/n)+'0');
    insert_yushu(d%n);
    d=d%n;
  }
  /*除法已完成*/
  if(temp!=-1) {/*发现循环节*/
    j=shang_head;
    while(j->data!='.')/*找到小数点的位置*/
      j=j->next;
    for(i=0;i<temp; i++)
      j=j->next;/*找到循环节开始的前一位*/
    new_node= new_shang_node('(');
    new_node->next=j->next;
    j->next= new_node;
    new_node= new_shang_node(')');
    shang_tail->next= new_node;
    shang_tail= new_node;
  }
}

void output(void) {
  struct node_shang *i;
  long temp;

  i=shang_head;
  temp=0;
  while(i->next!=0) {
    putchar(i->data);
    i=i->next;
    temp++;
    if((temp%76)==0)/*每行输出76个字符*/
      putchar('/n');
  }
  putchar(shang_tail->data);
  putchar('/n');
}

int main(void) {
  long d, n;

  scanf("%ld %ld", &d, &n);
  while((d<1)||(d>100000)||(n<1)||(n>100000)) {
    printf("Input is wrong! Please inpute again!(1<=d, n<=100000)/n");
    scanf("%ld %ld", &d, &n);
  }
  div(d, n);
  output();

  return 0;
}

相关文章推荐

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

分数化小数

分类:   数据结构与算法(23)  版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[+] 《编程之美》有一个题是给定一个小...

计算-小数相加-无限循环小数转为分数

小数相加 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给你两个个小数,你能计算出它们的和是多少吗? 你肯定会说,so easy。 可是,如果这些小数中...
  • wximo
  • wximo
  • 2015年04月22日 14:55
  • 639

小数,无限循环小数化为分数

  • 2013年11月24日 10:02
  • 1KB
  • 下载

有限小数 解题报告

题目描述 小J是一个严谨的人,他只能接受有限小数,而总有些数令他不爽,比如0.33...。一天,他发现0.33…在3进制下可以写成0.1,在30进制下可以写成0.A等,于是他坚信所有有理数都可以写成...

hdu 1717 小数化分数2 循环小数,算数论题吧. 不是很难.

小数化分数2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S...

【循环小数性质】HDU 1717——小数化分数2

题目:点击打开链接 这个题是个模拟,小数化分数的一般步骤可以看我的上一篇BLOG,无非除以10的位数次方,再约分一下,这个题也是如此。比较复杂的是无限小数的处理。 分三种情况: 1、纯循环小数 ...

POJ 1930 无限循环小数化分数&& HDU 2136

Dead Fraction Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1258   ...

poj1930(无限循环小数化成分数)

/* translation: 给出一个无限循环小数,把该小数改写成以最简分数表示的形式 solution: 如果能够求出分数的表示形式的话,那么利用gcd就可以化简。但是想了好久没有想出怎么化成...

POJ 1930 解题报告 无限循环小数化分数

Dead FractionTime Limit: 1000MS Memory Limit: 30000KTotal Submissions: 1258 Accepted: 379Description...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:分数化为有限小数或无限循环小数(c实现)
举报原因:
原因补充:

(最多只允许输入30个字)