分数求和

题目链接

本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:

输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。

输出格式:

输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

输入样例1:

5
2/5 4/15 1/30 -2/60 8/3

      
    

输出样例1:

3 1/3

      
    

输入样例2:

2
4/3 2/3

      
    

输出样例2:

2

      
    

输入样例3:

3
1/3 -1/6 1/8

      
    

输出样例3:

7/24

````C #include #include //定义存储分数的结构体 typedef struct grade { int a; //分子 char ch; //分数符号 int b; //分母 int c; //整数部分 } Num;

//函数申明
Num getSum(Num num1, Num num2);

void printGrade(Num num);

void simplifyGrade(Num *num);

int main()
{
//用户将要输入的分数的个数
int N;
scanf("%d", &N);
//定义分数的结构体数组
Num nums[N];
//所有分数的和
Num sum;
//依次对分数的分子,分数符号,分母赋值
for (int i = 0; i < N; i++)
{
scanf("%d", &nums[i].a);
scanf("%c", &nums[i].ch);
scanf("%d", &nums[i].b);
}

//将第一个分数赋值给sum
sum.a = nums[0].a;
sum.ch = nums[0].ch;
sum.b = nums[0].b;

//通过递归来求和
for (int i = 1; i < N; i++)
    sum = getSum(sum, nums[i]);

//打印该分数
printGrade(sum);

return 0;

}

//分数求和
Num getSum(Num num1, Num num2) {
//需要返回的sum
Num sum;
//需要注意 一定要给ch赋值,否则输出时会出现问题
sum.ch = '/';

//当两个分数的分母不等时,需要通分计算
if (num1.b != num2.b) {
    //通过for循环 找到两个分数分母的最小公倍数
    for (int i = num1.b;; i++)
        if (i % num1.b == 0 && i % num2.b == 0) {
            sum.b = i;  
            break;
        }
    //计算sum的分子
    sum.a = num1.a * (sum.b/num1.b) + num2.a *  (sum.b/num2.b);
}

//当两个分数的分母相等时,直接将两个分数的分子相加,赋值给sum的分子
else {
    sum.a = num1.a + num2.a;
    sum.b = num1.b;
}

return sum;

}

//打印分数
void printGrade(Num num) {
//当分数的分子为0时,直接输出0
if (num.a == 0) {
printf("0");
// return 0;
}

//当分数的分子不为0时
else
{
    //当分数的分子比分母要大时(假分数)
    if (num.a > num.b)
    {
        //得到分数前面的整数
        num.c = num.a / num.b;
        //等到新的分子
        num.a = num.a % num.b;

        //如果分子刚好除尽分母,则直接打印分数前面的整数
        if (num.a == 0)
            printf("%d", num.c);

        //如果分子没有除尽分母
        else
        {   
            //需要对分数进行进一步的化简
            simplifyGrade(&num);
            //最后打印分数
            printf("%d %d%c%d", num.c,num.a,num.ch,num.b);
        }
        // printf("a>b");
    }

    //当分数的分子比分母要小时(真分数)
    else if(num.a < num.b) {
        //直接调用化简函数进行化简
        simplifyGrade(&num);
        //最后打印化简后的分数
        printf("%d%c%d", num.a,num.ch,num.b);
    }  

    //当分数的分子和分母相等时,直接输出1
    else 
        printf("1");
}

}

//分数化简,由于这个函数需要改变分数的值
//所以需要传递结构体的地址
void simplifyGrade(Num *num) {
int i;

//通过循环找到分子与分母的最大公约数
for (i = num->a;; i--)
    if (num->a % i == 0 && num->b % i == 0)
        break;

//化简分数的分子和分母
num->a = num->a / i;
num->b = num->b / i;

}

<br>
![](https://img2020.cnblogs.com/blog/1715582/202003/1715582-20200320220701602-1623812050.png)

>**程序还需进一步完善,运行时间过长,未达到题目要求。**
原文地址:https://www.cnblogs.com/TomHe789/p/12535266.html