【问题标题】:if statement inside of for loop not being executedfor循环内的if语句未执行
【发布时间】:2020-08-15 03:04:16
【问题描述】:

编写程序解决欧拉项目的问题四:找到由两个 2 位数字的乘积构成的最大回文。这是我的代表:

#include <iostream>

int reverseNumber(int testNum)
{

    int reversedNum, remainder = 0;
    int temp = testNum;

    while(temp != 0)
    {
        remainder = temp % 10;
        reversedNum = reversedNum * 10 + remainder;
        temp /= 10;
    }

    return reversedNum;
}

int main()
{
    const int MIN = 100;
    int numOne = 99;
    int product = 0;

    for(int numTwo = 10; numTwo < 100; numTwo++)
    {
        product = numOne * numTwo;

        if (reverseNumber(product) == product)
        {
            int solution = product;
            std::cout << solution << '\n';
            return 0;
        }        
    }

    return 0;
}

我的主要思考过程是 for 循环将遍历从 10 到 99 的每个数字并将其乘以 99。我的预期结果是打印 9009,这是最大的回文数,有 2 个 2 位数。所以我认为这里应该发生的是 for 循环将从 10 变为 99,并且每个循环都应该通过 if 语句的参数来反转数字并查看它是否等于自身。 我确定这不是编译器问题,因为这在不同的编译器之间反复出现。 reverseNumber() 函数每次我测试它时都会返回正确的数字,所以这不应该是问题,但是这个问题只发生在函数涉及逻辑比较时。我的意思是即使我将它设置为一个变量并将该变量放入 if 参数中,问题仍然存在。我很难过。我只是希望这不是什么愚蠢的错误,因为我已经做了几天了。

【问题讨论】:

  • 您似乎未初始化变量reversedNum
  • 要开始调试此代码,请查看if 语句。它取决于两个值:product 的值和reverseNumber(product) 的值。所以如果if 语句有问题,要么是因为product 的值不是你所期望的,要么是因为reverseNumber(product) 返回的值不是你所期望的。所以首先要做的是查看reverseNumber(product)返回的值。首先添加一个输出语句,为循环的每次迭代写出product 的值和reverseNumber(product) 返回的值。

标签: c++ function for-loop if-statement


【解决方案1】:
int reversedNum, remainder = 0;

您应该知道,这给您(在自动变量上下文中)一个零 remainder 而是一个 任意 reversedNum。这实际上是一些开发商店有“每个声明一个变量”规则的原因之一。

换句话说,应该是:

int reversedNum = 0, remainder;

甚至:

int reversedNum = 0;
int remainder;

另一件经常有帮助的事情是将变量的范围限制在尽可能小的区域内,仅在需要时才使它们存在。一个例子是:

int reverseNumber(int testNum) {
    int reversedNum = 0;

    while (testNum != 0) {
        int remainder = testNum % 10;
        reversedNum = reversedNum * 10 + remainder;
        testNum /= 10;
    }

    return reversedNum;
}

事实上,我可能会更进一步,完全消除remainder,因为你只使用它一次:

reversedNum = reversedNum * 10 + testNum % 10;

你会注意到我在那里也删除了temp。将testNum 放入临时变量几乎没有什么好处,因为它已经是原始变量的副本(因为它是按值传递的)。


还有一个注意事项,更多的是与问题而不是代码有关。您似乎假设有一个回文是99 的倍数。 可能是这样,但谨慎的程序员不会依赖它 - 如果允许您假设这样的事情,您可以将整个程序替换为:

print 9009

因此您可能应该检查所有可能性。

你还会得到你找到的第一个不一定是最高的(例如,假设 99 * 1799 * 29 都是回文 - 你不想要第一个。

而且,由于您正在检查所有可能性,您可能希望在第一个处停止,即使嵌套循环正在递减而不是递增。这是因为,如果 99 * 397 * 97 都是回文,那么您希望最高, 而不是第一个。

因此,更好的方法可能是从高处开始并进行详尽的搜索,同时确保您忽略小于当前最大值的候选者的回文检查,例如(伪代码)

# Current highest palindrome.

high = -1

# Check in reverse order, to quickly get a relatively high one.

for num1 in 99 .. 0 inclusive:
    # Only need to check num2 values <= num1: if there was a
    # better palindrome at (num2 * num1), we would have
    # already found in with (num1 * num2).

    for num2 in num1 .. 0 inclusive:
        mult = num1 * num2

        # Don't waste time doing palindrome check if it's
        # not greater than current maximum - we can't use
        # it then anyway. Also, if we find one, it's the
        # highest possible for THIS num1 value (since num2
        # is decreasing), so we can exit the num2 loop
        # right away.

        if mult > high:
            if mult == reversed(mult):
                high = mult
                break

if high >= 0:
    print "Solution is ", high
else:
    print "No solution"

【讨论】:

  • 天哪,它做到了!这么小的细节……介意解释一下为什么会有这么大的不同吗?
【解决方案2】:

除了正确初始化你的变量,如果你想要最大的回文,你应该切换你的 for 循环的方向——比如:

for(int numTwo = 100; numTwo > 10; numTwo--) { 
    ...
}

否则你只是打印指定范围内的第一个回文

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多