您的位置:首页 > 其它

【再思考】PATBasic——1034. 有理数四则运算(20)

2015-06-29 15:26 369 查看


1034. 有理数四则运算(20)

时间限制

200 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

CHEN, Yue

本题要求编写程序,计算2个有理数的和、差、积、商。

输入格式:

输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。

输出格式:

分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。
输入样例1:
2/3 -4/2

输出样例1:
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)

输入样例2:
5/3 0/6

输出样例2:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
迄今为止,写了三个小时还没写出来的题,已经完全被搞晕掉了,我要歇一歇,改天清醒了再来!
这题前两天把我搞晕了,今天总算是整明白了~以后要训练自己养成写思路的习惯。看到题后,先在草稿纸上写下自己的思路,或者是伪代码。然后再开始敲代码!否则脑子越来越晕,越整越浆糊!不要想想就开始敲代码,感觉会给面试官留下不好的印象。废话不说了,说说这题的思路。
这题的题意不复杂,有理数的运算。我认为关键点有以下几点:
1、构建一个结构体Num,存放有理数。结构体中成员变量包括:符号,整数部分,分子,分母;
2、将输入字符串对应成Num中的格式。并判断第二个数是否为0的情况。为0情况特殊处理;
3、不为零的数,对两数进行加减乘除的运算。注意,输出的数格式都为假分数,此时直接用假分数进行计算,最后再化简即可。
4、对计算的结果,化成标准的最简真分数。这里涉及同时约分。(求最大公约数,再约分即可)
以下是我最后写出来的代码(代码还不是很优美,但是功能是可以的)
#include<vector>
#include <sstream>
#include<cmath>
#include<iomanip>
#include<iostream>
#include <ctype.h>
#include <stdlib.h>

using namespace std;

//1034. 有理数四则运算(20)

struct RatNum//创建一个结构体,表示一个有理数
{
bool sign;//1表示为正数,0表示为负数
long int intpart;
long int childp;
long int prtp;
};

//一系列要用到的函数申明,在实现部分写具体的功能
int maxCommon(int a, int b);
RatNum StringToRatNum(string s);
RatNum ToStdForm(RatNum num);
void Outputform(RatNum num);

RatNum StringToRatNum(string s)//注意输入的时候,本来就是一个假分数,因此这里将整数部分赋值为0
{
RatNum ratnum;
int fh = s.find('/');//找到分号的位置
ratnum.intpart = 0;
string childs;
string prts;

if (s[0] == '-')//为负数的情况
{
ratnum.sign = 0;
childs = s.substr(1, fh);
prts = s.substr(fh + 1, s.length() - 1);
}
else//为正数的情况
{
ratnum.sign = 1;
childs = s.substr(0, fh);
}

prts = s.substr(fh + 1, s.length() - 1);

ratnum.childp = atoi(childs.c_str());
ratnum.prtp = atoi(prts.c_str());

return ratnum;
}

// 顺便借题学习求最大公约数和最小公倍数的方法
int maxCommon(int a, int b)//求最大公约数
{
if (b == 0) return a;
else return maxCommon(b, a%b);
}

RatNum ToStdForm(RatNum num)//将假分数化为最简形式
{
RatNum ratnum;
ratnum.sign = num.sign;
int child = 0;
int part = 0;
ratnum.intpart = num.childp / num.prtp;
child = num.childp % num.prtp;
part = num.prtp;
int temp = maxCommon(child, part);
ratnum.childp = child / temp;
ratnum.prtp = part / temp;
return ratnum;
}

void Outputform(RatNum num)//函数实现标准格式的输出,包括:1、负数加括号;2、分子为0的情况;3、整数部分为0的情况
{
if (num.sign == false)//如果是负数,要加括号
{
if (num.childp == 0)
{
cout << "(-" << num.intpart << ")";
}
else
{
if (num.intpart == 0)
{
cout << "(-" << num.childp << "/" << num.prtp << ")";
}
else
{
cout << "(-" << num.intpart << " " << num.childp << "/" << num.prtp << ")";
}

}
}
else//为正数的情况
{
if (num.childp == 0)
{
cout << num.intpart;
}
else
{
if (num.intpart == 0)
{
cout << num.childp << "/" << num.prtp;
}
else
{
cout << num.intpart << " " << num.childp << "/" << num.prtp;
}

}
}
}

int main()
{
string a, b;
cin >> a >> b;

RatNum numa = StringToRatNum(a);//将输入的两个字符串表示为有理数的形式
RatNum numb = StringToRatNum(b);

RatNum he1, cha1, ji1, shang1;
he1.intpart = 0;//计算时均用假分数进行计算,因此
cha1.intpart = 0;
ji1.intpart = 0;
shang1.intpart = 0;

RatNum opt_numa = ToStdForm(numa);//将假分数转化成题目要求的形式,真分数,且最简形式
RatNum opt_numb = ToStdForm(numb);

if (numb.childp != 0)
{
//以下均先用假分数进行计算
if (numa.sign == numb.sign)//两数同号
{
ji1.sign = true;
shang1.sign = true;

if (numa.sign == true)//两数同为正
{
//和
he1.sign = true;

//差
cha1.childp = numa.childp*numb.prtp - numb.childp*numa.prtp;//计算差值
if (cha1.childp >= 0)
{
cha1.sign = true;
}
else
{
cha1.sign = false;
cha1.childp = abs(cha1.childp);//这里要注意取绝对值,数的正负在符号位反应,其他的正数,分子,分母部分均设为正数
}

}
else//两个数同时为负数
{
he1.sign = false;
cha1.childp = numb.childp*numa.prtp - numa.childp*numb.prtp;
if (cha1.childp >= 0)
{
cha1.sign = true;
}
else
{
cha1.sign = false;
cha1.childp = abs(cha1.childp);
}
}

//和
he1.childp = numa.childp*numb.prtp + numa.prtp*numb.childp;
}
else//两数异号
{
ji1.sign = false;
shang1.sign = false;

if (numa.sign == true)//a正b负
{
//和
he1.childp = numa.childp*numb.prtp - numa.prtp*numb.childp;
if (he1.childp >= 0)
{
he1.sign = true;
}
else
{
he1.sign = false;
he1.childp = abs(he1.childp);
}

//差
cha1.sign = true;
cha1.childp = numa.childp*numb.prtp + numb.childp*numa.prtp;
}

if (numa.sign == false)//a负b正
{
//和
he1.childp = numb.childp*numa.prtp - numa.childp*numb.prtp;
if (he1.childp >= 0)
{
he1.sign = true;
}
else
{
he1.sign = false;
he1.childp = abs(he1.childp);
}

//差
cha1.sign = false;
cha1.childp = numa.childp*numb.prtp + numa.prtp*numb.childp;
}
}

//和
he1.prtp = numa.prtp*numb.prtp;

//差
cha1.prtp = numa.prtp*numb.prtp;

//积
ji1.childp = numa.childp*numb.childp;
ji1.prtp = numa.prtp*numb.prtp;

//商
shang1.childp = numa.childp*numb.prtp;
shang1.prtp = numa.prtp*numb.childp;

RatNum he = ToStdForm(he1);//将假分数转化为标准形式
RatNum cha = ToStdForm(cha1);
RatNum ji = ToStdForm(ji1);
RatNum shang = ToStdForm(shang1);

Outputform(opt_numa);
cout << " + ";
Outputform(opt_numb);
cout << " = ";
Outputform(he);
cout << endl;

Outputform(opt_numa);
cout << " - ";
Outputform(opt_numb);
cout << " = ";
Outputform(cha);
cout << endl;

Outputform(opt_numa);
cout << " * ";
Outputform(opt_numb);
cout << " = ";
Outputform(ji);
cout << endl;

Outputform(opt_numa);
cout << " / ";
Outputform(opt_numb);
cout << " = ";
Outputform(shang);
cout << endl;
}
else//特殊处理第二个数为0的情况
{
Outputform(opt_numa);
cout << " + ";
Outputform(opt_numb);
cout << " = ";
Outputform(opt_numa);
cout << endl;

Outputform(opt_numa);
cout << " - ";
Outputform(opt_numb);
cout << " = ";
Outputform(opt_numa);
cout << endl;

Outputform(opt_numa);
cout << " * ";
Outputform(opt_numb);
cout << " = 0";
cout << endl;

Outputform(opt_numa);
cout << " / ";
Outputform(opt_numb);
cout << " = Inf";
cout << endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: