C++ 迭代排序列表并计算不同的数字
我想迭代一个排序列表以获得不同数字的数目 请在下面找到我实现此功能的尝试。列表的大小为C++ 迭代排序列表并计算不同的数字,c++,list,unique,counting,C++,List,Unique,Counting,我想迭代一个排序列表以获得不同数字的数目 请在下面找到我实现此功能的尝试。列表的大小为k*k。 在对列表进行排序时,我比较连续的项以识别重复项 int count_distinct(list<int> v) { int num = k*k; std::list<int>::iterator it; it = v.begin(); for (int a=0; a<k*k-1; a++) { if(*it == *
k*k
。
在对列表进行排序时,我比较连续的项以识别重复项
int count_distinct(list<int> v)
{
int num = k*k;
std::list<int>::iterator it;
it = v.begin();
for (int a=0; a<k*k-1; a++)
{
if(*it == *it+1)
num--;
it++;
}
return num;
}
int count\u distinct(列表五)
{
int num=k*k;
std::list::迭代器;
it=v.begin();
对于(inta=0;a如何使用std::set
获取唯一元素计数
size_t count_distinct(const list<int>& v)
{
std::set<int> temp (v.begin(), v.end());
return temp.size();
}
size\u t count\u distinct(常数列表&v)
{
设置温度(v.begin(),v.end());
返回温度大小();
}
假设您希望在该列表中查找唯一整数的数量,并且该列表未排序,则可以使用临时集合或无序集合,如下所示:
size_t count_distinct(list<int> v)
{
std::unordered_set<int> distinct;
for(auto &x : v)
{
distinct.insert(x);
}
return distinct.size();
}
size_t count_distinct(const std::list<int>& l) {
if (l.empty()) return 0;
size_t distinct = l.size();
auto prev = l.begin();
for (auto cur = std::next(prev); cur != l.end(); ++cur, ++prev) {
if (*cur == *prev)
--distinct;
}
return distinct;
}
size\u t count\u distinct(列表五)
{
std::无序的_集不明显;
用于(自动和x:v)
{
插入(x);
}
返回distinct.size();
}
下面是一个提取所有唯一值的容器的解决方案
(因为你说过你想在事后使用它们):
一种计算唯一值的方法:
template < typename T >
size_t count_unique(const std::list<T> & input)
{
std::set<T> unique(input.begin(), input.end());
return unique.size();
}
template < typename T >
void unique(const std::list<T> & input, std::list<T> & output)
{
std::set<T> unique(input.begin(), input.end());
std::copy(unique.begin(), unique.end(), std::back_inserter(output));
}
模板
大小计数唯一(常数标准::列表和输入)
{
std::set unique(input.begin(),input.end());
返回唯一的.size();
}
提取唯一值列表的方法:
template < typename T >
size_t count_unique(const std::list<T> & input)
{
std::set<T> unique(input.begin(), input.end());
return unique.size();
}
template < typename T >
void unique(const std::list<T> & input, std::list<T> & output)
{
std::set<T> unique(input.begin(), input.end());
std::copy(unique.begin(), unique.end(), std::back_inserter(output));
}
模板
void unique(常量std::列表和输入,std::列表和输出)
{
std::set unique(input.begin(),input.end());
std::copy(unique.begin()、unique.end()、std::back_插入器(输出));
}
示例程序:
int main(int argc, char** argv)
{
std::list<int> list = { 1, 3, 4, 10, 3, 1, 6, 7 };
std::list<int> out;
std::cout << count_unique(list) << std::endl;
unique(list, out);
for (auto & x : out)
std::cout << x << std::endl;
}
int main(int argc,char**argv)
{
列表={1,3,4,10,3,1,6,7};
列出来;
std::cout您可以使用std::list::unique()
获取v
中的所有不同元素,并使用size()
对它们进行计数。v
必须进行排序。检查是否使用函数std::is\u sorted()对v
进行排序。如果没有,则对其进行排序。这还意味着count\u distinct
对常量列表对象不起作用
size_t count_distinct(list<int>& v)
{
if (!is_sorted(v.begin(), v.end()))
{
v.sort();
}
v.unique();
return v.size();
}
size\u t count\u distinct(列表和v)
{
如果(!已排序(v.begin(),v.end())
{
v、 排序();
}
v、 唯一();
返回v.size();
}
您的代码存在以下问题:
您可以通过值将容器传递给函数。您应该通过常量引用来传递它,以最小化速度和内存损失
你的条件*it==*it+1
总是错误的(你比较n
和n+1
)。可能你想写*it=*(it+1)
,但是std::list
有,你不能+1
它们
代码应如下所示:
size_t count_distinct(list<int> v)
{
std::unordered_set<int> distinct;
for(auto &x : v)
{
distinct.insert(x);
}
return distinct.size();
}
size_t count_distinct(const std::list<int>& l) {
if (l.empty()) return 0;
size_t distinct = l.size();
auto prev = l.begin();
for (auto cur = std::next(prev); cur != l.end(); ++cur, ++prev) {
if (*cur == *prev)
--distinct;
}
return distinct;
}
然后简单地使用它
size_t distinct = unique_cnt(l.begin(), l.end());
还有一种std::unique\u copy
+自定义迭代器方法,但它看起来不够优雅。对于排序数据,您可能不会比尝试实现的直接方法更高效
我更喜欢有一些东西沿着这条线,因为我发现向上计数而不是向下计数更直观:
std::size_t count_unique_sorted(std::list<int> const& l) {
if (l.empty()) return 0;
std::size_t count = 1;
auto previous_value = l.front();
// TODO: hope that the compiler fixes that redundant first comparison...
for (auto next_value : l) {
if (next_value != previous_value) {
// the value changed! increment count and update previous_value
++count;
previous_value = next_value;
}
}
return count;
}
请注意,在这两种情况下,您都希望将列表作为常量引用而不是副本传递到函数中
如果您觉得这仍然很慢,请随意探索并行化的乐趣。这可能取决于数据量和分布。因此,您应该在那时开始进行一些系统分析
<> P>除非你需要重新排序这些值,首先要考虑将数据转储到<代码> STD::vector < /COD>第一。有随机访问迭代器简化了事情并且有更好的局部性也可以加速事情… <代码> K++< /代码>?你确定吗?<代码>(const Auto Num:v)
迭代列表。然后使用std::map
作为结果,并在num
索引处计算int
。输入列表是否已排序?@JesperJuhl如果我们只想计算不同的数字,则使用set
即可。如果列表未排序,则我认为std::set
是最佳方法。如果是,则也许手工计算元素是最好的。@Galik Opps是的,我只是盲目复制了OP的片段。@DAle如果你有什么想法,你可以提供一个。你应该添加一个注释,说明输入需要排序,并且不能在常量列表上工作。结果应该是大小\u t
,而不是int
你应该添加std::Is_排序
至答案,如果未排序,请使用std::sort
使此答案正确