首页 > 解决方案 > 无法获得问题所需的输出

问题描述

我试图在这里解决一个问题。我有两个数组需要添加并产生所需的输出。{'A','A','A','B','A','X','M'} 和 {'A','B','A','A','B' ,'A','B','B'}。A 的值为 10,B 的值为 20。

如果 A 或 B 连续重复,则添加奖金数字,即 10。我需要得到总分 90 第一和 140 第二的输出。我怎样才能写出完美的代码。

我的代码如下:第一个数组的输出应该是 90,第二个数组的输出应该是 140。X 和 M 的值为 0。所以不要介意他们。

#include <iostream>

int main()
{
    int currentEScore = 0;
    int TotalScore = 0;
    char Box[] = { 'A', 'A', 'A', 'B', 'A', 'X', 'M' };
    // A B A R A R A A
    for (int i = 0; i < Box[i]; i++) {
        if (Box[i] == 'A') {
            currentEScore = 10;
            if (Box[i - 1] == Box[i]) {
                currentEScore += 10;
                TotalScore = TotalScore + currentEScore;
            }
            else {
                TotalScore = TotalScore + currentEScore;
            }
        }
        else if (Box[i] == 'B') {
            currentEScore = 20;
            if (Box[i - 1] == Box[i]) {
                currentEScore += 10;
                TotalScore = TotalScore + currentEScore;
            }
            else {
                TotalScore = TotalScore + currentEScore;
            }
        }
        else {
            currentEScore = 0;
        }
    }

    std::cout << TotalScore;
}

标签: c++

解决方案


首先要做的事情是:您在第一次迭代 ( if (Box[i - 1] == Box[i])) 中越界访问数组。这是未定义的行为,严格来说,您的所有代码都是没有意义的,因为没有强制编译器对无效代码做任何有意义的事情。碰巧这不会影响代码的结果。这是未定义行为的最糟糕体现:它似乎有效。你需要解决这个问题。

接下来,您的循环读取for (int i = 0; i < Box[i]; i++) {并且条件不正确。这再次使您的循环访问数组越界。我有点困惑这是如何工作的(我自己并没有首先意识到这一点)。这也得修!我建议使用std::string字符数组。它更不容易出错,并且它有一种size()方法来获取它的大小。

上述问题并没有影响输出(尽管它们必须被修复!),所以现在让我们看看你的代码的逻辑。但首先是免责声明:我能给你的最好的建议是不要继续阅读这个答案。您面临的问题是学习如何使用调试器的好机会。这是你永远需要的技能。如果您仍然决定阅读以下内容,那么至少您应该尝试忘记此答案所说的所有内容,并通过使用调试器或一张纸和一支笔自行完成相同的过程。

让我们在您的第一个示例中逐步进行{ 'A', 'A', 'A', 'B', 'A', 'X', 'M' }

  • 第一个字符是A
  • if (Box[i] == 'A') -> 条件为真
  • currentEScore = 10;->currentEScoe == 10
  • (我们暂时忽略越界)
  • TotalScore = TotalScore + currentEScore;->TotalScore == 10
  • 下一个字符是A
  • if (Box[i] == 'A') -> 条件为真
  • currentEScore = 10;->currentEScore == 10
  • if (Box[i - 1] == Box[i])-> 是的
  • currentEScore += 10;->currentEScore == 20
  • TotalScore = TotalScore + currentEScore;->TotalScore == 10+20 == 30
  • 下一个字符是A
  • if (Box[i] == 'A') -> 条件为真
  • currentEScore = 10;-> currentEScore == 10-> 停止...这是错误的!

您正在重置每个角色的奖励分数,然后只检查前一个。效果是你永远不会给奖金超过20

解决方案:修复越界访问,仅在角色与上一个不同时重置奖励。此外,代码可以简化一点,通过意识到奖金与角色是A或无关B。您只需要检查它是否与上一个相同,因此可以单独计算奖金A并添加积分:B

#include <iostream>
#include <string>
int main()
{
    int bonus_increment = 10;
    int bonus = 0;
    int score_A = 10;
    int score_B = 20;
    int TotalScore = 0;
    std::string Box{"AAABAXM"};
    for (size_t i = 0; i < Box.size(); i++) {
        // determine bonus
        if ( i > 0 && Box[i] == Box[i-1] ) {
            bonus += bonus_increment;
        } else {
            bonus = 0;
        }
        // accumulate score
        if (Box[i] == 'A') {
            TotalScore += score_A + bonus;
        } else if (Box[i] == 'B') {
            TotalScore += score_B + bonus;
        }
    }
    std::cout << TotalScore;
}

别忘了我上面说的。如果您只是复制此代码并假设您通过这样做完成了练习,那么您将浪费此练习。


推荐阅读