题意:写出一个程序,接受一个以N/D的形式输入的分数,其中N为分子,D为分母,输出它的小数形式。如果它的小数形式存在循环节,要将其用括号括起来。
输入: 输出:
22/5 4.4
1/3 0.(3)
1/7 0.(142857)
解题思路很明朗,只需要将我们在草稿纸上演算的过程用代码模拟实现即可。
数据结构:
1:map容器。判断是否是循环小数的依据是每次做完除法后的余数前面是否出现过。比如:
1/7=0……1
10/7 =1……3
30/7 =4……2
……
50/7=7……1
因此需要使用map容器标记每个余数,以判断是否出现循环节点。
2:string类
string类为字符串处理提供了很多函数。比如给小数的循环部分添加括号,可以用string类提供的
find函数查找循环小数的开始位置index,用insert函数在index处插入"(".
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
bool existRemainder(int source[], int n);
int main()
{
int Calculate(const int numerator, const int denominator, char *decimaltostring);
int n, m;
char p[103];
cin >> n >> m;
cout << Calculate(n, m, p) << endl;
cout << p << endl;
return 0;
}
int Calculate(const int numerator, const int denominator, char *decimaltostring)
{
if (denominator == 0)
return -1;
if (numerator % denominator == 0)
{
itoa(numerator / denominator, &(decimaltostring[0]), 10); //整数转为字符串
return 0;
}
int remainder[110] = { 0 }; //保存余数
int decimal[110] = { 0 }; //保存小数部分
remainder[0] = numerator % denominator;
itoa(numerator / denominator, &(decimaltostring[0]), 10);
decimaltostring[1] = '.';
int rlable = 0;
int dlable = 0;
int i, j;
while (1)
{
if (dlable == 100)
{
remainder[rlable] = -1; //置为-1,未整除但小数超过100位,也不加括号,题目中没说清楚
break;
}
decimal[dlable++] = remainder[rlable] * 10 / denominator;
remainder[rlable + 1] = remainder[rlable] * 10 % denominator;
rlable++;
if (remainder[rlable - 1] * 10 % denominator == 0)// if(!remainder[rlable])即可
{
remainder[rlable] = -1; //置为-1标志整除
break;
}
if (existRemainder(remainder, rlable))
break;
}
if (remainder[rlable] == -1)
{
for (i = 0, j = 2; i < dlable; i++, j++)
{
itoa(decimal[i], &(decimaltostring[j]), 10);
}
}
else
{
decimaltostring[2] = '(';
for (i = 0, j = 3; i < dlable; i++, j++)
{
itoa(decimal[i], &(decimaltostring[j]), 10);
}
decimaltostring[j] = ')';
}
return 0;
}
bool existRemainder(int source[], int n)
{
int i;
for (i = 0; i < n; i++)
{
if (source[n] == source[i])
return true;
}
return false;
}
//实现的想法:保存每次的余数,然后用 余数*10 再除以除数,得到余数后,在所保存的余数数组中查找,如果没有,则继续,如果已经出现了该余数,说明接下来会出现循环了,则跳出循环。