题目链接:https://leetcode.com/problems/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)".
Hint:
- No scary math, just apply elementary math knowledge. Still remember how to perform a long division?
- Try a long division on 4/9, the repeating part is obvious. Now try 4/333. Do you see a pattern?
- Be wary of edge cases! List out as many test cases as you can think of and test your code thoroughly.
一.自己写的,好麻烦。。。
class Solution {
public:
string fractionToDecimal(long long numerator, long long denominator) {//把参数int类型改成long long类型,因为测试数据有INT_MIN有错误
string result;
long long len = 0; long long position = 0; long long flag = 0;
vector<long long> q;//存放每一步的熵
vector<long long> r;//存放每一步的余数
long long sign = 1;//标志最后结果正负
if (numerator < 0)
{
numerator = -numerator;
sign = -1*sign;
}
if (denominator < 0)
{
denominator = -denominator;
sign = -1 * sign;
}
//乘积最后为负,最后加“-”
if (sign == -1&&numerator!=0)
{
result.append("-");
}
while (1)
{
if (numerator<denominator)//分子<分母的情况
{
q.push_back(0);//商存入0
r.push_back(numerator);//余数存入被除数
numerator = numerator * 10;
}
else//分子大于分母的情况,除出来得出商和余数
{
q.push_back(numerator / denominator);
r.push_back(numerator%denominator);
numerator = numerator%denominator * 10;
len = r.size();
for (int i = 0; i<len-1; i++)
{
if (r[len - 1] == r[i])//得出循环位的前一位
{
flag = 1;
position = i;
break;
}
}
}
if (flag == 1||r[r.size()-1]==0)
break;
}
long long count = 1;
long long temp = q[0];
while (temp / 10>0)//计算整数部分位数
{
count++;
temp = temp % 10;
}
char *tmp=new char[count];
sprintf(tmp, "%lld", q[0]);
result.append(tmp);
//整数后面存入小数点
if (q.size() != 1)
{
result.append( ".");
}
if (r[r.size() - 1] != 0)//如果没有被除尽
{
for (int i = 1; i<q.size(); i++)
{
if (i -1== position)
{
result.append("(");
}
char *tmp1 = new char[count];
sprintf(tmp1, "%lld", q[i]);
result.append(tmp1);
}
result.append(")");
}
else//如果被除尽,就不用加括号了
{
for (int i = 1; i<q.size(); i++)
{
char *tmp1 = new char[count];
sprintf(tmp1, "%lld", q[i]);
result.append(tmp1);
}
}
return result;
}
};
二.改短后,简洁多了。。。
class Solution {
public:
string fractionToDecimal(long long numerator, long long denominator) {//把参数原来的int类型改成long long,因为测试数据有INT_MAX
string result;
long long len = 0;
long long flag = 0;
vector<long long> q;
vector<long long> r;
result=numerator*denominator<0?result.append("-"):result;
numerator = abs(numerator);
denominator = abs(denominator);
while (1)
{
q.push_back(numerator / denominator);
r.push_back(numerator % denominator);
char *tmp1 = new char[20];
sprintf(tmp1, "%lld", numerator / denominator);
result.append(tmp1);
if (numerator % denominator == 0)
return result;
numerator = numerator % denominator;
if (numerator<denominator)
numerator = numerator%denominator * 10;
if(q.size()==1)
result.append(".");
len = r.size();
for (int i = 0; i<len - 1; i++)
{
if (r[len - 1] == r[i])
{
result.insert(result.find(".")+i+1, "(");
result.append(")");
flag = 1;
break;
}
}
if (flag == 1)
break;
}
return result;
}
};
注:1.’INT_MIN和-2147483648不同,在VS中测试的时候,输入后者报错,前者可以</span>
2.调用字符串插入和查找的函数,insert,find可以缩短代码长度
3.string a;int b;sprintf(a,'%d',b);可以把整数b转换成字符串类型并存进a
三.大神写的,时间复杂度很低,代码很简洁
class Solution {
public:
// upgraded parameter types
string fractionToDecimal(int64_t n, int64_t d) {
// zero numerator
if (n == 0) return "0";
string res;
// determine the sign
if (n < 0 ^ d < 0) res += '-';
// remove sign of operands
n = abs(n), d = abs(d);
// append integral part
res +=to_string</span>(n / d);
// in case no fractional part
if (n % d == 0) return res;
res += '.';
unordered_map<int, int> map;
// simulate the division process
for (int64_t r = n % d; r; r %= d)</span> {
// meet a known remainder
// so we reach the end of the repeating part
if (map.count(r) > 0)</span> {
res.insert(map[r], 1, '(');
res += ')';
break;
}
// the remainder is first seen
// remember the current position for it
map[r] = res.size();
r *= 10;
// append the quotient digit
res += to_string(r / d);
}
return res;
}
};
分析:1、用无序关联容器map将每一步的余数和res的位置对应起来,为之后插入“(”确定位置提供了方便
2、for循环的用法值得借鉴
3、在字符串后添加子串的方法:res.append("a")或者res+="a";
4、to_string(a)可以将整型转换成字符串类型