PAYATHON 2026

C++ 如何固定一个 array 的元素并遍历另一个 vector 查找匹配项?

技术老齐

可以用嵌套循环查找共同车型:外层依次取出 mycars 中的车型,内层遍历 yourcars。找到相同车型后输出,再用 break 退出内层循环,继续检查下一个车型。

带空格的名称需要用 std::getline(std::cin, yourcar) 读取整行。执行 std::cin >> n 后,要先清除当前行剩余的内容,再读取车型。

原代码的问题

原来的比较方式:

mycars[i] == yourcars.at(i)

只比较两个容器中位置相同的元素。如果 "911 targa" 在两个列表中的位置不同,就找不到匹配。两个容器长度不同时,还可能发生越界访问。

输入部分也有两个问题:

getline(cin, yourcar, ' ');
cin >> yourcar;
  • getline 的第三个参数是分隔符。指定 ' ' 后,读取会在遇到空格时停止。
  • 随后的 cin >> yourcar 会再次读取并覆盖 yourcar,同样无法读入完整的带空格名称。

cin >> n 通常还会留下用户按回车产生的换行符。此时直接调用 getline,第一次读到的可能就是空字符串。

修改后的完整代码

代码保留原来的普通数组,用范围 for 循环遍历,需要 C++11 或更高版本。

#include <iostream>
#include <limits>
#include <string>
#include <vector>

int main() {
    const std::string mycars[] = {
        "MX5", "560sec", "560sl", "sl65", "lp500",
        "f40", "demon", "6*6", "g550 cab", "u5000",
        "slk500", "sl600", "lc79", "sls", "slr",
        "valkyrie", "cls", "911 targa", "firebird"
    };

    std::vector<std::string> yourcars;

    std::cout << "My dream cars are:\n";
    for (const auto& car : mycars) {
        std::cout << car << '\n';
    }

    int n = 0;
    std::cout << "\nHow many dream cars do you have?\n";

    if (!(std::cin >> n) || n < 0) {
        std::cerr << "Please enter a non-negative integer.\n";
        return 1;
    }

    // 丢弃数量所在行的剩余内容,包括换行符。
    std::cin.ignore(
        std::numeric_limits<std::streamsize>::max(), '\n'
    );

    // 每行输入一个完整的车型名称。
    for (int i = 0; i < n; ++i) {
        std::string yourcar;
        std::cout << "Enter dream car " << i + 1 << ":\n";

        if (!std::getline(std::cin, yourcar)) {
            std::cerr << "Failed to read a car name.\n";
            return 1;
        }

        yourcars.push_back(yourcar);
    }

    bool foundAny = false;

    for (const auto& mycar : mycars) {
        for (const auto& yourcar : yourcars) {
            if (mycar == yourcar) {
                std::cout << "We both share a dream car! It is: "
                          << mycar << '\n';
                foundAny = true;
                break;
            }
        }
    }

    if (!foundAny) {
        std::cout << "We do not share any dream cars.\n";
    }

    return 0;
}

嵌套循环如何完成匹配

外层循环每次取出一个车型,赋给 mycar。内层循环再逐个取出 yourcars 中的元素,与当前的 mycar 比较:

for (const auto& mycar : mycars) {
    for (const auto& yourcar : yourcars) {
        if (mycar == yourcar) {
            // 找到了当前车型。
            break;
        }
    }
}

break 只退出最近一层循环,所以找到匹配后,外层循环会继续处理下一个 mycar。即使用户重复输入同一车型,当前 mycar 也只会输出一次。

foundAny 用来记录整个比较过程中是否找到过匹配。只有完成所有比较,才能判断是否需要输出“没有共同车型”。某一对元素不相等,不能说明两个列表完全没有交集。

例如,依次输入:

3
911 targa
MX5
other car

比较部分会按 mycars 的顺序输出:

We both share a dream car! It is: MX5
We both share a dream car! It is: 911 targa

还需要注意什么

  • 不需要 n++。用户输入多少辆车,循环就读取多少行。
  • 原数组有 19 个元素,i < 18 会漏掉最后一个。范围 for 循环可以直接遍历全部元素。
  • 原代码在 main 开头声明的 int i; 没有初始化。for (int i = ...) 中的 i 是另一个局部变量,因此后面的 if (i > yourcars.size()) 使用了未初始化的值,应删除这套分支。
  • std::string 的 == 比较区分大小写,也会比较空格。"MX5" 与 "mx5" 不相等,getline 保留的名称首尾空格也会影响匹配。
  • 输入时,数量和每个车型名称各占一行。读取数量后调用一次 ignore,之后连续使用 getline 即可。

备注:内容仅供参考。