【问题标题】:Why is this giving runtime error?? I think i'm write with the loops then too为什么这会给出运行时错误?我想我也在用循环写
【发布时间】:2021-12-23 22:57:33
【问题描述】:
vector<int> matchingStrings(vector<string> s, vector<string> q) {
        
        vector<int> res;
        map<string, int> mp;
        for(int i = 0 ; i < s.size();i++){
            mp[s[i]]++;
        }
        
        for(int i = 0 ; i < q.size();i++){
                res[i] = mp[q[i]]; 
        }
        return res;
}

【问题讨论】:

  • 向量res。所有对它的索引都将超出范围并导致未定义的行为
  • std::map在内部添加一个新元素,如果与operator[]一起使用的键不存在,std::vector需要在使用operator[]获取元素之前填充。
  • 如有疑问,请提取minimal reproducible example。这样的问题不仅需要它,它还可以帮助您理解问题。作为这里的新用户,请同时关注tour并阅读How to Ask

标签: c++ string stl


【解决方案1】:

问题是你有一个空向量,并写:

res[i];

您正在尝试访问其不存在的 ith 元素。 您可以通过在res 上使用push_back解决此问题,如下所示:

res.push_back(mp[q[i]]);//you could use emplace_back here instead

我还想在这里给出 2 条建议:

  1. 当您不想创建无意的元素时,在std::map 上使用.at() 而不是[]

  2. 在这种情况下,您也可以使用emplace_back 代替push_back

考虑到建议的第 2 点,您可以将上述建议语句写成:

res.emplace_back(mp[q[i]]); //use .at() only if you don't want to create/add elements into the map and just want to read

所以修改后的代码如下:

vector<int> matchingStrings(vector<string> s, vector<string> q) {
        
        vector<int> res;//res is an empty vector
        map<string, int> mp;
        for(int i = 0 ; i < s.size();i++){
            mp[s[i]]++;
        }
        
        for(int i = 0 ; i < q.size();i++){
                res.emplace_back(mp[q[i]]); //used emplace_back
        }
        return res;
}

替代解决方案

创建具有特定大小的res

vector<int> res(q.size());//res has size equal to q's size

现在您可以安全地使用res[i];,并且不需要使用push_backemplace_back

所以修改后的代码如下:

vector<int> matchingStrings(vector<string> s, vector<string> q) {
        
        vector<int> res(q.size());//res has size q
        map<string, int> mp;
        for(int i = 0 ; i < s.size();i++){
            mp[s[i]]++;
        }
        
        for(int i = 0 ; i < q.size();i++){
                res[i] = mp[q[i]]; //res[i] is fine now 
        }
        return res;
}

【讨论】:

  • 如果他使用的是 c++ 11 或更高版本,您也可以建议 emplace_back。此外,始终使用 c++ 11 或更高版本还可以避免使用旧样式迭代 qs,而是使用 range-based for
  • @IkarusDeveloper 是的,我现在在答案末尾添加了 2 条建议,请检查(编辑后的答案)。
  • 另一种可能的解决方案是在创建向量时设置大小,如std::vector&lt;int&gt; res(q.size());
  • 我认为建议是在地图中添加新元素,因此使用std::map::at 他会破坏代码。
  • @IkarusDeveloper 在第二个 for 循环中,我不认为目的是将新元素添加到地图中。无论如何,如果目的是添加新元素,那么他/她不要使用at(),正如我在第一个建议中已经写的那样,只要你不想创建无意的元素
【解决方案2】:

除了@Anoop Rana 的回答之外,我认为您还可以通过使用std::count(自c++17 起)来减少对给定函数进行编码的工作量。

std::vector<int> matchingStrings(const std::vector<string>& s, const std::vector<string>& q) {
    std::vector<int> ret{};
    ret.reserve(q.size());
    for(auto& str: q)
        ret.emplace_back(std::count(s.begin(), s.end(), str));
    return ret;
}

注意:使用 const std::vector&lt;string&gt;&amp; 可以避免在使用匹配字符串时复制值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多