使用C高效方法中的指针程序比较分数

时间:2015-02-27 21:45:48

标签: c

如何比较存储在指针实例中的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个案例但是时间太长了。

任何人都可以告诉我一个短而有效的方法

谢谢!

3 个答案:

答案 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);
}

然后在你的函数中,使用:

找到你的分子和分母的gcd
int 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。