深蓝

自信人生二百年,会当水击三千里。

分数化为有限小数或无限循环小数(c实现)
问题描述:
将分数转化为小数,相信很多人都会吧.那么,这里给定一个分数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;
}
阅读更多
个人分类: C Language
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭