字符串 小数化分数

【问题描述】 任何小数都能表示成分数的形式,对于給定的小数,编写程序其化为最简分数输出,小数包括简单小数和循环小数。

【输入形式】 第一行是一个整数N,表示有多少组数据。\每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。【输出形式】 对每一个对应的小数化成最简分数后输出,占一行

【样例输入】

3

0.(4)

0.5

0.32(692307)

【样例输出】

4/9

1/2

17/52


我用的知识都是string里面的,没学过的话可以上b站看黑马程序员P189-196,新手也能学,而且很好用。


#include <iostream>

#include <string>

using namespace std;

int main()

{

int n;

 cin >> n;

 cin.ignore();

 while (n--)

 {

  int sum = 1, num = 0, num1 = 0, sum1 = 1;

//num用于记录分子,sum记录分母,num1和sum1的用处后面再讲

  string s, t;

  getline(cin, s);

无非三种情况,第1种简单小数,第2种括号紧跟小数点,第3种括号不紧跟小数点


  size_t pos = s.find("(", 2);//判断是简单小数还是循环小数

  if (pos == string::npos)//第一种情况

  {

   t = s.substr(2);//截取小数点后的数字

   for (size_t i = 0; i < t.size(); i++)

   {

    num = num * 10 + t[i] - '0';//将分子化成整数

    sum *= 10;//分母相应的变化

   }

   for (int j = num; j >= 2; j--)

   {

    if (num % j == 0 && sum % j == 0)

//判断是否可以约分

    {

     num /= j;

     sum /= j;

    }

   }

  }

  else if (pos == 2)//第二种情况,括号紧跟着小数点

{

   sum = 9;//因为分母都是9,99,999这种,所以我让sum=9

   t = s.substr(3);//截取括号之后的一串字符串

   for (size_t i = 0; i < t.size()-1; i++)//只遍历到右括号前的数字

{

num = num * 10 + t[i] - '0';

    sum = sum*10+9;

   }//相应的分子分母

sum /= 10;//因为我一开始就让它等于9,但它其实是0.9,所以后面除以10

   for (int j = num; j >= 2; j--)

{

    if (num % j == 0 && sum % j == 0)

{

num /= j;

     sum /= j;

    }

   }

  }

    ​
​
else

  {

   sum = 9;

   t = s.substr(2, pos - 2);//截取小数点后和左括号前的一串数字 

​  
for (size_t i = 0; i < t.size(); i++)

   {

    num1 = num1 * 10 + t[i] - '0';

    sum1 *= 10;

   }//获得相应的分子分母

   t = s.substr(pos + 1);//截取括号中的数字

   for (size_t i = 0; i < t.size() - 1; i++)

   {

    num = num * 10 + t[i] - '0';

    sum = sum * 10 + 9;

   }

sum /= 10;

   for (int j = num; j >= 2; j--)

   {

    if (num % j == 0 && sum % j == 0)

{

     num /= j;

​ sum /= j;

}

   }//求括号中数字的分子,分母

   num = num1 * sum + num;

   sum = sum * sum1;//然后再将两者整合,化成同一个分数

for (int j = num; j >= 2; j--)

   {

if (num % j == 0 && sum % j == 0)

{

num /= j;

     sum /= j;

}

}//再进行约分

}

cout << num << "/" << sum << endl;

 }

return 0;

}

最后发现第2种情况和第3种情况可以整合,就相当于第2种情况括号前的数字截取的是一个空的字符串,并不会影响最后的结果。接下来展示最终的代码:


结合样例应该很好看懂,不会欢迎评论问我



      
      

#include <iostream>
#include <string>
using namespace std;
int main()
{
	int n;
	cin >> n;
	cin.ignore();
	while (n--)
	{
		int sum = 1, num = 0, num1 = 0, sum1 = 1;
		string s, t;
		getline(cin, s);
		size_t pos = s.find("(", 2);
		if (pos == string::npos)
		{
			t = s.substr(2);
			for (size_t i = 0; i < t.size(); i++)
			{
				num = num * 10 + t[i] - '0';
				sum *= 10;
			}
			for (int j = num; j >= 2; j--)
			{
				if (num % j == 0 && sum % j == 0)
				{
					num /= j;
					sum /= j;
				}
			}
		}

		else
		{
			sum = 9;
			t = s.substr(2, pos - 2);
			for (size_t i = 0; i < t.size(); i++)
			{
				num1 = num1 * 10 + t[i] - '0';
 				sum1 *= 10;
			}
			t = s.substr(pos + 1);
			for (size_t i = 0; i < t.size() - 1; i++)
			{
				num = num * 10 + t[i] - '0';
				sum = sum * 10 + 9;
			}
			sum /= 10;
		for (int j = num; j >= 2; j--)
			{
				if (num % j == 0 && sum % j == 0)
				{
					num /= j;
					sum /= j;
				}
			}
			num = num1 * sum + num;
			sum = sum * sum1;
			for (int j = num; j >= 2; j--)
			{
				if (num % j == 0 && sum % j == 0)
				{
					num /= j;
					sum /= j;
				}
			}

		}
		cout << num << "/" << sum << endl;
	}
	return 0;
}


             


当然,求最大公约数可以用辗转相除法

话不多说,上代码!!!(方法二)


#include <iostream>
#include <string>
using namespace std;
int gcd(int a, int b)//辗转相除求最大公约数
{
	if (b == 0)return a;
	return gcd(b, a % b);
}
int main()
{
	int n;
	cin >> n;
	cin.ignore();
	while (n--)
	{
		int sum = 1, num = 0, num1 = 0, sum1 = 1,result=0;
		string s, t;
		getline(cin, s);
		size_t pos = s.find("(", 2);
		if (pos == string::npos)
		{
			t = s.substr(2);
			for (size_t i = 0; i < t.size(); i++)
			{
				num = num * 10 + t[i] - '0';
				sum *= 10;
			}
			result=gcd(sum, num);
			sum /= result;
			num /= result;
		}	
		else
		{
			sum = 9;
			t = s.substr(2, pos - 2);
			for (size_t i = 0; i < t.size(); i++)
			{
				num1 = num1 * 10 + t[i] - '0';
 				sum1 *= 10;
			}
			t = s.substr(pos + 1);
			for (size_t i = 0; i < t.size() - 1; i++)
			{
				num = num * 10 + t[i] - '0';
				sum = sum * 10 + 9;
			}
			sum /= 10;
			result = gcd(sum, num);
			sum /= result;
			num /= result;
			num = num1 * sum + num;
			sum = sum * sum1;
			result = gcd(sum, num);
			sum /= result;
			num /= result;
		}
		cout << num << "/" << sum << endl;
	}
	return 0;
}

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无意识程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值