C语言PAT刷题 - 1034 有理数四则运算

作者的话:若有朋友复制代码去PAT试着运行遇到问题的:
1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了;
2.可能是注释原因,PAT有时候检测到注释会编译错误,所以可以先把注释删了,再进行提交回答;
3.可能是作者当初根据题目写出来的代码仍存在一些疏漏,而恰好当时的测试机制没那么完善,没检测出问题。后面测试机制有所更新,故出现问题,若有相关需要的可以评论区留言或私信作者,我看到的话会去再查一下疏漏之处,然后更新文章。

一、题目描述
本题要求编写程序,计算 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
二、解题思路
读题:
输入两个分数形式的有理数,要求程序分四行以最简形式输出两个有理数的加减乘除四个算式。
最简形式:k a/b(其中k是整数部分,a/b是最简分数部分;若为负数,则需加括号;若除法分母为0,则输出Inf;若k为非0,a以正数形式显示输出)。
思路:
1 变量定义:因为输出时都需要转成最简形式(k a/b),所以两个输入的有理数都各需要三个变量来存储k、a、b三个部分,而运算结果的k、a、b三部分我将放在运算函数里定义,故不在此定义;
2 接收两个分数;
3 形式变换:通过调用函数fraction(),对输入的两个分数进行约分,并变成最简形式;
4 对四则运算的前半部分输出:k或a为负数的有理数,用括号括起(对单个有理数的输出要遵循题目规定的格式,所以我定义了单个有理数的格式输出函数myprintf());
5 四则运算计算功能的实现。(函数调用在第四步①的代码中)
三、具体实现
0.标准C源程序框架

#include <stdio.h>
int main()
{
    return 0;
}

1 变量定义:因为输出时都需要转成最简形式(k a/b),所以两个输入的有理数都各需要三个变量来存储k、a、b三个部分,而运算结果的k、a、b三部分我将放在运算函数里定义,故不在此定义;

	long long k1 = 0, a1, b1;//三个变量用于存储输入的第一个有理数的最简形式的三个部分
	long long k2 = 0, a2, b2;//用于存储输入的第二个有理数的最简形式的三个部分

2 接收两个分数;

scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);

3 形式变换:通过调用函数fraction(),对输入的两个分数进行约分,并变成最简形式;
①形式变换函数调用部分

	fraction(&k1, &a1, &b1);
	fraction(&k2, &a2, &b2);

②形式变换函数定义部分

void fraction(long long* pk, long long* pa, long long* pb)//分数形式,小数形式
{
    //转化成最简形式
	*pk = (*pa) / (*pb);
	(*pa) = (*pa) - (*pk) * (*pb);
	if ((*pk) != 0)
		(*pa) = (*pa) > 0 ? (*pa) : (-*pa);
	//约分 - 经过最简形式转化后,此时a<b
	long long r = reduc((*pa), (*pb));
	(*pa) = (*pa) / r;
	(*pb) = (*pb) / r;
}

③约分函数定义部分(测试点3、4对程序运行效率有较高要求,所以要尽量优化约分函数,要求熟练掌握辗转相除法)

long long reduc(long long a, long long b)
{
	long long temp;
	while (b != 0) {
		temp = a % b;
		a = b;
		b = temp;
	}
	return a>0?a:(-a);
}

4 对四则运算的前半部分输出:k或a为负数的有理数,用括号括起(对单个有理数的输出要遵循题目规定的格式,所以我定义了单个有理数的格式输出函数myprintf());
①实现四则运算前半部分的输出

	//四则运算
	//加法
	myprintf(k1, a1, b1);//第一个有理数的输出
	printf(" + ");
	myprintf(k2, a2, b2);//第二个有理数的输出
	printf(" = ");
	add(k1, a1, b1, k2, a2, b2);//加法运算的实现
	printf("\n");
	//减法
	myprintf(k1, a1, b1);
	printf(" - ");
	myprintf(k2, a2, b2);
	printf(" = ");
	sub(k1, a1, b1, k2, a2, b2);//减法运算的实现
	printf("\n");
	//乘法
	myprintf(k1, a1, b1);
	printf(" * ");
	myprintf(k2, a2, b2);
	printf(" = ");
	mul(k1, a1, b1, k2, a2, b2);//乘法运算的实现
	printf("\n");
	//除法
	myprintf(k1, a1, b1);
	printf(" / ");
	myprintf(k2, a2, b2);
	printf(" = ");
	div(k1, a1, b1, k2, a2, b2);//除法运算的实现

②函数myprintf()的定义

void myprintf(long long k, long long a, long long b)//符合本题条件的特殊格式打印
{
	if (k < 0 || a < 0)//k或a有一个为0即说明当前有理数为负数,所以需要加括号,此处先输出左括号
		printf("(");
	if (k != 0)//如果k不为0,则需要输出k
		printf("%lld", k);
	if (k && a)	printf(" ");//如果k和a都非0,即需要显示,则两者之间还需要输出一个空格
	if (a != 0)//如果a不为0,则需要输出a/b
		printf("%lld/%lld", a, b);
	if (k < 0 || a < 0)//k或a有一个为0即说明当前有理数为负数,所以需要加括号,此处输出右括号
		printf(")");
	if (k == 0 && a == 0)//如果k、a均为0,即当前有理数为0,输出0
		printf("0");
}

5 四则运算计算功能的实现。(函数调用在第四步①的代码中)

//加法
void add(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 + k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	//当k非0时最简形式的a必显示为正数,但实际可能是负数,不在运算前改回来的话可能会导致结果错误
	//我就因为忽略了这个点在测试点3卡了很久,所以务必抓好每个细节
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	//加法的话可以整数部分和整数部分相加,分数部分相加,再把整数部分和分数部分结合成一个分数,
	//后用形式变换函数fraction()进行约分和转变为最简形式,最后将结果进行打印
	k = k1 + k2;
	if (k != 0)
		a = a1 * b2 + b1 * a2 + k * b1 * b2;
	else
		a = a1 * b2 + b1 * a2;
	b = b1 * b2;
	fraction(&k, &a, &b);
	myprintf(k, a, b);
}
//减法
void sub(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 - k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	k = k1 - k2;
	if (k != 0)
		a = a1 * b2 - b1 * a2 + k * b1 * b2;
	else
		a = a1 * b2 - b1 * a2;
	b = b1 * b2;
	fraction(&k, &a, &b);
	myprintf(k, a, b);
}
//乘法
void mul(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 * k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	a1 = a1 + k1 * b1;
	a2 = a2 + k2 * b2;
	a = a1 * a2;
	b = b1 * b2;
	fraction(&k, &a, &b);
	myprintf(k, a, b);
}
//除法
void div(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 / k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	a1 = a1 + k1 * b1;
	a2 = a2 + k2 * b2;
	if (a2 == 0)	printf("Inf");
	else//(a1*b2)/(b1*a2)
	{
		a = a1 * b2;
		b = b1 * a2;
		if (b < 0)
		{
			a = -a;
			b = -b;
		}
		fraction(&k, &a, &b);
		myprintf(k, a, b);
	}
}

四、测试数据
1 题目所给输入、输出样例多用用,给自己的代码进行测试(样例过了,测试点1、2应该都过了);
2 题目给出的整数可能超过int范围,所以整数都必须用long long型存放,不然最后两个测试点过不去。(虽然题目有说结果不会超出int,但因为我们的算法都是先计算结果再约分,所以可能超出;出题者希望我们的算法应该是和平常做分数乘法时一样,先对乘法两边的分子分母交叉进行约分,再相乘得到最终结果,这样应该可以使用int完成本题代码。奈何本人懒惰,选择挥霍空间完成这道题,大家凑合凑合)(对应测试点3、4);
3 测试点3、4对程序运行效率有较高要求,所以要尽量优化约分函数,要求熟练掌握辗转相除法;
4 测试点3过不去的也可以考虑考虑分子分母同为负数的情况;
5 测试点3过不去也可以试一下输入-5/2 1/2,看能否得到正确结果;(这个最重要!!!)
(哪个测试点折磨我最久大家应该一目了然了,crying)
五、初版代码(失败版本,因为思路不够清晰,程序也没有进行模块划分,代码显得杂乱,测试点3、4一直失败,调试无果后我选择放弃这个版本)

/*目标:输入两个分数形式的有理数,要求程序分四行输出两个有理数最简形式的加减乘除四个算式.
最简形式:k a/b(其中k是整数部分,a/b是最简分数部分;若为负数,则需加括号;若除法分母为0,则输出Inf).
*/                  // a1/b1 a2/b2
/*步骤分解:
1 变量预备。因为程序的输入是两个分数形式的有理数,每个分数由分子、'/'、分母组成(分子、分母均为整数)。
所以两个分数形式的有理数总共有四个整数需要存储,故需要定义四个整型变量,而'/'没有太多意义,不需要进行存储。
而四则运算的结果要以最简形式输出,形式为k a/b,所以有必要再定义三个变量存储运算结果。
2 输入接收。
3 四则运算。根据输入实现四则运算,计算出结果。
4 输出显示*/
#include <stdio.h>
void fraction(int k, int a, int b)
{
	int t = a > 0 ? a : (-a);
	for (int i = t; i >= 2; i--)
	{
		if (a % i == 0 && b % i == 0)
		{
			a = a / i;
			b = b / i;
			break;
		}
	}
	if (k < 0)
	{
		printf("(%d", k);
		if (a > 0)
			printf(" %d/%d)", a, b);
		else
			printf(")");
	}
	else if (k > 0)
	{
		printf("%d",k);
		if (a > 0)
			printf(" %d/%d", a, b);
	}
	else    //k==0
	{
		if (a > 0)	printf("%d/%d",a,b);
		else if (a < 0)	printf("(%d/%d)",a,b);
		else printf("0");
	}
}
int main()
{
	int k1 = 0, a1, b1;
	int k2 = 0, a2, b2;
	int k, a, b;
	scanf("%d/%d %d/%d",&a1,&b1,&a2,&b2);
	k1 = a1 / b1;
	k2 = a2 / b2;
	//加法运算
	fraction(k1, a1 - k1 * b1, b1);
	printf(" + ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	k = (a1 * b2 + a2 * b1) / (b1 * b2);
	if (k < 0)	a = -((a1 * b2 + a2 * b1) - k * (b1 * b2));
	else	    a = (a1 * b2 + a2 * b1) - k * (b1 * b2);
	b = (b1 * b2);
	fraction(k,a,b);
	printf("\n");
	//减法运算  
	fraction(k1, a1 - k1 * b1, b1);
	printf(" - ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	k = (a1 * b2 - a2 * b1) / (b1 * b2);
	if (k < 0)	a = -((a1 * b2 - a2 * b1) - k * (b1 * b2));
	else	    a = (a1 * b2 - a2 * b1) - k * (b1 * b2);
	b = (b1 * b2);
	fraction(k, a, b);
	printf("\n");
	//乘法运算  
	fraction(k1, a1 - k1 * b1, b1);
	printf(" * ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	k = (a1 * a2) / (b1 * b2);
	if (k < 0)	a = -(a1 * a2 - k * b1 * b2);
	else	    a = a1 * a2 - k * b1 * b2;
	b = b1 * b2;
	fraction(k, a, b);
	printf("\n");
	//除法运算  
	fraction(k1, a1 - k1 * b1, b1);
	printf(" / ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	if (k2 == 0 && (a2 - k2 * b2) == 0)	printf("Inf");
	else  
	{   // 3/-2    -3/-2   -2/3
		// k -1 a 1 b 2
		// k 1  a 1 b 2
		// k 0  a -2 b 3
		k = a1 * b2 / (b1 * a2);
		if (k == 0)
		{
			if (a2 < 0)
			{
				a1 = -a1;
				a2 = -a2;
			}
			a = a1 * b2;
		}
		else if (k > 0)
		{
			if (a2 < 0)
			{
				a1 = -a1;
				a2 = -a2;
			}
			a = a1 * b2 - k * b1 * a2;
		}
		else
		{
			if (a2 < 0)
			{
				a1 = -a1;
				a2 = -a2;
			}
			a = -(a1 * b2 - k * b1 * a2);
		}
		b = b1 * a2;
		fraction(k, a, b);
	}
	return 0;
}

六、第二版代码(做了更多的模块划分,程序思路较初版清晰许多,已通过测试)

/*目标:输入两个分数形式的有理数,要求程序分四行输出两个有理数最简形式的加减乘除四个算式.
最简形式:k a/b(其中k是整数部分,a/b是最简分数部分;若为负数,则需加括号;
若除法分母为0,则输出Inf).
*/                  // a1/b1 a2/b2
/*
步骤分解:
1 变量定义:因为输出时都需要转成最简形式(k a/b),所以两个输入的有理数以及最后的运算结果都各需要
三个变量来存储k、a、b三个部分;
2 接收两个分数;
3 形式变换:通过调用函数fraction(),对输入的两个分数进行约分,并变成最简形式;
4 对四则运算的前半部分输出:k为负数的有理数,用括号括起
5 四则运算计算功能的实现;
*/
#include <stdio.h>
long long reduc(long long a, long long b)
{
	long long temp;
	while (b != 0) {
		temp = a % b;
		a = b;
		b = temp;
	}
	return a>0?a:(-a);
}
void fraction(long long* pk, long long* pa, long long* pb)//分数形式,小数形式
{
	*pk = (*pa) / (*pb);
	(*pa) = (*pa) - (*pk) * (*pb);
	if ((*pk) != 0)
		(*pa) = (*pa) > 0 ? (*pa) : (-*pa);
	//约分 - 经过最简形式转化后,此时a<b
	long long r = reduc((*pa), (*pb));
	(*pa) = (*pa) / r;
	(*pb) = (*pb) / r;
}
void myprintf(long long k, long long a, long long b)//符合本题条件的特殊格式打印
{
	if (k < 0 || a < 0)//k或a有一个为0即说明当前有理数为负数,所以需要加括号,此处先输出左括号
		printf("(");
	if (k != 0)//如果k不为0,则需要输出k
		printf("%lld", k);
	if (k && a)	printf(" ");//如果k和a都非0,即需要显示,则两者之间还需要输出一个空格
	if (a != 0)//如果a不为0,则需要输出a/b
		printf("%lld/%lld", a, b);
	if (k < 0 || a < 0)//k或a有一个为0即说明当前有理数为负数,所以需要加括号,此处输出右括号
		printf(")");
	if (k == 0 && a == 0)//如果k、a均为0,即当前有理数为0,输出0
		printf("0");
}
//加法
void add(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 + k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	//当k非0时最简形式的a必显示为正数,但实际可能是负数,不在运算前改回来的话可能会导致结果错误
	//我就因为忽略了这个点在测试点3卡了很久,所以务必抓好每个细节
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	//加法的话可以整数部分和整数部分相加,分数部分相加,再把整数部分和分数部分结合成一个分数,
	//后用形式变换函数fraction()进行约分和转变为最简形式,最后将结果进行打印
	k = k1 + k2;
	if (k != 0)
		a = a1 * b2 + b1 * a2 + k * b1 * b2;
	else
		a = a1 * b2 + b1 * a2;
	b = b1 * b2;
	fraction(&k, &a, &b);
	myprintf(k, a, b);
}
//减法
void sub(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 - k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	k = k1 - k2;
	if (k != 0)
		a = a1 * b2 - b1 * a2 + k * b1 * b2;
	else
		a = a1 * b2 - b1 * a2;
	b = b1 * b2;
	fraction(&k, &a, &b);
	myprintf(k, a, b);
}
//乘法
void mul(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 * k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	a1 = a1 + k1 * b1;
	a2 = a2 + k2 * b2;
	a = a1 * a2;
	b = b1 * b2;
	fraction(&k, &a, &b);
	myprintf(k, a, b);
}
//除法
void div(long long k1, long long a1, long long b1, long long k2, long long a2, long long b2)
{   //k1 a1/b1 / k2 a2/b2
	long long k, a, b;//用于四则运算计算结果的最简形式的三个部分
	if (k1 < 0)a1 = -a1;
	if (k2 < 0)a2 = -a2;
	a1 = a1 + k1 * b1;
	a2 = a2 + k2 * b2;
	if (a2 == 0)	printf("Inf");
	else//(a1*b2)/(b1*a2)
	{
		a = a1 * b2;
		b = b1 * a2;
		if (b < 0)
		{
			a = -a;
			b = -b;
		}
		fraction(&k, &a, &b);
		myprintf(k, a, b);
	}
}
int main()
{
	long long k1 = 0, a1, b1;//三个变量用于存储输入的第一个有理数的最简形式的三个部分
	long long k2 = 0, a2, b2;//用于存储输入的第二个有理数的最简形式的三个部分
	scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);
	fraction(&k1, &a1, &b1);
	fraction(&k2, &a2, &b2);
	//四则运算
	//加法
	myprintf(k1, a1, b1);//第一个有理数的输出
	printf(" + ");
	myprintf(k2, a2, b2);//第二个有理数的输出
	printf(" = ");
	add(k1, a1, b1, k2, a2, b2);//加法运算的实现
	printf("\n");
	//减法
	myprintf(k1, a1, b1);
	printf(" - ");
	myprintf(k2, a2, b2);
	printf(" = ");
	sub(k1, a1, b1, k2, a2, b2);//减法运算的实现
	printf("\n");
	//乘法
	myprintf(k1, a1, b1);
	printf(" * ");
	myprintf(k2, a2, b2);
	printf(" = ");
	mul(k1, a1, b1, k2, a2, b2);//乘法运算的实现
	printf("\n");
	//除法
	myprintf(k1, a1, b1);
	printf(" / ");
	myprintf(k2, a2, b2);
	printf(" = ");
	div(k1, a1, b1, k2, a2, b2);//除法运算的实现
	return 0;
}

七、初版代码修正(经过第二版代码理清思路后,把初版代码的问题找出来并进行修正,最后通过测试)

/*目标:输入两个分数形式的有理数,要求程序分四行输出两个有理数最简形式的加减乘除四个算式.
最简形式:k a/b(其中k是整数部分,a/b是最简分数部分;若为负数,则需加括号;若除法分母为0,则输出Inf).
*/                  // a1/b1 a2/b2
/*步骤分解:
1 变量预备。因为程序的输入是两个分数形式的有理数,每个分数由分子、'/'、分母组成(分子、分母均为整数)。
所以两个分数形式的有理数总共有四个整数需要存储,故需要定义四个整型变量,而'/'没有太多意义,不需要进行存储。
而四则运算的结果要以最简形式输出,形式为k a/b,所以有必要再定义三个变量存储运算结果。
2 输入接收。
3 四则运算。根据输入实现四则运算,计算出结果。
4 输出显示*/
#include <stdio.h>
void fraction(long long k, long long a, long long b)
{
	long long temp;
	long long a1 = a, b1 = b;
	while (b1 != 0) {
		temp = a1 % b1;
		a1 = b1;
		b1 = temp;
	}
	a1 = a1 > 0 ? a1 : (-a1);
	a = a / a1;
	b = b / a1;
	if (k < 0)
	{
		printf("(%lld", k);
		a = -a;
		if (a > 0)
			printf(" %lld/%lld)", a, b);
		else	printf(")");
	}
	else if (k > 0)
	{
		printf("%lld", k);
		if (a > 0)
			printf(" %lld/%lld", a, b);
	}
	else    //k==0
	{
		if (a > 0)	printf("%lld/%lld", a, b);
		else if (a < 0)	printf("(%lld/%lld)", a, b);
		else printf("0");
	}
}
int main()
{
	long long k1 = 0, a1, b1;
	long long k2 = 0, a2, b2;
	long long k, a, b;
	scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);
	k1 = a1 / b1;
	k2 = a2 / b2;
	//加法运算
	fraction(k1, a1 - k1 * b1, b1);
	printf(" + ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	k = (a1 * b2 + a2 * b1) / (b1 * b2);
	a = (a1 * b2 + a2 * b1) - k * (b1 * b2);
	b = (b1 * b2);
	fraction(k, a, b);
	printf("\n");
	//减法运算  
	fraction(k1, a1 - k1 * b1, b1);
	printf(" - ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	k = (a1 * b2 - a2 * b1) / (b1 * b2);
	a = (a1 * b2 - a2 * b1) - k * (b1 * b2);
	b = (b1 * b2);
	fraction(k, a, b);
	printf("\n");
	//乘法运算  
	fraction(k1, a1 - k1 * b1, b1);
	printf(" * ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	k = (a1 * a2) / (b1 * b2);
	a = a1 * a2 - k * b1 * b2;
	b = b1 * b2;
	fraction(k, a, b);
	printf("\n");
	//除法运算  
	fraction(k1, a1 - k1 * b1, b1);
	printf(" / ");
	fraction(k2, a2 - k2 * b2, b2);
	printf(" = ");
	if (a2 == 0)	printf("Inf");
	else
	{   
		k = a1 * b2 / (b1 * a2);
		if (a2 < 0)
		{
			a1 = -a1;
			a2 = -a2;
		}
		a = a1 * b2 - k * b1 * a2;
		b = b1 * a2;
		fraction(k, a, b);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 可以使用结构体来表示有理数,结构体包含分子和分母两个整数成员。四则运算可以通过分别对分子和分母进行加、减、乘、除的操作来实现。具体实现可以参考以下代码: ``` #include <stdio.h> typedef struct { int numerator; // 分子 int denominator; // 分母 } Rational; // 求最大公约数 int gcd(int a, int b) { return b == ? a : gcd(b, a % b); } // 化简有理数 void simplify(Rational *r) { int g = gcd(r->numerator, r->denominator); r->numerator /= g; r->denominator /= g; } // 加法 Rational add(Rational r1, Rational r2) { Rational result; result.numerator = r1.numerator * r2.denominator + r2.numerator * r1.denominator; result.denominator = r1.denominator * r2.denominator; simplify(&result); return result; } // 减法 Rational subtract(Rational r1, Rational r2) { Rational result; result.numerator = r1.numerator * r2.denominator - r2.numerator * r1.denominator; result.denominator = r1.denominator * r2.denominator; simplify(&result); return result; } // 乘法 Rational multiply(Rational r1, Rational r2) { Rational result; result.numerator = r1.numerator * r2.numerator; result.denominator = r1.denominator * r2.denominator; simplify(&result); return result; } // 除法 Rational divide(Rational r1, Rational r2) { Rational result; result.numerator = r1.numerator * r2.denominator; result.denominator = r1.denominator * r2.numerator; simplify(&result); return result; } int main() { Rational r1 = {2, 3}; Rational r2 = {3, 4}; Rational r3 = add(r1, r2); printf("%d/%d + %d/%d = %d/%d\n", r1.numerator, r1.denominator, r2.numerator, r2.denominator, r3.numerator, r3.denominator); Rational r4 = subtract(r1, r2); printf("%d/%d - %d/%d = %d/%d\n", r1.numerator, r1.denominator, r2.numerator, r2.denominator, r4.numerator, r4.denominator); Rational r5 = multiply(r1, r2); printf("%d/%d * %d/%d = %d/%d\n", r1.numerator, r1.denominator, r2.numerator, r2.denominator, r5.numerator, r5.denominator); Rational r6 = divide(r1, r2); printf("%d/%d / %d/%d = %d/%d\n", r1.numerator, r1.denominator, r2.numerator, r2.denominator, r6.numerator, r6.denominator); return ; } ``` ### 回答2: 在C语言中,可以使用结构体来表示有理数,结构体包含两个整数成员numerator(分子)和denominator(分母)。 接下来,我们可以定义一些函数来实现有理数四则运算: 1. 加法(addition)函数: ```c struct Rational add(struct Rational r1, struct Rational r2) { struct Rational result; result.numerator = r1.numerator * r2.denominator + r2.numerator * r1.denominator; result.denominator = r1.denominator * r2.denominator; return result; } ``` 2. 减法(subtraction)函数: ```c struct Rational subtract(struct Rational r1, struct Rational r2) { struct Rational result; result.numerator = r1.numerator * r2.denominator - r2.numerator * r1.denominator; result.denominator = r1.denominator * r2.denominator; return result; } ``` 3. 乘法(multiplication)函数: ```c struct Rational multiply(struct Rational r1, struct Rational r2) { struct Rational result; result.numerator = r1.numerator * r2.numerator; result.denominator = r1.denominator * r2.denominator; return result; } ``` 4. 除法(division)函数: ```c struct Rational divide(struct Rational r1, struct Rational r2) { struct Rational result; result.numerator = r1.numerator * r2.denominator; result.denominator = r1.denominator * r2.numerator; return result; } ``` 上述函数中,我们利用了分子和分母的性质,通过运算得到了结果的分子和分母,最后构造并返回了一个新的有理数结构体。 需要注意的是,使用这些函数之前需要先定义一个有理数的结构体类型struct Rational,并根据具体情况进行初始化。由于最后的结果可能需要进行约分,我们可以再编写一个约分(reduction)函数对结果进行化简。 ### 回答3: C语言可以通过定义结构体来实现有理数四则运算。 首先,我们可以定义一个有理数的结构体,包含两个整数成员分子和分母: ```c typedef struct { int numerator; // 分子 int denominator; // 分母 } Rational; ``` 接下来,可以实现有理数的加法、减法、乘法和除法运算函数: ```c Rational add(Rational num1, Rational num2) { Rational result; result.numerator = num1.numerator * num2.denominator + num2.numerator * num1.denominator; result.denominator = num1.denominator * num2.denominator; return result; } Rational subtract(Rational num1, Rational num2) { Rational result; result.numerator = num1.numerator * num2.denominator - num2.numerator * num1.denominator; result.denominator = num1.denominator * num2.denominator; return result; } Rational multiply(Rational num1, Rational num2) { Rational result; result.numerator = num1.numerator * num2.numerator; result.denominator = num1.denominator * num2.denominator; return result; } Rational divide(Rational num1, Rational num2) { Rational result; result.numerator = num1.numerator * num2.denominator; result.denominator = num1.denominator * num2.numerator; return result; } ``` 使用上述定义和函数,可以进行两个有理数四则运算: ```c Rational num1 = {1, 2}; // 1/2 Rational num2 = {3, 4}; // 3/4 Rational sum = add(num1, num2); // 相加 Rational difference = subtract(num1, num2); // 相减 Rational product = multiply(num1, num2); // 相乘 Rational quotient = divide(num1, num2); // 相除 ``` 以上就是用C语言实现有理数四则运算的简单示例,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值