166 Fraction to Recurring Decimal
链接: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)”.
Credits:
Special thanks to @Shangrila for adding this problem and creating all test cases.
Hide Tags Hash Table Math
这个问题很容易理解,两数相除,如果有陷入循环,则用()将循环部分括起来。这题问题出在例子实在太极端,出题人真是丧心病狂,写C写的吐血了,以后都用C++吧,STL确实提供了丰富好用的功能,C实在玩不起了。C代码:
struct data
{
long long int val;
int remain;
int pos;
struct data *next;
};
int calcintlength(long long int num)
{
int result=0;
if(num==0)
return 1;
while(num>0)
{
result++;
num/=10;
}
return result;
}
char* fractionToDecimal(int numerator, int denominator)
{
long long int mnumerator=numerator,mdenominator=denominator,intger=0;
int intlength=0,totallength=0,fractionlength=0,pos=0;
struct data head,*cur,*a;
char* result;
char flag=0;
if(mnumerator==0)
{
result=(char*)malloc(2);
result[0]='0';
result[1]='\0';
return result;
}
if((mnumerator<0&&mdenominator>0)||(mnumerator>0&&mdenominator<0))
flag=1;
mdenominator=mdenominator>0? mdenominator:-mdenominator;
mnumerator=mnumerator>0?mnumerator:-mnumerator;
head.next=NULL;
cur=&head;
intger=mnumerator/mdenominator;
mnumerator%=mdenominator;
fractionlength=-1;
while(mnumerator!=0)
{
a=(struct data *)malloc(sizeof(struct data));
a->next=NULL;
a->val=mnumerator/mdenominator;
mnumerator=mnumerator%mdenominator;
a->remain=mnumerator;
a->pos=++fractionlength;
cur->next=a;
cur=head.next;
while(cur!=a)
{
if(cur->remain==mnumerator)
{
pos=cur->pos;
goto deal;
}
cur=cur->next;
}
mnumerator*=10;
}
deal:
intlength=calcintlength(intger);
totallength+=intlength;
//只有整数,没有小数
if(fractionlength<=0)
{
int i=0;
result=(char *)malloc(totallength+1);
result[totallength]='\0';
for(;i<totallength;i++)
{
result[totallength-i-1]=intger%10+'0';
intger/=10;
}
goto end;
}
a=head.next;
head=*head.next;
cur=head.next;
free(a);
//有小数,没循环
totallength++;
if(mnumerator==0)
{
int i=0;
totallength+=fractionlength;
result=(char *)malloc(totallength+1);
result[totallength]='\0';
for(;i<intlength;i++)
{
result[intlength-i-1]=intger%10+'0';
intger/=10;
}
result[intlength++]='.';
while(cur!=NULL)
{
result[intlength++]=cur->val+'0';
a=cur;
cur=cur->next;
free(a);
}
goto end;
}
//这里处理有循环
else
{
int i=0;
totallength+=2;
totallength+=fractionlength;
result=(char *)malloc(totallength+1);
result[totallength]='\0';
result[totallength-1]=')';
for(;i<intlength;i++)
{
result[intlength-i-1]=intger%10+'0';
intger/=10;
}
result[intlength++]='.';
result[intlength+pos]='(';
for( i=0;i<fractionlength+1;i++,intlength++)
{
if(i==pos)
continue;
else
{
result[intlength]=cur->val+'0';
a=cur;
cur=cur->next;
free(a);;
}
}
goto end;
}
end:
if(flag==1)
{
char *r=(char *)malloc(totallength+2);
memcpy(r+1,result,totallength+1);
r[0]='-';
free(result);
result=r;
}
return result;
}
相比之下使用STL的C++代码不经短小了许多,也更容易读懂。
class Solution {
public:
string fractionToDecimal(int numerator, int denominator)
{
long long int mnumerator=numerator,mdenominator=denominator;
if(numerator==0) return "0";
string result;
if((mnumerator<0&&mdenominator>0)||(mnumerator>0&&mdenominator<0)) result+='-';
mnumerator= mnumerator>0? mnumerator:-mnumerator;
mdenominator= mdenominator>0? mdenominator:-mdenominator;
result+=to_string(mnumerator/mdenominator);
mnumerator%=mdenominator;
if(mnumerator==0)
return result;
result+='.';
map<int,int> map;
while(mnumerator!=0)
{
if(map.find(mnumerator)!=map.end())
return result.substr(0,map[mnumerator])+"("+result.substr(map[mnumerator],result.size())+')';
map[mnumerator]=result.size();
mnumerator*=10;
result+=to_string(mnumerator/mdenominator);
mnumerator=mnumerator%mdenominator;
}
return result;
}
};