如何比较存储在指针实例中的2个分数? 考虑以下代码:
struct frac {
int num;
int denom;
};
我们需要实现:如果* a等于* b,fr_equal(a,b)返回true。
bool fr_equal(const struct frac *a, const struct frac *b);
我在这方面遇到了困难,我的代码如下:
bool fr_equal(const struct frac *a, const struct frac *b) {
if ( (*a).num != 0 && (*b).num !=0)
{
int x = (*a).num;
int y = (*a).denom;
int m = (*b).num;
int n = (*b).denom;
if (x==m && y==n )
return true;
if (x%y==0)
y=y/x;
else
return false;
}
else
{
return false;
}
}
我的代码不完整,因为我还没有理解如何继续以及所有需要考虑的案例。我可以有4个案例但是时间太长了。
任何人都可以告诉我一个短而有效的方法
谢谢!
答案 0 :(得分:1)
我真的不明白你的其他代码试图做什么。
根据你的解释,你不能这样做:
bool fr_equal(const struct frac *a, const struct frac *b)
{
return a->num == b->num && a->denom == b->denom;
}
如果你试图用可减少的分数来解释数学上的等价,我认为来自void_ptr的这个建议会涵盖它。
bool fr_equal(const struct frac *a, const struct frac *b)
{
return (a->num * b->denom) == (b->num * a->denom);
}
在我考虑它时,以下也应该是一种有效的方法,尽管它需要一些额外的错误检查来防止除以零。
bool fr_equal(const struct frac *a, const struct frac *b)
{
// WARNING: Needs to include code to avoid divide by zero
return ((double)a->num / a->denom) == ((double)b->num / a->denom);
}
答案 1 :(得分:1)
如果你的函数有两个未完全缩小的分数,你可以使用gcd算法:
int gcd(int a, int b) {
if (a == 0) return b;
return gcd(b % a, a);
}
然后在你的函数中,使用:
找到你的分子和分母的gcdint r_factor = gcd(a->num, a->denom);
并减少你的分数。
接下来,你对b做同样的事情,并比较两者。
bool fr_equal(const struct frac *a, const struct frac *b) {
int r_factor = gcd(a->num, a->denom);
a->num /= r_factor;
a->denom /= r_factor;
r_factor = gcd(b->num, b->denom);
b->num /= r_factor;
b->denom /= r_factor;
return (a->num == b->num && a->denom == b->denom);
}
答案 2 :(得分:1)
将a / b与c / d进行相等比较的有效方法是比较 d == b c。但是,这比较慢的方法会更快地溢出。如果你有C99支持和<stdint.h>
标题,你可以使用int32_t作为分子和分母,然后:
bool fr_equal(const frac *lh, const frac *rh)
{
return (int64_t)lh->num*rh->denom == (int64_t)rh->num*lh->denom;
}
否则,最好转换为double而不是int64_t。这与现代台式机/笔记本电脑处理器上的64位int算法一样快(可能不是在低功耗移动设备上,在嵌入式处理器上也不太可能),因此除了误差之外,对于非常接近相等的分数而言,除了大共同点。
如果您已安排类型以使分母始终为正,您也可以进行有序比较。例如,a / b < c / d iff ad&lt; bc,条件是bd> 0。