【问题标题】:Write a function that computes and returns the total number of integers between two target numbers that are divisible by 3编写一个函数,计算并返回两个可被 3 整除的目标数之间的整数总数
【发布时间】:2019-10-20 19:49:04
【问题描述】:

我被指派编写这段代码,起初它看起来很简单。我把它写出来,并尽我所能去理解它,我真的以为我把它记下来了。但是当我尝试使用VisualStudio检查代码时,弹出代码错误并且代码无法完成处理。

这是作业:

编写一个名为 specialNumbers 的函数,该函数计算并返回两个可被 3 整除的目标数之间的整数总数。该函数有两个参数: 1. 开始,整数 2. end,大于 start 的整数 该函数返回 start 和 end 之间的 3 的倍数的总数,包括 start 和 end。 例如,如果 start=3,end=10,则函数将返回 3。

这是我目前的代码:

#include <iostream>
using namespace std;

int specialNumbers(int start, int end) {
    int count = 0;
    for (int i = start; i < end; i++) {
        if (i % 3 == 0)
            count++;
    }
    return count;
} 

int main() {
    int a, b;
    cout << "Enter two numbers to find total number of integars divisble by 3 between them" << endl;
    cin >> a, b;
    int n = specialNumbers(a, b);
    cout << "Number of integars divisible by 3 between" << a << "and" << b << "are" << n << endl;
    return 0;
}

显示的错误是

调试错误!变量b被使用了,没有初始化

【问题讨论】:

  • 请显示错误。
  • cin &gt;&gt; a &gt;&gt; b;
  • 它说变量 b 正在使用但尚未初始化但我认为我已正确初始化它
  • @suspectus 非常感谢你,我应该多看一看
  • 在上交作品之前,请注意您的算法也有错误。例如,如果数字是 4 和 6,它会在应该返回 1 时返回 0

标签: c++ function


【解决方案1】:

您使用错误的语法从 cin 中提取两个整数,应该是:

cin >> a >> b;

由于comma operator 的语义,您的代码给出了“未初始化错误”,它接受两个参数并返回后者。

简单来说,你的代码相当于:

(cin >> a), b;  // ERROR: `b` isn't being initialized.

【讨论】:

  • 不错的答案。我希望未初始化的消息将是警告,而不是错误(除非警告被视为 OP 设置中的错误)。
【解决方案2】:

其他答案解决了cin 的正确使用问题,但也存在算法错误。如果最后一个数字是 3 的倍数,则代码返回不正确的结果。

例如,如果你输入数字 4 和 6,当 6 是 3 的倍数时它会返回 0,而它应该返回 1。

这可以通过更改来纠正:

for (int i = start; i < end; i++) {

for (int i = start; i <= end; i++) {

但是,当整数相距很远时,该算法的效率极低。例如,如果它们是 15 和 2,000,000,000,则检查每个整数将非常耗时。这就像通过一次又一次地添加一个数字来将两个数字相乘。

此代码首先注意到,如果从开始值和结束值中都减去 3 的倍数,则可被 3 整除的值的数量将保持不变。

其次,在这样做之后,包含在 start 和 end 之间的值的数量将恰好是 end/3 的值,如果 start==0 加一

因此,此代码将产生正确答案而无需循环:

#include <iostream>
using namespace std;

int specialNumbers(int start, int end) {
    int adj = 3 * (start / 3);  // find and remove the multiples of 3 from start and end
    start = start - adj;        // start will now be either 0, 1 or 2
    end = end - adj;
    int count = end / 3;        // count is the number of exact multiples of 3 in the sequence
    if (start == 0)             // unless the adjusted start is zero in which case it must be incremented
        count++;
    return count;
    }

int main() {
    int a, b;
    while (1) {
        cout << "Enter two numbers to find total number of integars divisble by 3 between them" << endl;
        cin >> a >> b;
        int n = specialNumbers(a, b);
        cout << "Number of integars divisible by 3 between" << a << "and" << b << "are" << n << endl;
    }
    return 0;
}

【讨论】:

  • 或者只是count = end/3 - (start-1)/3。或者count = end/3 - (start+2)/3 + 1,应对特殊情况start=0
  • @TonyK 是的。特殊情况发生的时间为 1/3,因此非常重要。我把它分解成,希望清楚。实际上让我感到惊讶的是,这个问题和答案让这样的错误逃脱通知如此之久。 SO 贡献者通常是最重要的。
  • 特例不是(start % 3) == 0,只是start == 0。所以它可能不会发生三分之一的时间。
  • @TonyK 调整后,start 为 0、1 或 2,假设原始 start 和 end 是随机分布的,分布相等。所以概率是1/3。然而,虽然我已经注意到调整后的开始在 0,1 和 2 范围内,但模运算符是多余的,所以表达式 start % 3==0 s/b 只是 start==0 感谢您指出这一点。我会编辑答案。
  • 我的 start 未调整。所以它可以取任何非负值,而不仅仅是 0-2。
【解决方案3】:

改变改变这个:

cin >> a, b;

到:

cin >> a >> b;

因为在这种情况下您绝对不想要逗号运算符,而是 &gt;&gt; 运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多