Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;检查向量中一行中有多少相同的元素_C++_Algorithm_Vector_Stl - Fatal编程技术网

C++ C++;检查向量中一行中有多少相同的元素

C++ C++;检查向量中一行中有多少相同的元素,c++,algorithm,vector,stl,C++,Algorithm,Vector,Stl,我有一个包含24000个元素的大向量,比如: (1,1,1,1,3,3,3,3,3,3,5,5,5,...etc) 我想检查一行中有多少相同的元素,如: 4-6-3..等等 我使用以下代码: 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

我有一个包含24000个元素的大向量,比如:

(1,1,1,1,3,3,3,3,3,3,5,5,5,...etc)
我想检查一行中有多少相同的元素,如: 4-6-3..等等 我使用以下代码:

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;
  }
}
静态整数计数器=1;
矢量数;
对于(int n=0;n您的算法在时间上是
O(n)
,这对我来说似乎是非常优化的,因为您必须访问每个独特的元素进行比较。您仍然可以在这里或那里减少一些周期,例如通过消除
else()中的条件
或通过打开某些编译器设置,但从算法上讲,您的状态良好

如果输入已经进行了排序,您可以进行一系列的二元搜索。这将为您提供最坏情况下的复杂性
O(N lg N),但平均情况可能会大大降低,这取决于相等元素序列的平均长度


顺便说一句,正如@AndyProwl在他的回答中所显示的那样:即使是做这种低级算法的东西,标准库也非常棒。
相邻的
上界
算法都有很好的文档化复杂性,迭代器约定将保护您的代码中存在的边缘情况一旦你学会了这个词汇表,你就可以很容易地在自己的例程中使用它们(当范围达到C++时,希望它也能更容易地组成它们)。

@ RalbBeSMA基本上给了你正确的答案。作为补充,如果你想以更标准的方式重写你的算法:

#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);
    }
}
#包括

此外,当对向量进行排序时,这将为您提供更好的最佳案例复杂性:

#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;
    }
}

#include.

有一些小优化可能会给您带来几毫秒:

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!!
int size=numbers.size()-1;
静态整数计数器=1;
静态int*num1=&numbers[0];
静态int*num2=&numbers[1];

对于(int n=0;nIs)已排序的向量,您可以删除第二条if()语句,并且应该关心最后一条element@SonicpathSonicwave是包含{1,2,3,1}的向量可能的输入?@stefan是的,是的,我知道我总是要手动检查最后一个元素。我不知道如何在代码+1中使用标准库。在我们的示例中,您缺少一个使用命名空间std;
,或者一些
std::
限定符。@rhalbersma:除非我犯了一些错误,否则这些
 std::
是不必要的,因为ADL。但是,是的,他们可能在那里;)啊,你的ADL成瘾又开始了!我们都有自己的缺点:-)(我用过一次
#pragma,没有其他包括警卫)@rhalbersma:Btw,很抱歉打错了你的用户名如果没有太多相同的元素,我认为
上限方法不会更快。我相信这种方法是最坏的情况O(n logn)(但最好的情况O(logn)),而本机方法总是O(n)。另外,一个轻微的改进可能是从
i
开始,类似于
上限(i,end(v),*i)
。然后还可以删除内部循环中的
endl
,因为它会在每次都刷新缓冲区,而不仅仅是在缓冲区满的时候。你说得对!!我已经编辑了这一行。此外,也许还有比iosteam更有效的方法。