简体   繁体   English

c++ 中的无序 map

[英]Unordered map in c++

I am trying to implement this problem in C++ using unordered map :我正在尝试使用unordered map在 C++ 中实现此问题:

Given a non-empty array of integers, every element appears twice except for one.给定一个非空整数数组,每个元素都出现两次,除了一个。 Find that single one.找到那个单一的。

Note:笔记:

Your algorithm should have a linear runtime complexity.您的算法应该具有线性运行时复杂度。 Could you implement it without using extra memory?您能否在不使用额外的 memory 的情况下实现它?

Example 1:示例 1:

Input: [2,2,1]输入:[2,2,1]
Output: 1 Output:1

Example 2:示例 2:

Input: [4,1,2,1,2]输入:[4,1,2,1,2]
Output: 4 Output:4

My solution:我的解决方案:

class Solution {
 public:
  int singleNumber(vector<int>& nums) {
    std::unordered_map<int, int> umap;

    for (auto i = nums.begin(); i != nums.end(); i++) {
      umap[*i] = umap[*i] + 1;
    }

    for (auto i = umap.begin(); i != umap.end(); i++) {
      if (umap[*i] == 1) {
        return *i;
      }
    } 
  }
};

But unfortunately, it does not work.但不幸的是,它不起作用。 I get this error while compiling编译时出现此错误

Line 16: Char 17: fatal error: no viable overloaded operator[] for type 'std::unordered_map'
        if (umap[*i] == 1) {
            ~~~~^~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/unordered_map.h:973:7: note: candidate function not viable: no known conversion from 'std::pair' to 'const std::unordered_map, std::equal_to, std::allocator > >::key_type' (aka 'const int') for 1st argument
      operator[](const key_type& __k)
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/unordered_map.h:977:7: note: candidate function not viable: no known conversion from 'std::pair' to 'std::unordered_map, std::equal_to, std::allocator > >::key_type' (aka 'int') for 1st argument
      operator[](key_type&& __k)
      ^
1 error generated.

I cannot understand the error.我无法理解错误。 Can anyone explain to me?谁能给我解释一下?

The relevant bit of the error is:错误的相关位是:

candidate function not viable: no known conversion from
   'std::pair' to
   'const std::unordered_map, std::equal_to, std::allocator > >::key_type'
       (aka 'const int')
for 1st argument operator[](const key_type& __k)

So what this means is then when using the subscript operator in umap[*i] == 1 the type of *i is some std::pair and the type that the operator expects is const int (look at the "aka").所以这意味着当在umap[*i] == 1中使用下标运算符时, * *i的类型是一些std::pair并且运算符期望的类型是const int (查看“aka”)。

That's because map iterators return an std::pair containing a reference to the key data and to the value data.这是因为 map 迭代器返回一个std::pair包含对键数据值数据的引用。 You can get the value data easily just from the iterator without invoking the subscript operator:您可以仅从迭代器轻松获取值数据,而无需调用下标运算符:

if (i->second == 1)
  return i->first;

However, as stated in the comments you don't need any additional container to solve this puzzle.但是,正如评论中所述,您不需要任何额外的容器来解决这个难题。 The constraint "Could you implement it without using extra memory?"约束“你能在不使用额外的 memory 的情况下实现它吗?” is actually a hint to the solution.实际上是对解决方案的提示。 There is a mathematical property in a non-empty array of integers, where every element appears twice (.) except for one.在非空整数数组中有一个数学属性,其中每个元素出现两次(.),除了一个。


Also, I'd recommend using the variable name i for indexes and calling iterators it , but that's just personal preference.另外,我建议使用变量名i作为索引并调用迭代器it ,但这只是个人喜好。

You do not need std::unordered_map as std::unordered_set would be sufficient in this case:您不需要std::unordered_map因为std::unordered_set在这种情况下就足够了:

std::unordered_set<int> set;
for( auto i : nums ) {
   auto p = set.insert( i );
   if( !p.second ) set.erase( p.first );
}

So logic is you try to insert a number, but if it was already there you remove it.因此,逻辑是您尝试插入一个数字,但如果它已经存在,则将其删除。 Another benefit of this approach beside smaller memory footprint is that after loop you will have only one element in the set - one you need.除了更小的 memory 占用空间之外,这种方法的另一个好处是,在循环之后,您将在集合中只有一个元素 - 您需要一个。 So you do not need to iterate and search.所以你不需要迭代和搜索。

But proper solution is a trick that you should be aware about.但是正确的解决方案是您应该注意的技巧。 It based of the properties of xor operation:它基于xor或运算的性质:

A xor A == 0 for any A
A xor 0 == A for any A

and because xor operation has commutative property as well:并且因为xor操作也具有可交换性:

A xor B xor A == A xor A xor B == 0 xor B == B

I think you now can get the idea of implementation without additional memory.我认为您现在无需额外的 memory 即可获得实现的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM