“如何编写一个算法,给定数字n,打印出所有具有分母1..n的简化粗俗分数
(我希望我能说得好,请随意改写。)
示例:如果n为3,则输出应为“1/2 1/3 2/3”
我们在最后一堂课结束时谈论这个问题。他向我们展示了一个解决方案,并要求我们尝试理解代码。这是:
#include<stdio.h>
void main()
{
int p,m,n,i,j,a,b;
p=7;
m=0;
n=1;
do
{
printf("%d/%d\n",m,n);
i=j=1;
for(b=2; b<=p; b++)
{
a=m*b/n+1;
if(a*j<b*i)
{
i=a;
j=b;
}
}
m=i;
n=j;
}
while(i<j);
}
我是C的新手,只是学习编码,说实话我无法弄清楚这段代码的作用。它还打印“0/1”,我也想知道为什么会这样,我认为它不应该打印出来。
以下是解决此问题的基本方法:
#include <stdio.h>
int gcd(int a, int b) // Finds the GCD of two numbers.
{
int temp;
while (a) {
temp = a;
a = b % a;
b = temp;
}
return b;
}
int main(void)
{
int i, j;
for (i = 1; i <= 7; i++) // Denominator goes from 1 to 7
for (j = 1; j < i; j++) // Numerator goes from 1 to denominator
if (gcd(i, j) == 1)
printf("%d/%d ", j, i); // If the numerator and the denominator
// are coprimes then print the fraction
return 0;
}
“n”在两个代码中均为7。我用更大的数字检查了执行时间,我的算法比另一个快。所以我不明白其他代码是什么。此外,对我的代码的任何建议/更正表示赞赏。
答案 0 :(得分:3)
你教授的代码看起来可能是故意复杂的,也许是作为一种学习练习。如果是这样的话,我不能说我同意这种做法。
嵌套for循环的方法正是我接触解决方案的方法。
它还会打印“0/1”,我也想知道为什么会这样,我认为它不应该打印出来。
简单地说,由于这一行,它打印“0/1”:
printf("%d/%d\n",m,n);
值m和n在do循环之前被初始化为0和1,因此在第一次传递时它会完全打印出来。
答案 1 :(得分:2)
您的代码在几个方面优于第一次粘贴。 b
上的循环是尝试为m
和n
找到共同素数因子的一种蹩脚方式。但它只运行到b=7
,因此第一个程序可以打印11/121
和其他非减少分数!
如果b
上的循环已正确编码,则需要O(sqrt(n))
次。您的gcd()
(使用欧几里得算法)的时间为O(log(n))
。
答案 2 :(得分:1)
其他代码编写得异常糟糕。非惯用的单字母变量? void main()?没意见?不应该期望任何人理解该代码,尤其不是学习者。
您的代码似乎非常称职 - 它比其他代码更清晰,更清晰,并且在各方面都非常优越。我要做的唯一建议是,首先,你应该从控制台输入N作为用户输入,以便更简单地重新运行不同值的程序,你还应该注释GCD函数来解释它的操作。