【问题标题】:Finding ratio of 2 numbers in C++在 C++ 中查找 2 个数字的比率
【发布时间】:2021-06-06 08:56:13
【问题描述】:

我目前正在使用 Bjarne Stroustrup 的 PPP 学习 C++。有一道练习题:

编写一个程序,提示用户输入两个整数值。 将这些值存储在名为 val1 和 val2 的 int 变量中。写你的 程序来确定更小、更大、和、差、积和 比率并将它们报告给用户。

对于比率,我希望它类似于The ratio of 500 and 700 is 5:7。我知道这个答案可能是

double ratio = 500/700;

但我想将其显示为 5:7 而不是 500/700 = 0.714

我该怎么做?

编辑:- 我就是这样做的。

#include <iostream>
#include <cmath>

void Ratio(double val1, double val2)
{
    double temp1 = val1;
    double temp2 = val2;
    for(int num = 0; num < 20; num++)
    {
        if(num == 0 || num == 1)
            continue;

        if(std::fmod(temp1, num) == 0 && std::fmod(temp1, num) == 0) 
        {
            temp1 /= num;
            temp1 /= num;
            num = 0;
        }
    } 
    std::cout<<"Ratio of " << val1 << " and " << val2 << " is " << val1 << ":" << val2<< std::endl;
}

int main()
{
    Ratio(500, 700);
}

我仍然是编程的初学者,这对我来说真的很重要。 任何人都有更好的解决方案。

【问题讨论】:

  • 这能回答你的问题吗? Converting floating ratios to int
  • 您可以将(整数?)val1val2 除以 gcd 以简化表达式。
  • 任务要求您输入 integer 值并且您正在使用 double 精度 floating 点数,所以我不认为这是有效的。如果您想要一个形式上有效的解决方案,则必须考虑欧几里得算法,但这肯定不是这里的任务。
  • 请注意,double ratio = 500/700; 会将双精度 ratio 设置为 0
  • C++17 起,std::gcd(500,700) == 100.

标签: c++ math


【解决方案1】:

正如@Dominique 指出的那样:

您正在使用错误的算法:为了找到比率 在ab 两个数字之间,你正在做:

calculate a/b; 
do something with the result.

这不起作用,因为 计算机不理解有理数(在数学中,1/3 是 与0.333333333 不同,但对于计算机来说两者是相等的,因为 计算机无法处理无限小数)。

您想要的是simplified a fraction(将其简化为最简单的形式)。为此,您可以将ab 除以gcd(a,b)。两个数的gcd()可以用Euclidean algorithm计算,也可以直接用__gcd() function计算。

代码:

#include <iostream>
#include <cmath>
using namespace std;

int gcd(int a, int b)
{
    if (b == 0) {return a;}
    return gcd(b, a%b);
}

pair<int, int> ratioFunc(int a, int b)
{
    pair<int, int> ret;
    if (a == 0)
    {
        ret.first = 0; ret.second = b;
    }
    else
    {
        int gc = gcd(abs(a),abs(b));
        a /= gc; b /= gc;
        ret.first = a; ret.second = b;
    }
    return ret;

}

int main()
{
    int a,b; cin >> a >> b;
    if (b == 0) {cout << "No answer";}
    else {auto res = ratioFunc(a,b); cout << "The ratio of " << a << " and " << b << " is " << res.first << ":" << res.second;}
}

输出:

500 700
The ratio of 500 and 700 is 5:7

输出(负整数):

-33 27
The ratio of -33 and 27 is -11:9

如果您还没有使用过pair,您可以立即打印:

void ratioFunc(int a, int b)
{
    if (b == 0) {cout << "No answer";}
    else
    {

        if (a == 0) {cout << "The ratio of " << a << " and " << b << " is " << a << ":" << b; return; }

        int x = a, y = b; //Storing a,b for printing
        int gc = gcd(abs(a),abs(b));
        a /= gc; b /= gc;

        cout << "The ratio of " << x << " and " << y << " is " << a << ":" << b;
    }
}

【讨论】:

  • 我刚开始使用 c++,目前不了解算法。你的回答对我很有帮助。
  • 我刚刚重新阅读了我的答案,我意识到我的错误:正确的缩写是来自“Greatest Common Dividor”的“gcd”,而不是来自“Grootste Gemene Deler”的“ggd”(我有荷兰语作为母语):-)
  • @Dominique 我注意到了,但我只是假设它是某种形式的gcd。例如,在我的国家,学生实际上称它为 hcf 而不是 gcd :)
【解决方案2】:

您正在使用错误的算法:为了找到两个数字之间的比率 ab,您正在这样做:

calculate a/b;
do something with the result.

这是行不通的,因为计算机不理解有理数(在数学中,1/3 is different from 0.333333333,但对于计算机来说两者是相等的,因为计算机无法处理无限小数)。

因此需要采用另一种算法,如下:

calculate the greatest common divisor of a and b (ggd(a,b))
Show: a / ggd(a,b)
      b / ggd(a,b)

【讨论】:

    【解决方案3】:

    正如这里许多朋友所建议的,您可以使用 gcd 在循环中查找和划分步骤,直到 gcd 为 1,但它可能不是最佳的。

    我认为最佳算法是将两个数字分解并去除公因子,然后将剩余的因子相乘并为每个数字打印出来。

    伪代码如下所示:

    1. input a and b
    2. list a_factors := all factors of a
    3. list b_factors := all factors of b
    4. subprog: remove common elements in a_factors and b_factors
    5. let a := multiplication of all remaining elements in a_factors
    6. let b := multiplication of all remaining elements in b_factors
    7. output a and b
    

    【讨论】:

    • gcd-方法不是一些迭代方案。最大公约数被计算一次,然后将其除以立即将比率降低到最低项。
    • @N.Wouda,谢谢你的提示,显然我认为 gcd 返回最大因素是错误的,所以我调整了我的答案。尽管如此,我认为 gcd 方法可能在某种程度上不是最佳的,但仍然非常简短且功能强大,可以解决问题。
    • 找出答案的一种方法是对这两种方法进行基准测试。但我非常怀疑这种方法 - 对两个数字进行完全分解 - 优于欧几里德算法的一种应用,除了最小整数。
    • @N.Wouda,我同意基准测试会响亮,但我认为这个算法至少不会比 gcd 差,因为它没有缺陷,而 gcd 本身已经很复杂,有很多乘法和除法。
    • 比较例如this,或this。我想你会发现大多数整数分解算法都包括,正如你所说的,很多乘法和除法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    相关资源
    最近更新 更多