我想找到给定矢量的所有可能的矢量旋转组合。我的代码在向量中顺序找到一个特定的元素,然后围绕它旋转,但是这个逻辑在两个相同的元素连续发生时失败,如{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 ++的新手。
答案 0 :(得分:2)
首先,您的代码存在潜在的细分错误:
for(int i = 1; i <= a.size(); i++)
由于std::vector
索引从0开始,i = a.size()
超出范围。
对于实际问题:请注意,如果您只想要不同的旋转,您只需要将初始向量旋转到重复自身的点 - 这将是它的周期,从那时起就不会有新的不同旋转。
此期间可以是从1到a.size()
的任何时间段,并且它始终存在,因此达到它应该是您的暂停条件。
可能的算法是
b
a
b
推送到结果向量b
旋转1 b
与a
进行比较。如果相等,则返回结果向量,否则返回步骤2 矢量比较(最后一步)在某种程度上是计算量很大并且可以被优化,例如,句点始终是a.size()
的除数,因此您可以基于此跳过一些步骤。
此外,您可能希望切换到更加适合旋转的数据结构,例如std::list
或std::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个不同的旋转。