c ++向量旋转所有组合

时间:2016-09-13 23:15:26

标签: c++ c++11

我想找到给定矢量的所有可能的矢量旋转组合。我的代码在向量中顺序找到一个特定的元素,然后围绕它旋转,但是这个逻辑在两个相同的元素连续发生时失败,如{1,1,2} 下面是代码片段,有人可以帮助我绕过这个问题,最好是让我在for循环中说一个if else循环。

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

using namespace std;
vector<vector<int> > allrot(const vector<int>& a);

int main()
{
      int myints[] = { 1, 1, 2 };
      std::vector<int> a (myints, myints + sizeof(myints) / sizeof(int));
      std::vector<vector<int> > b;
      b = allrot(a);
}

vector<vector<int> > allrot(const vector<int>& a) {
        std::vector<vector<int> > b;
        for(int i = 1; i <= a.size(); i++) {
                //int k;
                //if (a[i] == a[i+1])
                    //k = a [i+1];
                //else
                    //k = a[i];

                auto pivot = std::find(a.begin(), a.end(), a[i]);
                std::vector<int> dest(a.size());
                std::rotate_copy(a.begin(), pivot, a.end(), dest.begin());
                for (const auto &i : dest) {
                    std::cout << i << ' ';
                }
                std::cout << '\n';
                b.push_back(dest);
        }
        return b;
}

如果问题看起来很幼稚,我很抱歉,我是c ++的新手。

2 个答案:

答案 0 :(得分:2)

首先,您的代码存在潜在的细分错误:

for(int i = 1; i <= a.size(); i++)

由于std::vector索引从0开始,i = a.size()超出范围。

对于实际问题:请注意,如果您只想要不同的旋转,您只需要将初始向量旋转到重复自身的点 - 这将是它的周期,从那时起就不会有新的不同旋转。

此期间可以是从1到a.size()的任何时间段,并且它始终存在,因此达到它应该是您的暂停条件。

可能的算法是

  • 制作初始向量b
  • 的临时副本a
  • b推送到结果向量
  • b旋转1
  • ba进行比较。如果相等,则返回结果向量,否则返回步骤2

矢量比较(最后一步)在某种程度上是计算量很大并且可以被优化,例如,句点始终是a.size()的除数,因此您可以基于此跳过一些步骤。

此外,您可能希望切换到更加适合旋转的数据结构,例如std::liststd::deque,至少对于处理实际旋转的对象。

答案 1 :(得分:0)

我认为问题在于行auto pivot = std::find(a.begin(), a.end(), a[i]);这将找到a[i]处的值出现的第一个实例。

请考虑以下实施。

vector<vector<int>> all_rot(const vector<int>& a){
  vector<vector<int>> b;
  for (auto it = a.begin(); it != a.end(); ++it){
    vector<int> dest(a.size());
    dest = std::rotate_copy(a.begin(), it, a.end(), dest.begin());
    if (b.size() != 0 && dest == b[0]){ return b; } // checks to see if you have repetition in cycles.
    b.push_back(dest);
    for (const auto item& : dest){
      std::cout << item << " ";
    }
    std::cout << endl;
  }
  return b;
}

由于您知道pivot(我上面称之为it)位于ith位置,因此我们不需要找到它。虽然,因为我们只需要迭代器,所以我只是迭代输入中的每个元素并根据该元素进行旋转。

要考虑的另一个边缘情况是每个元素都相同。如果向量的所有元素都相同,则恰好有1个不同的旋转。