如何计算unordered_set中的唯一整数?

时间:2015-05-15 21:52:39

标签: c++ hashmap unordered-set

一个可能显得微不足道的问题,但我想知道在将包含重复整数的数组转换为unordered_set之后是否有一种获取整数计数的方法。要清楚,我从一些数组开始,变成一个无序集,然后突然,unordered_set只包含唯一的整数,我只是在unordered_set中重复的整数数之后。 这有可能吗? (类似于unordered_set.count(index)?)

3 个答案:

答案 0 :(得分:0)

  

一个可能显得微不足道的问题,但是我想知道在将包含重复整数的数组转换为unordered_set后,是否有一种方法可以获得唯一的整数计数。

如果容器是连续的,就像数组一样,那么我相信你可以在做一些迭代器数学运算后使用 SSLContext sslContext = SSLContext.getInstance("SSL"); // set up a TrustManager that trusts everything sslContext.init(null, new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }, new SecureRandom()); SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); Scheme httpsScheme = new Scheme("https", 443, sf); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(httpsScheme); BasicClientConnectionManager cm = new BasicClientConnectionManager(schemeRegistry); DefaultHttpClient httpClient = new DefaultHttpClient(cm); 来计算它们。不过,我不确定不连续的容器。

因为你从一个数组开始:

  1. 在阵列上调用unique
  2. ptrdiff_t返回unique
  3. 使用iter.end()ptrdiff_t count
  4. 计算iter.begin()

    请记住,需要针对iter.end()和元素调整步骤3中的计算。

    但是用Beta的话来说,有些容器适合这种情况,而其他容器则不然。如果你有一个无序集(或地图或树),那么这些信息就不会随时可用。

答案 1 :(得分:0)

根据您对user2357112问题的回答,我会写一个解决方案。 所以,让我们假设我们将使用向量代替unordered_set,而我们的向量具有如下值:

{1, 1, 1, 3, 4, 1, 1, 4, 4, 5, 5};

所以,我们希望得到特定值出现在向量中的次数(在我认为的不同向量中),对吗?并且在这个具体情况下结果将是:1出现5次,3次出现,4次出现3次,5次出现2次。

要做到这一点,一个可能的解决方案可能是这样的:

  1. 从源向量中获取唯一条目并将其存储在不同的向量中,因此此向量将包含:1,3,4,5
  2. 遍历整个唯一向量并从源向量中计算这些元素。
  3. 打印结果
  4. 第1点的代码可以是这样的:

    template <typename Type>
    vector<Type> unique_entries (vector<Type> vec) { 
        for (auto iter = vec.begin (); iter != vec.end (); ++iter) { 
            auto f = find_if (iter+1, vec.end (), [&] (const Type& val) {
               return *iter == val; 
            });
    
            if (f != vec.end ()) { 
                vec.erase (remove (iter+1, vec.end (), *iter), vec.end ());
            }
        }
        return vec;
    }
    

    第2点的代码可以是这样的:

    template <typename Type>
    struct Properties { 
        Type key;
        long int count;
    };
    
    template <typename Type>
    vector<Properties<Type>> get_properties (const vector<Type>& vec) { 
        vector<Properties<Type>> ret {};
        auto unique_vec = unique_entries (vec);
        for (const auto& uv : unique_vec) { 
            auto c = count (vec.begin (), vec.end (), uv); // (X)
            ret.push_back ({uv, c});
        }
        return ret;
    }
    

    当然我们不需要Properties类来存储键和计数值,你可以只返回一个int的向量(带有元素的数量),但正如我所说,它是可能的解决方案之一。因此,通过使用 unique_entries ,我们得到一个带有唯一条目(:)的向量,然后我们可以遍历整个向量vec( get_properties ,使用 std :: count 标记为(X)),push_back属性对象为向量 ret

    第3点的代码可以是这样的:

    template <typename Type>
    void show (const vector<Properties<Type>>& vec) { 
        for (const auto& v : vec) { 
            cout << v.key << " " << v.count << endl;
        }
    }
    
    // usage below
    vector<int> vec {1, 1, 1, 3, 4, 1, 1, 4, 4, 5, 5};
    auto properties = get_properties (vec);
    show (properties);
    

    结果如下:

    1 5
    3 1
    4 3
    5 2
    

    值得注意的是,此示例是使用模板编写的,以便灵活地选择向量中的元素类型。如果要存储long,long long,short等值而不是int类型,您只需要更改源向量的定义,例如:

    vector<unsigned long long> vec2 {1, 3, 2, 3, 4, 4, 4, 4, 3, 3, 2, 3, 1, 7, 2, 2, 2, 1, 6, 5};
    show (get_properties (vec2));
    

    将产生:

    1 3
    3 5
    2 5
    4 4
    7 1
    6 1
    5 1
    

    这是期望的结果。

    还有一点需要注意,你也可以用字符串向量来做到这一点。

    vector<string> vec_str {"Thomas", "Rick", "Martin", "Martin", "Carol", "Thomas", "Martin", "Josh", "Jacob", "Jacob", "Rick"};
    show (get_properties (vec_str));
    

    结果是:

    Thomas 2
    Rick 2
    Martin 3
    Carol 1
    Josh 1
    Jacob 2
    

答案 2 :(得分:0)

我假设您正在尝试获取唯一值及其出现次数的列表。在这种情况下,std::map提供了最干净,最简单的解决方案:

//Always prefer std::vector (or at least std::array) over raw arrays if you can
std::vector<int> myInts {2,2,7,8,3,7,2,3,46,7,2,1}; 

std::map<int, unsigned> uniqueValues;

//Get unique values and their count
for (int val : myInts)
    ++uniqueValues[val];

//Output:
for (const auto & val : uniqueValues)
    std::cout << val.first << " occurs " << val.second << " times." << std::endl;

在这种情况下,不必是std::unordered_set