leetcode 166. Fraction to Recurring Decimal

本文详细介绍了如何将整数分数转换为字符串格式,并处理重复小数部分的方法。通过逐步解析过程,确保精度和避免计算机表示误差。

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.


If the fractional part is repeating, enclose the repeating part in parentheses.


For example,


Given numerator = 1, denominator = 2, return "0.5".
Given numerator = 2, denominator = 1, return "2".
Given numerator = 2, denominator = 3, return "0.(6)".


不能直接除,因为计算机表示精度有限,直接除第一次除出来的结果就有偏差了,数位少看不出来,往后面算出来的数就可能不对了,所以这个解法受制于计算机,行不通。

例如1/17,正确答案为"0.(0588235294117647)",上直接除输出却为"0.0588235294117647100620160927064716815948486328125",就是这个原因。

上面这个问题可以每次求余数,这样精度不会有任何损失。


在一个还有溢出问题,numerator和denominator都可能超出int的最大表示范围,所以要转化为long。

程序里fraction和pp两个变量定义成int,出错了找了半天,应该是long,思维不周密啊


class Solution {
	string myitoa(long long int num)
	{
		string re;
		if (num == 0)
			return string("0");
		while (num != 0)
		{
			re.insert(re.begin(), '0' + num % 10);
			num = num / 10;
		}
		return re;
	}
public:
	string fractionToDecimal(int numerator, int denominator) {
		if (numerator == 0)
			return string("0");
		if (denominator == 0)
			return string("");
		string re;
		if (numerator < 0 && denominator>0 || numerator > 0 && denominator < 0)
			re += '-';
		long long int num = numerator, den = denominator;
		num = abs(num), den = abs(den);
		long long int integer = num / den;
		re += myitoa(integer);

		long long int fraction = num - abs(integer*den);
		if (fraction == 0)
			return re;
		re += '.';
		map<int,int>bb;
		string fracpart;
		int kk = 0;
		while (fraction != 0)
		{
			if (bb.find(fraction) != bb.end())
			{
				string ff = string(fracpart.begin() + bb[fraction], fracpart.end());
				fracpart.erase(fracpart.begin() + bb[fraction], fracpart.end());
				fracpart += ('(' + ff + ')');
				return re + fracpart;
			}
			else
				bb.insert(pair<int, int>(fraction, kk));
			long long int pp = 10 * fraction;
			fracpart += myitoa(pp  /den);
			fraction = pp  - (long long int)(pp / den)*den;
			kk++;
		}
		int hh = fracpart.length()-1;
		while (fracpart[hh] == '0')
			hh--;
		fracpart.erase(hh + 1, fracpart.length());
		return re + fracpart;
	}
};


accepted
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值