You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++实现Bulls & Cows游戏遇逻辑错误及代码精简咨询

解决 Bulls & Cows 中的奶牛计数问题及代码精简建议

看起来你遇到的问题很典型——奶牛计数时漏算了一个匹配项。让我们先拆解问题原因,再给出修复方案和代码优化建议。

问题原因分析

你提到用4321测试时(假设秘密数字是1234),预期0 bulls and 4 cows但实际得到3 cows,大概率是你的奶牛计数逻辑存在单向匹配或未覆盖所有位置的问题:

  • 比如你的代码可能只检查猜测数字是否在秘密数字的后续位置(比如j从i+1开始遍历),而忽略了前面的位置;
  • 或者没有标记已匹配的数字(不过在无重复数字的场景下,这个问题不会显现,但如果有重复数字会导致重复计数)。

举个反例,如果你的奶牛检查逻辑是这样的:

for (int i = 0; i < 4; ++i) {
    if (secret[i] == guess[i]) {
        bulls++;
    } else {
        // 只检查当前索引之后的位置,导致前面的匹配项被遗漏
        for (int j = i + 1; j < 4; ++j) {
            if (secret[j] == guess[i]) {
                cows++;
                break;
            }
        }
    }
}

那猜测的最后一个数字1就无法匹配秘密数字的第一个1(因为j从4开始,超出范围),最终奶牛数少1。

正确的逻辑实现

计算公牛和奶牛的标准方法是:

  1. 先统计公牛:遍历每个位置,数字和索引都匹配的计数加1;
  2. 统计总共有多少共同数字:用两个计数数组(或哈希表)统计秘密数字和猜测数字中0-9每个数字出现的次数,然后对每个数字取最小值相加,得到总匹配数;
  3. 奶牛数 = 总匹配数 - 公牛数:这样就能自动排除已经被算作公牛的数字,同时避免重复计数。

修复后的代码示例

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

pair<int, int> calculateBullsAndCows(const vector<int>& secret, const vector<int>& guess) {
    int bulls = 0;
    vector<int> secretCount(10, 0), guessCount(10, 0);

    // 统计公牛和数字出现次数
    for (int i = 0; i < secret.size(); ++i) {
        if (secret[i] == guess[i]) {
            bulls++;
        } else {
            secretCount[secret[i]]++;
            guessCount[guess[i]]++;
        }
    }

    // 统计奶牛
    int cows = 0;
    for (int i = 0; i < 10; ++i) {
        cows += min(secretCount[i], guessCount[i]);
    }

    return {bulls, cows};
}

int main() {
    vector<int> secret = {1, 2, 3, 4};
    vector<int> guess = {4, 3, 2, 1};

    // C++17及以上支持结构化绑定,旧标准可改用pair的first/second
    auto [bulls, cows] = calculateBullsAndCows(secret, guess);

    cout << bulls << " bulls and " << cows << " cows" << endl;
    // 输出:0 bulls and 4 cows
    return 0;
}

代码精简建议

  1. 使用结构化绑定(C++17+):直接解构pair返回值,让代码更简洁;
  2. 避免嵌套循环:用计数数组替代双层循环,时间复杂度从O(n²)降到O(n),效率更高;
  3. 参数抽象:把计算逻辑封装成函数,复用性更强;
  4. 利用标准库函数:比如std::min简化计数逻辑,避免手动判断大小;
  5. 兼容重复数字场景:这个逻辑天然支持有重复数字的情况(比如秘密数字1122,猜测2211,结果是0 bulls and 4 cows),而原始逻辑如果没处理重复的话会出错。

内容的提问来源于stack exchange,提问作者mchd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:45:18