我在分配时遇到了很大的困难:
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) * b
的LCM(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
)或自由形式的输入(带scanf
或fscanf
)中的一种并坚持下去。%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);
}