我有一个包含24.000个元素的大矢量,如:
(1,1,1,1,3,3,3,3,3,3,5,5,5,...etc)
我想检查一行中有多少相同的元素,如: 4-6-3..etc 我使用这段代码:
static int counter=1;
vector<int>numbers;
for(int n=0;n<numbers.size()-1;n++)
{
if(numbers[n]==numbers[n+1])
{
counter++;
}
else if(numbers[n]!=numbers[n+1])
{
cout<<counter<<endl;
counter=1;
}
}
是否有任何算法可以更快地执行相同操作;
答案 0 :(得分:10)
#include <algorithm>
#include <vector>
#include <iterator>
#include <functional>
#include <iostream>
int main()
{
std::vector<int> v { 1, 1, 2, 3, 3, 5, 5, 5 }; // or whatever...
auto i = begin(v);
while (i != end(v))
{
auto j = adjacent_find(i, end(v), std::not_equal_to<int>());
if (j == end(v)) { std::cout << distance(i, j); break; }
std::cout << distance(i, j) + 1 << std::endl;
i = next(j);
}
}
这是live example。
此外,当向量排序时,这将为您提供更好的最佳案例复杂性:
#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
int main()
{
std::vector<int> v { 1, 1, 2, 3, 3, 5, 5, 5 }; // must be sorted...
auto i = begin(v);
while (i != end(v))
{
auto ub = upper_bound(i, end(v), *i);
std::cout << distance(i, ub) << std::endl;
i = ub;
}
}
这是live example。
答案 1 :(得分:6)
你的算法及时O(N)
,这似乎对我来说非常理想,因为你必须访问每个独特的元素进行比较。你可能仍然会在这里和那里刮掉几个周期,例如通过消除else()
中的条件或打开一些编译器设置,但在算法上你的状态良好。
如果输入已经排序,您可以执行一系列二进制搜索。这会给你O(N lg N)
最坏情况的复杂性,但平均情况可能会大大降低,具体取决于相等元素序列的平均长度。
adjacent_find
和upper_bound
算法具有详细记录的复杂性,迭代器约定将保护您自己的代码中存在的边缘情况。一旦你学会了这个词汇,就可以在自己的例程中轻松使用它们(当Ranges来到C ++时,希望它们也更容易组合它们。)
答案 2 :(得分:0)
有一些小问题可能会给你一些ms:
int size = numbers.size()-1;
static int counter=1;
static int *num1 = &numbers[0];
static int *num2 = &numbers[1];
for(int n=0;n<size;n++)
{
if(*num1==*num2) counter++;
else
{
cout << counter << "\n";
counter=1;
}
num1++;
num2++;
}
cout<<counter<<endl; //Caution, this line is missing in your code!!
Basicaly: