Поиск суммы дробей

Даны несколько положительных дробей, разделенных пробелом. Вычислить сумму дробей (результат сократить на наибольший общий делитель)

Программа выдает ошибку сегментирования. В чем ошибка ?

    #include <stdio.h>             
        #include <stdlib.h>
            int gcd (int a, int b) {
                if (a == b) {
                    return a;
                else if (a > b) {
                    int tmp;
                    a = b;
                    b = tmp;
                }
            return gcd(a, b - a);
        }
        int main () {
            int a, b, sum = 0, pro = 1, n, *num = NULL, *den = NULL, j, tmp;
            scanf ("%d\n", &n);
            num = malloc(n * sizeof(int));
            den = malloc(n * sizeof(int));
                for (int i = 0; i < n; i++) {
                    scanf ("%d/%d\n", &num[i], &den[i]);
                }
                for (int i = 0; i < n; i++) {
                    pro *= den[i];
                    for ((j = 0 && j != i); j < n; j++)
                        tmp = num[i] * den[j];
                    sum += tmp;
                }
                if (gcd (sum, pro) != 1) {
                    sum %= gcd(sum, pro);
                    pro %= gcd(sum, pro);
                }
                printf ("%d/%d", sum, pro);
                free(num);
                free(den);
        }

Ответы (1 шт):

Автор решения: Harry

Ваш код вообще не компилируется. Если подправить очевидные ошибки - как уже вам сказали, есть неинициализированные переменные. Ваш способ работы с дробями будет работать только для очень небольших значений числителя и знаменателя, так как быстро ведет к переполнению.

Я бы делал так, без всяких массивов. long long для перестраховки, на случай, если у вас будут дроби, которые приведут к переполнению при произведении. "Защита от дурака" простейшая, через assert.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

long long gcd(long long m, long long n)
{
    while(m && n) if (m < n) n %= m; else m %= n;
    return m + n;
}

int main ()
{
    int num;
    long long n, d, s, p;
    scanf("%d", &num);
    scanf("%lld/%lld",&s,&p);
    assert(p != 0);

    for (int i = 1; i < num; i++)
    {
        scanf("%lld/%lld", &n, &d);
        assert(d != 0);
        s = s*d + n*p;
        p *= d;
        long long g = gcd(s,p);
        s /= g;
        p /= g;
    }
    printf ("%lld/%lld\n", s, p);
}

Работающий пример. Сами видите, как быстро растут значения...

По-хорошему, надо бы еще и входные дроби сокращать на всякий случай:

long long gcd(long long m, long long n)
{
    while(m && n) if (m < n) n %= m; else m %= n;
    return m + n;
}

void reduce(long long* m, long long* n)
{
    long long g = gcd(*m, *n);
    *m /= g;
    *n /= g;
}

int main ()
{
    int num;
    long long n, d, s, p;
    scanf("%d", &num);
    scanf("%lld/%lld",&s,&p);
    reduce(&s,&p);
    assert(p != 0);

    for (int i = 1; i < num; i++)
    {
        scanf("%lld/%lld", &n, &d);
        assert(d != 0);
        reduce(&n,&d);
        s = s*d + n*p;
        p *= d;
        reduce(&s,&p);
    }
    printf ("%lld/%lld\n", s, p);
}
→ Ссылка