C++ 如何在我们';你只剩下一个了?

C++ 如何在我们';你只剩下一个了?,c++,arrays,algorithm,vector,lambda,C++,Arrays,Algorithm,Vector,Lambda,设J是具有值(0,1,1,2,3,5,8,3,1)的向量 我想一直从向量中移除奇数处的所有值,直到J中只剩下一个元素 (0,1,1,2,3,5,8,3,1)=>(1,2,5,3)=>(2,3)=>(3) 我如何做到这一点 我的做法: #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int J[] = {0, 1, 1

设J是具有值(0,1,1,2,3,5,8,3,1)的向量

我想一直从向量中移除奇数处的所有值,直到J中只剩下一个元素

(0,1,1,2,3,5,8,3,1)=>(1,2,5,3)=>(2,3)=>(3)

我如何做到这一点

我的做法:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
  int J[] = {0, 1, 1, 2, 3, 5, 8, 3, 1};
  int len=sizeof(J)/sizeof(J[0]);
  vector<int> Jvec;
  for (int i=0; i<len; i++) {  //Putting the values of array into Jvec
    Jvec.push_back(J[i]);
  }

  while (Jvec.size()!=1) {
    vector<int> oddJ;
    for (int k=0; k<Jvec.size(); k=k+2) {  //Storing values of odd places
      oddJ.push_back(Jvec[k]);
    }

    for (int i=0; i<oddJ.size(); i++) {
      Jvec.erase(remove(Jvec.begin(), Jvec.end(), oddJ[i]), Jvec.end()); //removing values from vector by value, not index
    }
  }
  cout << Jvec[0];
  return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
int J[]={0,1,1,2,3,5,8,3,1};
int len=sizeof(J)/sizeof(J[0]);
载体Jvec;

对于(int i=0;i来回答您的问题,哪里出了问题:
std::remove
删除给定值的所有元素,因此如果您在“1”上第二次应用它,它实际上会删除两个元素,与“3”相同稍后,参见.Read:从ReNATE评论:

< P>数组和标准容器的C++索引从0开始。因此,更准确地说,

如何一直从向量中删除偶数处的值,直到 我们只剩下一个了

下面是一个演示程序,展示了如何实现这一点

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main() 
{
    std::vector<int> v = { 0, 1, 1, 2, 3, 5, 8, 3, 1 };

    while ( v.size() > 1 )
    {
        // comment these two statements in the release version
        for ( const auto &item : v ) std::cout << item << ' ';
        std::cout << '\n';

        std::vector<int>::size_type i = 0;

        auto even_pos = [&i] ( const auto & ) { return i++ % 2 == 0; };

        v.erase( std::remove_if( std::begin( v ), std::end( v ), even_pos ),
                 std::end( v ) );
    }

    for ( const auto &item : v ) std::cout << item << ' ';
    std::cout << '\n';

    return 0;
}
至于你的代码,那么这个电话

Jvec.erase(remove(Jvec.begin(), Jvec.end(), oddJ[i]), Jvec.end());
从向量
Jvec
中不仅删除一个元素,而且删除所有等于
oddJ[i]
的元素


因此,例如,如果
oddJ[i]
等于
3
,则位置
4
7
处的两个元素将从向量
Jvec

中删除,尽管已经提供了正确的解决方案,但使用稍微简单的代码可以获得相同的结果:

#include <iostream>
#include <vector>

using std::cout;
using std::vector;

int main()
{
   vector<int> v = { 0, 1, 1, 2, 3, 5, 8, 3, 1 };

   while (v.size() > 1)
   {
        for(size_t i = 0; i < v.size(); i++)
        {
            v.erase(v.begin() + i);
        }
        for (const auto &i : v) cout << i << ' ';
        cout << '\n';
   }
   return 0;
}
#包括
#包括
使用std::cout;
使用std::vector;
int main()
{
向量v={0,1,1,2,3,5,8,3,1};
而(v.size()>1)
{
对于(size_t i=0;i对于(const auto&i:v)cout事实上,您的问题有一个非常简洁、快速的解决方案

由于您希望删除每个步骤上的第1、第3、第5等索引,因此数组基于0,因此您实际上应该删除每个步骤上的第0、第2、第4索引

以下是一些在搜索答案时有用的观察结果:

  • 在每一步中,数组被减半,这意味着在
    O(logN)
    步中,您将得到一个大小为
    1
    的数组

  • 在最后一步中,搜索的值具有索引
    0

  • 在每一步(但最后一步)上,搜索的值都有一个奇数索引,因此它会被保留,直到数组大小变为
    1

因此,在最后一步中,搜索值的索引是
0
,在前一步中,它有索引
1
,在前一步中,它有索引
3
,依此类推

我们可以清楚地看到,从
0
开始,索引增加一倍,然后添加
1
,这样它就得到奇数而不是删除。这正好发生了
logn

因此,为了跟踪最终应该打印的数字的索引,我们可以执行以下操作:

int[] values = {0, 1, 1, 2, 3, 5, 8, 3, 1};
int n = values.length, index = 0;
while (n > 1) {
  index = 2 * index + 1;
  n /= 2;
}
System.out.println(values[index]);
我用Java编写了代码,但是您可以很容易地根据自己选择的语言对其进行调整


这使得总体复杂度为
O(logN)<代码> N>代码>代码大小> <代码>数组.< /p>你是否尝试使用调试器?在每次擦除调用之后,向量的值是什么?可能的重复我可以简单地说,答案是从最后一个或第二个最后的数字从奇数的地方实际上是从偶数索引吗?在C++中,索引从0开始。h是找到小于或等于元素数的2的最大幂,并在该位置打印元素。您能解释一下什么是“自动偶数”_pos=[&i](const auto&){return i++%2==0;}正在做什么?@P.Pawar这是一个lambda表达式。它检查向量的当前索引是否为偶数。我收到一个错误:“偶数”没有指定一个值type@P.Pawar你是否在没有自己修改的情况下复制并粘贴了演示程序?我只是复制了while循环的内容。我目前是学习stl和poin的初学者所以我在试图理解它时遇到了一些困难,我看不到任何关于删除你的索引的参考code@P.Pawar这就是使它更简单的原因。注意:一旦你删除了元素#1,向量就缩小了,现在原来是#3的元素已经移到了位置#2。所以你所要做的就是按顺序删除元素索引i处的ts(每次迭代时递增1)直到向量结束。运行代码,您将看到。@P.Pawar这很容易理解,但效率不高:任何时候删除其中一个元素,所有后续元素都会向前移动一个位置。将此事实纳入计算,内部循环将得到
O(n²)
复杂度,因此与外部循环一起,我们最终将陷入
O(log(n)*n²)
复杂度。在这方面,其他解决方案更优越……这启发了我:必须有一个数学公式来找到索引……它是:
2^层(log2(n))-1
,或者更计算机友好的
1U
int[] values = {0, 1, 1, 2, 3, 5, 8, 3, 1};
int n = values.length, index = 0;
while (n > 1) {
  index = 2 * index + 1;
  n /= 2;
}
System.out.println(values[index]);