带有std :: map的C ++向量?

时间:2017-08-26 19:21:06

标签: c++ c++11 vector

我的功能如下:

bool getPair(std::vector<std::vector<unsigned short>>Cards) {
std::sort(Cards.begin(), Cards.end(), Cardsort);
std::map<unsigned short, int>Counter;
for (int i = 0; i < 6; i++)
    Counter[Cards[i][0]];
for (const auto& val : Counter) {
    if (val.second == 2)
        return true;
}
return false;
}

我非常确定我错误地使用std::map,我基本上都有这样的矢量设置:

{{2,0},{3,0},{4,1},{3,0},{4,0},{5,0},{6,0}}

其中第一个数字代表值,第二个代表卡片套装。我现在意识到我应该使用一个可能使这个问题不那么复杂的对象,但现在我试图用std::map来计算值出现的次数,如果它出现两次,它show return true(在向量中它将在3处返回true)但我不认为我正确地使用std::map

我想知道卡片[i] [0]中卡片是否有多个相同的变量,我不关心卡片中的重复[i] [1]

3 个答案:

答案 0 :(得分:2)

测试过并且有效。突出显示修复

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

using namespace std;

bool getPair(std::vector<std::vector<unsigned short>>Cards) {
std::sort(Cards.begin(), Cards.end());
std::map<unsigned short, int>Counter;
for (int i = 0; i < 6; i++)
    Counter[Cards[i][0]]++;   // ++++++++++++++++++ need to alter the value!
for (const auto& val : Counter) {
    if (val.second == 2)
        return true;
}
return false;
}

int main() {
    // your code goes here
    // {{2,0},{3,0},{4,1},{3,0},{4,0},{5,0},{6,0}}
    std::vector<std::vector<unsigned short>> c = {{2,0},{3,0},{4,1},{3,0},{4,0},{5,0},{6,0}};
    std::cout << getPair(c);
    return 0;
}

答案 1 :(得分:1)

这是我的建议。

一些评论:

  • 为什么要使用两个循环?您已经有要检查的地图条目,因为您想要增加它,因此您可以在计数循环中检查双精度对称。无需第二次运行。这种方式便宜得多。
  • 我将vector参数更改为const&amp ;.按价值传递这样的东西是一个非常糟糕的主意,至少我不明白为什么在那种情况下这是合适的
  • 我遗漏了排序的东西,无法看到它需要什么,只需重新插入它,如果有必要的话。排序非常昂贵。
  • 你是对的,因为std :: containers不需要初始化,它们被正确初始化,分配器调用新元素的构造函数,例如,例如int这就是一个原因,例如: int得到了一个默认的构造函数语法,你可以编写像auto a = int();这样有趣的东西。
  • 访问地图中不存在的密钥只是创建它们
  • 使用集合和计数肯定不会产生更好的性能

我认为代码很容易阅读,你在这里:

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

bool getPair(const std::vector<std::vector<unsigned short>>& cards) {
    std::map<unsigned short, int> counts;
    for(const auto& n : cards) {
        if(++counts[n[0]] == 2)
            return true;
    }
    return false;
}

int main()
{
   std::vector<std::vector<unsigned short>> cards1 = {{2,0},{3,0},{4,1},{3,0},{4,0},{5,0},{6,0}};
   std::vector<std::vector<unsigned short>> cards2 = {{1,0},{2,0},{4,1},{3,0},{5,0},{7,0},{6,0}};
   std::cout << getPair(cards1) << "\n";
   std::cout << getPair(cards2) << "\n";

   return 0;
}

编辑: 引用C++14 Standard关于访问std :: map的现有成员,仅为了完整性:

23.4.4.3地图元素访问[map.access] T&安培; operator [](const key_type&amp; x);

  • 效果:如果地图中没有等效于x的键,则将value_type(x,T())插入到地图中。
  • 要求:key_type应为CopyInsertable,而mapped_type应为DefaultInsertable *此。
  • 返回:对* this中的x对应的mapped_type的引用。
  • 复杂性:对数.23.4.4.3地图元素访问

答案 2 :(得分:0)

首先,你在Counter中解决了未初始化的变量,然后你真的没有对它做任何事情(你为什么要运行到6而不是Cards.size()?你的数组的大小为7 BTW。还有为什么有那里有某种?你不需要它。):

std::map<unsigned short, int>Counter;
for (int i = 0; i < 6; i++)
     Counter[Cards[i][0]];

他们可能会将未初始化的变量自动设置为0或者它们可能不会 - 它取决于实现,因为它没有被指定为我所知(在Debug中他们确实将它设置为0但我怀疑发布版本) 。您需要按如下方式重写代码,以使其在所有情况下都能100%运行:

std::map<unsigned short, int> Counter;
for (int i = 0; i < (int)Cards.size(); i++)
{
    unsigned short card = Cards[i][0];

    auto itr = Counter.find(card);
    if(itr == Counter.end())
         Counter[card] = 1;
    else
         itr->second++;
}

我建议使用std :: set执行此任务:

std::set<unsigned short> Counter;
for (int i = 0; i < (int)Cards.size(); i++)
{
    unsigned short card = Cards[i][0];
    if(Counter.count(card)>0)
    {
          return true;
    }
    Counter.insert(card);
}
return false;