C++ (类)C+中容器的旋转和切片元件+;

C++ (类)C+中容器的旋转和切片元件+;,c++,rotation,spline,splice,C++,Rotation,Spline,Splice,我有一个std::vector,它包含一个点结构(x、y、z和一些其他非指针类型) 这些点是用于绘制bspline曲线的控制点。绘制曲线没有问题,但当我必须关闭曲线时会出现复杂情况,这涉及到按一定顺序添加控制点(容器中存在的alredy) 例如,如果我有5个控制点 A B C D E 我必须得到5个这样的序列: A B C D //curve is drawn from B to C B C D E //curve is drawn from C to D C D E A //curve

我有一个
std::vector
,它包含一个
点结构(x、y、z和一些其他非指针类型)

这些点是用于绘制bspline曲线的控制点。绘制曲线没有问题,但当我必须关闭曲线时会出现复杂情况,这涉及到按一定顺序添加控制点(容器中存在的alredy)

例如,如果我有5个控制点

A B C D E
我必须得到5个这样的序列:

A B C D  //curve is drawn from B to C
B C D E  //curve is drawn from C to D
C D E A  //curve is drawn from D to E 
D E A B  //curve is drawn from E to A
E A B C  //curve is drawn from A to B
起初,我使用了
std::rotate
,但后来意识到这不是我想要的

我在实现这一点上遇到了困难。我得到的最好的是C++中的非工作版本(失败的原因不是问题,这里是一个片段)。
静态字符字母='A';
类型定义结构点{
浮动x,y,z;
字符名;
点(浮点x,浮点y,浮点z=0):名称(字母++){
}点;
typedef std::向量lpoints;
无效的
旋转(点和点)
{

例如,对于(unsigned int i=0;i使用
std::rotate()
)到底有什么错误

std::vector<int> v(5);

std::rotate(v.begin(), v.begin() + 1, v.end());
std::vector<int> firstFour(v.begin(), v.begin() + 4);
标准:向量v(5); 旋转(v.begin(),v.begin()+1,v.end()); 向量前四(v.begin(),v.begin()+4);

firstFour
然后包含旋转向量的前四个元素。如果在循环中使用它并运行它
v.size()
次,您将得到问题中的五个向量。

如果您愿意使用更多的空间,您可以先在自身上附加lpoints,然后在需要时增加迭代器,同时使用subseq。这也符合您的“五个不同向量或一个长向量”,因为您可以只使用加倍向量的迭代器创造新的

对不起,我暂时没有写C++,所以这里是C++类伪代码< /p>
void 
rotate(lpoints& points) 
{ 
    pointsDouble = Append(points,points); // Do your own implementation
                                 // if points is A B C D E
                                 // pointsDouble is A B C D E A B C D E

    pointsDouble::iterator beg =   lista.begin(); 
    pointsDouble::iterator dernier=lista.begin()+4;  

    for (unsigned int i =0;i<5;i++){ 

        lpoints subseq(beg,dernier); //4 points in subseq 

        //do stuff with subseq

       ++beg; ++dernier;

    } 
}

(Luc建议使用back\u inserter)

您能做如下操作吗:

// vector = (a,b,c,d,e);

front = vector.front();
vector.pop_front();
vector.push_back(front);
// now you have (b,c,d,e,a);
重复任意次数。
在内存洗牌方面可能效率低下,但与James在上面所写的差不多:

vector <char> newv[5];

for(int i=0; i<5; i++)
{
    newv[i].insert(newv[i].begin(),v.begin(), v.begin()+4);
    std::rotate(v.begin(), v.begin()+1, v.end());
}
vectornewv[5];

对于(int i=0;i以上所有答案都需要对容器进行变异。不进行变异就可以解决这一问题,并且仍然使用stl/boost算法。如果由于我还没有测试,下面的问题无法完全编译,则采用近似方法

std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);

for(int i = 0; i < 5; i ++)
{
    using boost::join;
    using boost::adaptors::sliced;
    using std::ostream_iterator;
    using std::cout;
    using boost::copy;

    copy
        ( join(v | sliced(i,4), v | sliced(0, (4 + i) % 5))
        , ostream_iterator<int>(cout, " ") 
        )
    }
    cout << std::endl;

}
std::vector v;
v、 推回(0);
v、 推回(1);
v、 推回(2);
v、 推回(3);
v、 推回(4);
对于(int i=0;i<5;i++)
{
使用boost::join;
使用boost::adapters::sliced;
使用std::ostream_迭代器;
使用std::cout;
使用boost::copy;
复制
(连接(v|切片(i,4),v|切片(0,(4+i)%5))
,ostream_迭代器(cout,“”)
)
}

您是否希望解决方案中有5个不同的向量?@位、5个不同的向量或一个较长的向量都可以。谢谢,我循环了一个std::rotate,但使用不当,因为我将v.begin()+I作为第二个参数传递(I是循环变量)汤姆:作为后续的思想,如果你知道你总是在你的结果向量中有四个元素,你可以考虑使用<代码>数组< /Cord>容器(可以从Boost、C++ +Tr1或C++ 0x中得到)。可能错误的是它可能是O(n ^ 2)(n为二次)。,其中n是向量的长度。您可以将向量附加到自身(在O(n)时间内),而不必每次都创建新的向量(参见我的答案)“@Tom:我觉得这很优雅。你似乎完全忽略了它。哦,好吧…@白痴希望你没有生气。我没有忽略它,但现在想不起附加功能,试图突破死线,很累。但是谢谢。@Tom:不,没有冒犯。只是惊讶于你对此无话可说。有关附加,请参阅我的编辑。要附加。”如果要将向量复制到自身,可能需要使用back\u插入器:
std::copy(points.begin()、points.end()、std::back\u插入器(pointsDouble)
。如果需要,你可以事先调用
reserve
。@Micheal:链接似乎要花很长时间。请随意编辑答案并添加它。@Luc:谢谢,我已经按照你的建议进行了编辑。如果你使用向量,这是低效的,O(n^2)。但是如果你使用列表,它就会变成O(n),因此,对于希望避免复制的情况,这可能很好。
vector <char> newv[5];

for(int i=0; i<5; i++)
{
    newv[i].insert(newv[i].begin(),v.begin(), v.begin()+4);
    std::rotate(v.begin(), v.begin()+1, v.end());
}
std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);

for(int i = 0; i < 5; i ++)
{
    using boost::join;
    using boost::adaptors::sliced;
    using std::ostream_iterator;
    using std::cout;
    using boost::copy;

    copy
        ( join(v | sliced(i,4), v | sliced(0, (4 + i) % 5))
        , ostream_iterator<int>(cout, " ") 
        )
    }
    cout << std::endl;

}