C分数算术



我在分配时遇到了很大的困难:
a声明一个包含有理数的数据结构
b编写将+,-,*,/有理数的f'xn
所有的f'xn都必须传递3个参数,每个参数都指向我在a部分声明的类型的数据结构;参数中的2个=操作数,第3个=结果
c编写一个f'xn,它将指向数据结构的指针作为参数,并返回数字的GCD&denom
d使用c部分中的f'xn来编写一个f'xn,它将把分数(有理数)降到最低项。传入一个指向分数的指针,并用f'xn修改分数
e编写输入和输出函数,以便用户可以以1/5的形式输入分数。

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

我走对了吗?我相信我有a-c,但没有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 PROGRAMn");
    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;
}

代码中的一些注释:

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

最后但并非最不重要的是,格式化"%c%*c"以获得y/n问题的答案是可能的,但也是危险的:您可能会将前面输入的新行作为响应!选择面向行的输入(带有fgets+sscanf)或自由形式的输入(带scanffscanf)中的一种并坚持下去。%1s变成char response[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/%dn", compute(f1, f2, PLUS).nom, compute(f1, f2, PLUS).denom);
    printf("Subtraction: %d/%dn", compute(f1, f2, MINUS).nom, compute(f1, f2, MINUS).denom);
    printf("Multiplication: %d/%dn", compute(f1, f2, MULTIPLY).nom, compute(f1, f2, MULTIPLY).denom);
    printf("Division: %d/%dn", compute(f1, f2, DIVIDE).nom, compute(f1, f2, DIVIDE).denom);
    return 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)=%dn", gcd(12,9));
  printf("gcd(9,12)=%dn", gcd(9,12));
  printf("gcd(4,12)=%dn", gcd(4,12));
  printf("gcd(8,12)=%dn", gcd(8,12));
  printf("gcd(12,8)=%dn", gcd(12,8));
  puts("-");
  printf("lcm(12,9)=%dn", lcm(12,9));
  printf("lcm(9,12)=%dn", lcm(9,12));
  printf("lcm(8,12)=%dn", lcm(8,12));
  printf("lcm(12,8)=%dn", lcm(12,8));
  printf("lcm(4,12)=%dn", lcm(4,12));
  printf("lcm(3,5)=%dn", lcm(3,5));
  printf("lcm(4,5)=%dn", lcm(4,5));
  printf("lcm(3,4)=%dn", 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);
}

相关内容

  • 没有找到相关文章

最新更新