7

我在为分配需要做的以下事情上遇到了很大的困难
声明一个包含有理数的数据结构。
湾。写 f'xns 将 +, -, *, / 有理数。
所有 f'xns 都必须传递 3 个参数,每个参数都指向我在 a 部分声明的类型的数据结构;参数中的 2 个 = 操作数,第 3 个 = 结果。
C。编写一个 f'xn,它将指向您的数据结构的指针作为参数并返回数字的 GCD。& 面额。
d。使用 c 部分中的 f'xn 编写一个 f'xn,它将分数(有理数)减少到最低项。传入一个指向分数的指针,并让 f'xn 修改分数。
e.编写输入和输出函数,以便用户可以输入 1/5 形式的分数。

应该允许用户输入任意数量的问题,并且程序应该以最低的形式输出答案。

我在正确的轨道上吗?我相信我有 ac,但没有 d,尤其是 e。有人可以指导我或帮助我更正我的脚本吗?

int GCD (int numer, int denom)
{
    int result;
    while (denom > 0) {
        result = numer % denom;
        numer = denom;
        denom = result;
    }
    return numer;
}

int getLCM (int numer, int denom)
{
    int max;
    max = (numer > denom) ? numer : denom;
    while (1) {
        if (max % numer == 0 && max % denom == 0)
            break;
        ++max;
    }
    return max;
}

struct Fraction 
{
    int numer;
    int denom;
};

typedef struct 
{
    int numer;
    int denom; 
};
Fraction

Fraction add_fractions (Fraction a, Fraction b)
{
    Fraction sum;
    sum.numer = (a.numer * b.denom) + (b.numer * a.denom);
    sum.denom = a.denom * b.denom;
    return sum;
}

Fraction subtract_fractions (Fraction a, Fraction b)
{
    Fraction sum;
    sum.numer = (a.numer * b.denom) - (b.numer * a.denom);
    sum.denom = a.denom * b.denom;
    return sum;
}

Fraction multiply_fractions (Fraction a, Fraction b)
{
    Fraction sum;
    sum.numer = (a.denom * b.denom);
    sum.denom = (a.numer * b.numer);
    return sum;
}

Fraction divide_fractions (Fraction a, Fraction b)
{
    Fraction sum;
    sum.numer = (a.denom * b.numer);
    sum.denom = (a.numer * b.denom);
    return sum;
}

int main ()
{
    char response;

    printf ("FRACTION ARITHMETIC PROGRAM\n");
    printf ("Enter your problem (example 2/3 + 1/5):\n");
    scanf (, &problem);

    if (denom == 0 || denom < 0) {
        printf ("Illegal input!!\n");
        printf ("Another problem (y/n)?  ");
        scanf ("%c%*c", &response);
    } else {
        printf ("The answer is  ");

        printf ("Another problem (y/n)?  ");
        scanf ("%c%*c", &response);
    }

    while ((response == 'y') || (response == 'Y')) {
        printf ("\nWould you like to play again?\n");
        scanf ("%c%*c", &response);
    }

    while ((response == 'n') || (response == 'N'))
        printf ("Goodbye and thank you");

    return 0;
}

由于评论回复,删除 typedef 后进行编辑:

struct Fraction {
    int numer;
    int denom;
};

struct Fraction add_fractions (struct Fraction a, struct Fraction b)
{
    struct Fraction sum;
    sum.numer = (a.numer * b.denom) + (b.numer * a.denom);
    sum.denom = a.denom * b.denom;
    return sum;
}

struct Fraction subtract_fractions (struct Fraction a, struct Fraction b)
{
    struct Fraction sum;
    sum.numer = (a.numer * b.denom) - (b.numer * a.denom);
    sum.denom = a.denom * b.denom;
    return sum;
}

struct Fraction multiply_fractions (struct Fraction a, struct Fraction b)
{
    struct Fraction sum;
    sum.numer = (a.denom * b.denom);
    sum.denom = (a.numer * b.numer);
    return sum;
}

struct Fraction divide_fractions (struct Fraction a, struct Fraction b)
{
    struct Fraction sum;
    sum.numer = (a.denom * b.numer);
    sum.denom = (a.numer * b.denom);
    return sum;
}
4

3 回答 3

3

您的代码的一些注释:

  • 您没有完全遵循您的要求,因为 GCD 函数在需要采用指向结构的指针时采用 2 个整数,而您的函数采用 2 个结构作为参数,并在它们应该采用 3 个(指向)结构时返回另一个。
  • 您的 GCD 函数使用了一个很好的 GCD 实现(感谢 Jonathan 的评论),即使有一些评论解释了为什么对未来的读者很好
  • 正如您在评论中所说,您应该在对其进行操作之前减少有理数以避免不必要的溢出,并且在添加或减去有理数时,出于同样的原因,您应该使用 denoms 的 LCM
  • 你的 LCM 算法很差。由于您的 GCD很好,为什么不简单地使用:LCM(a,b) = a * b / GCD(a,b)计算lcm = (a/gcb) * b以减少溢出风险(感谢@nm 的简化形式)
  • a/b 的简化形式是 a'/b' 其中 a'=a/GCD(a,b) 和 b'=b/GCD(a,b)
  • "%d/%d"对于结构的两个成员,输入和输出的格式如何?

最后但并非最不重要的一点是,"%c%*c"获取 ay/n 问题答案的格式是可能的,但很危险:您可能会得到前面输入的换行符作为响应!选择面向行的输入(带fgets+ sscanf)或自由格式输入(带scanffscanf)之一并坚持下去。%1s进入一个char response[2]更安全...

并在评论中仔细写下你只处理积极的理性或照顾符号!这样的细节会让图书馆的用户非常生气……更不用说吹毛求疵的老师了(Jonathan Leffler的作品)。

于 2015-11-24T09:18:25.487 回答
2

您可以使用运算符的枚举和打开运算符的函数,因为所有运算符都遵循类似的模式。这简化了代码。这是一些实现的示例,您可以添加其余的:

typedef struct node {
    int nom;
    int denom;
} Tfraction;

typedef enum {PLUS, MINUS, MULTIPLY, DIVIDE} Ops;

int calculate(int x, Ops op, int y) {
    switch (op) {
        case PLUS: return x + y;
        case MINUS: return x - y;
        case MULTIPLY: return x * y;
        case DIVIDE: return x / y;
    }
}

//reccursive gcd
int gcdr (int a, int b) {
    if (a == 0) return b;
    return gcdr(b % a, a);
}

void simplify(Tfraction *fraction) {
    int gcd = gcdr(fraction->nom, fraction->denom);
    fraction->nom /= gcd;
    fraction->denom /= gcd;
}

Tfraction compute(Tfraction a, Tfraction b, Ops op) {
    if (op == DIVIDE) {
        int temp = b.nom;
        b.nom = b.denom;
        b.denom = temp;
        op = MULTIPLY;
    }

    if (op == MULTIPLY) {
        Tfraction result = { calculate(a.nom, op, b.nom), calculate(a.denom, op, b.denom) };
        simplify(&result);
        return result;
    }
    if (a.denom == b.denom) {
        Tfraction result = { calculate(a.nom, op, b.nom), a.denom };
        simplify(&result);
        return result;
    }
    else {
        Tfraction result = { (calculate((a.nom * b.denom), op, (b.nom * a.denom))), (a.denom * b.denom) };
        simplify(&result);
        return result;
    }
}

int main ()
{
    //Test
    Tfraction f1 = {2, 4}, f2 = {4, 2};

    printf("Addition: %d/%d\n", compute(f1, f2, PLUS).nom, compute(f1, f2, PLUS).denom);
    printf("Subtraction: %d/%d\n", compute(f1, f2, MINUS).nom, compute(f1, f2, MINUS).denom);
    printf("Multiplication: %d/%d\n", compute(f1, f2, MULTIPLY).nom, compute(f1, f2, MULTIPLY).denom);
    printf("Division: %d/%d\n", compute(f1, f2, DIVIDE).nom, compute(f1, f2, DIVIDE).denom);

    return 0;
}
于 2015-11-24T10:55:02.473 回答
0

我更改了 sum 和 multiply 函数以最小化溢出,尽管我没有将它们更改为接受 3 个参数(我更喜欢这种方式)。

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

typedef struct {
    int numer;
    int denom; 
} Fraction;

int gcd(int numer, int denom) {
  int result;
  while (denom != 0) {
    result = numer % denom;
    numer = denom;
    denom = result;
  }
  return numer;
}

int lcm(int a, int b) {
  return (a / gcd(a,b)) * b;
}

Fraction simplify (Fraction a) {
  int cd;
  cd = gcd(a.numer, a.denom);
  a.numer /= cd;
  a.denom /= cd;
  return a;
}

Fraction add_fractions (Fraction a, Fraction b) {
  Fraction sum;
  int lcmd;
  a = simplify(a);
  b = simplify(b);
  lcmd = lcm(a.denom, b.denom);
  sum.numer = (lcmd / a.denom * a.numer) + (lcmd / b.denom * b.numer);
  sum.denom = lcmd;
  return simplify(sum);
}

Fraction subtract_fractions (Fraction a, Fraction b) {
  Fraction sum;
  int lcmd;
  a = simplify(a);
  b = simplify(b);
  lcmd = lcm(a.denom, b.denom);
  sum.numer = (lcmd / a.denom * a.numer) - (lcmd / b.denom * b.numer);
  sum.denom = lcmd;
  return simplify(sum);
}

void swap(int *a, int *b) {
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

Fraction multiply_fractions (Fraction a, Fraction b) {
  Fraction sum;
  a = simplify(a);
  b = simplify(b);
  swap(&a.numer, &b.numer); // another round of simplifications to avoid (minimize) overflows below
  a = simplify(a);
  b = simplify(b);
  sum.numer = (a.numer * b.numer);
  sum.denom = (a.denom * b.denom);
  return sum;
}

Fraction divide_fractions (Fraction a, Fraction b) {
  swap(&b.numer, &b.denom);
  return multiply_fractions(a, b);
}

int main() {
  int a, b;
  Fraction f1 ,f2, res;

  printf("gcd(12,9)=%d\n", gcd(12,9));
  printf("gcd(9,12)=%d\n", gcd(9,12));

  printf("gcd(4,12)=%d\n", gcd(4,12));

  printf("gcd(8,12)=%d\n", gcd(8,12));
  printf("gcd(12,8)=%d\n", gcd(12,8));

  puts("-");

  printf("lcm(12,9)=%d\n", lcm(12,9));
  printf("lcm(9,12)=%d\n", lcm(9,12));

  printf("lcm(8,12)=%d\n", lcm(8,12));
  printf("lcm(12,8)=%d\n", lcm(12,8));

  printf("lcm(4,12)=%d\n", lcm(4,12));
  printf("lcm(3,5)=%d\n", lcm(3,5));
  printf("lcm(4,5)=%d\n", lcm(4,5));
  printf("lcm(3,4)=%d\n", lcm(3,4));

  puts("-");

  f1.numer = 12;
  f1.denom = 9;
  printf(" %d/%d simplified to", f1.numer, f1.denom);
  f1 = simplify(f1);
  printf(" %d/%d \n", f1.numer, f1.denom);

  f1.numer = 8;
  f1.denom = 12;
  printf(" %d/%d simplified to", f1.numer, f1.denom);
  f1 = simplify(f1);
  printf(" %d/%d \n", f1.numer, f1.denom);

  puts("-");

  f1.numer = 1; f1.denom = 4;
  f2.numer = 1; f2.denom = 4;
  res = add_fractions(f1, f2);
  printf(" %d/%d + %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 1; f1.denom = 4;
  f2.numer = 1; f2.denom = 12;
  res = add_fractions(f1, f2);
  printf(" %d/%d + %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 1; f1.denom = 3;
  f2.numer = 5; f2.denom = 6;
  res = add_fractions(f1, f2);
  printf(" %d/%d + %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 35; f1.denom = 100;
  f2.numer = 1; f2.denom = 4;
  res = subtract_fractions(f1, f2);
  printf(" %d/%d - %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 7; f1.denom = 10;
  f2.numer = 1; f2.denom = 2;
  res = subtract_fractions(f1, f2);
  printf(" %d/%d - %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 1; f1.denom = 2;
  f2.numer = 1; f2.denom = 2;
  res = multiply_fractions(f1, f2);
  printf(" %d/%d x %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 12; f1.denom = 5;
  f2.numer = 5; f2.denom = 6;
  res = multiply_fractions(f1, f2);
  printf(" %d/%d x %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 12; f1.denom = 21;
  f2.numer = 7; f2.denom = 4;
  res = multiply_fractions(f1, f2);
  printf(" %d/%d x %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

  f1.numer = 1; f1.denom = 5;
  f2.numer = 1; f2.denom = 5;
  res = divide_fractions(f1, f2);
  printf(" %d/%d / %d/%d = %d/%d \n", f1.numer, f1.denom, f2.numer, f2.denom, res.numer, res.denom);

}
于 2015-12-28T07:53:22.880 回答