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

C++统计vector字符串出现次数:越界与最后元素未统计问题

问题描述

自学C++一周,编写了统计vector<string>容器words中各字符串出现次数的代码。当前代码可正常输出「Six」「Three」「Two」的出现次数,但无法输出「One」的统计结果,且程序会因访问vector越界报错。需要解决:在不越界的前提下判断当前元素与下一个元素是否相等,同时确保最后一个元素被正确统计。

原代码如下:

int main()
{
    vector<string> words;
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Three");
    words.push_back("Three");
    words.push_back("Three");
    words.push_back("Two"); 
    words.push_back("Two");
    words.push_back("One");

    vector<int> values; // vector to tracks the # of times a string
                        //appears in the vecotor words

    //create elements in values equal to number of 
    //elements in words
    //note: this creates too many elements
    //I am aware but am a begginner and don't know how
    //to solve this issue
    for (int i = 0; i <= words.size() - 1; i++) 
    {
        values.push_back(0);
    }

    int invariant = 0; // tracks number of times loops
    string current; // used make sure duplicate strings aren't recounted

    while (invariant <= words.size() - 1) 
    {
        //compare each element of words to each other element 
        //one at a time and increment the appropriate
        //element of values if they match
        for (int i = 0; i <= words.size() - 1; i++)
        {
            if (words[invariant] == words[i])
            {
                values[invariant] = values[invariant] + 1;
            }
        }
        //used to check for duplicate strings
        current.clear();
        current = words[invariant];

        if (invariant + 1 > words.size()) //avoids going outside range of words
        {
            return 0; //Errors outside range after this return
        }
        else{
            if (words[invariant+1] == current) // if the next word is the same
            {
                ++invariant;
            }
            else //if the next word is different output the number of times the current word appears
            {
                cout << current << " appears " << values[invariant] << " times.\n";
                ++invariant;
            }
        }
    }
    return 0;
}

注:习惯在循环中使用invariant <= value的写法,若不设置invariant == value - 1程序就会出现越界错误。

问题分析与解决方案

核心问题

  • 越界判断逻辑错误:原代码中invariant + 1 > words.size()的判断无效,当invariant指向最后一个元素(索引为words.size()-1)时,invariant+1等于words.size(),此时访问words[invariant+1]会直接触发越界。
  • 最后一个元素未输出:处理到最后一个元素时,代码直接return 0,导致「One」的统计结果无法输出。
  • 冗余的values容器:创建了与words等长的values容器,实际上只需记录当前字符串的出现次数即可。

修正后的代码

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

using namespace std;

int main()
{
    vector<string> words;
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Six");
    words.push_back("Three");
    words.push_back("Three");
    words.push_back("Three");
    words.push_back("Two"); 
    words.push_back("Two");
    words.push_back("One");

    vector<int> values;
    for (int i = 0; i <= words.size() - 1; i++) 
    {
        values.push_back(0);
    }

    int invariant = 0;
    string current;

    while (invariant <= words.size() - 1) 
    {
        // 统计当前字符串出现次数
        for (int i = 0; i <= words.size() - 1; i++)
        {
            if (words[invariant] == words[i])
            {
                values[invariant]++;
            }
        }
        current = words[invariant];

        // 优先判断是否为最后一个元素,避免越界
        if (invariant == words.size() - 1)
        {
            cout << current << " appears " << values[invariant] << " times.\n";
            ++invariant;
        }
        else
        {
            if (words[invariant+1] == current)
            {
                ++invariant;
            }
            else
            {
                cout << current << " appears " << values[invariant] << " times.\n";
                ++invariant;
            }
        }
    }
    return 0;
}

关键修改点

  • 修正越界问题:新增invariant == words.size() - 1的判断,直接处理最后一个元素的输出,彻底避免访问words[invariant+1]导致的越界。
  • 保留你的循环习惯:依然使用invariant <= words.size() - 1的循环条件,符合你的编程习惯。
  • 确保最后一个元素输出:当invariant指向最后一个元素时,直接输出统计结果,不再提前return。

进阶优化(可选)

如果想简化代码,无需手动处理重复和越界问题,可以用std::map自动统计次数,代码更简洁高效:

#include <iostream>
#include <vector>
#include <string>
#include <map>

using namespace std;

int main()
{
    vector<string> words = {"Six", "Six", "Six", "Six", "Six", "Six", "Three", "Three", "Three", "Two", "Two", "One"};
    
    map<string, int> countMap;
    for (const string& word : words)
    {
        countMap[word]++;
    }

    for (const auto& pair : countMap)
    {
        cout << pair.first << " appears " << pair.second << " times.\n";
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:30:04