LeetCode 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)".

Hint:

  1. No scary math, just apply elementary math knowledge. Still remember how to perform a long division?
  2. Try a long division on 4/9, the repeating part is obvious. Now try 4/333. Do you see a pattern?
  3. 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)可以将整型转换成字符串类型
 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值