我看到qCopy和qCopybackward但似乎都没有让我以相反的顺序复制.qCopybackward只能以相反的顺序复制它,但保持darn元素的顺序相同!我想要做的就是以相反的顺序返回列表的副本.有有成为一个函数,对不对?
Mar*_*utz 30
如果您不喜欢QTL,只需使用STL即可.他们可能没有Qt-ish API,但是STL API是摇滚稳定的:)那就是说,qCopyBackward只是std::copy_backward,所以至少它们是一致的.
回答你的问题:
template <typename T>
QList<T> reversed( const QList<T> & in ) {
QList<T> result;
result.reserve( in.size() ); // reserve is new in Qt 4.7
std::reverse_copy( in.begin(), in.end(), std::back_inserter( result ) );
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑2015-07-21:显然(或者可能不是),如果你想要一个单行(并且人们似乎更喜欢那个,看看五年后不同答案的相对赞成)并且你有一个非const list上述崩溃至
std::reverse(list.begin(), list.end());
Run Code Online (Sandbox Code Playgroud)
但是我觉得索引摆弄的东西更适合工作安全:)
小智 21
用一行反转你的QList:
for(int k = 0; k < (list.size()/2); k++) list.swap(k,list.size()-(1+k));
Rob*_*och 10
@Marc Jentsch的答案很好.如果你想获得额外30%的性能提升,你可以将他的单行改为:
for(int k=0, s=list.size(), max=(s/2); k<max; k++) list.swap(k,s-(1+k));
Run Code Online (Sandbox Code Playgroud)
一个QPad为1000万QTimers的ThinkPad W520我得到了这些数字:
提振是结果
您可以使用Java样式迭代器.这里有完整的例子(http://doc.qt.digia.com/3.2/collection.html).寻找"反向"这个词.
QList<int> list; // initial list
list << 1;
list << 2;
list << 3;
QList<int> rlist; // reverse list+
QListIterator<int> it(list);
while (it.hasPrevious()) {
rlist << it.previous();
}
Run Code Online (Sandbox Code Playgroud)
[原创改写]
目前尚不清楚OP是否想知道"我如何反转QList?" 或者实际上想要反转副本.用户mmutz给出了反向拷贝的正确答案,但是如果你只想反转QList,那就是:
#include <algorithm>
Run Code Online (Sandbox Code Playgroud)
然后
std::reverse(list.begin(), list.end());
Run Code Online (Sandbox Code Playgroud)
或者在C++ 11中:
std::reverse(std::begin(list), std::end(list));
Run Code Online (Sandbox Code Playgroud)
C++标准库(以及通常的模板)的优点在于算法和容器是分开的.起初看起来很烦人的是标准容器(以及较小程度上的Qt容器)没有类似的便利功能list.reverse(),但考虑其他选择:哪个更优雅:reverse()为所有容器提供方法,或者为其定义标准接口所有允许双向迭代的容器,并提供一个reverse()适用于支持双向迭代的所有容器的实现?
为了说明为什么这是一种优雅的方法,请考虑一些类似问题的答案:
"你怎么扭转std::vector<int>?":
std::reverse(std::begin(vec), std::end(vec));
Run Code Online (Sandbox Code Playgroud)
"你怎么扭转std::deque<int>?":
std::reverse(std::begin(deq), std::end(deq));
Run Code Online (Sandbox Code Playgroud)
容器的部分怎么样?
"你如何扭转a的前7个元素QList?":即使QList作者给了我们一个方便的.reverse()方法,他们可能也不会给我们这个功能,但这里是:
if (list.size() >= 7) {
std::reverse(std::begin(list), std::advance(std::begin(list), 7));
}
Run Code Online (Sandbox Code Playgroud)
但它变得更好:因为迭代器接口与C指针语法相同,并且因为C++ 11添加了free std::begin()和std::end函数,所以你可以这样做:
"你如何反转阵列float x[10]?":
std::reverse(std::begin(x), std::end(x));
Run Code Online (Sandbox Code Playgroud)
或者预先C++ 11:
std::reverse(x, x + sizeof(x) / sizeof(x[0]));
Run Code Online (Sandbox Code Playgroud)
(这就是std::end()我们隐藏的丑陋.)
让我们继续:"你如何反转float* x大小的缓冲区n?":
std::reverse(x, x + n);
Run Code Online (Sandbox Code Playgroud)
"你如何反转以null结尾的字符串char* s?":
std::reverse(s, s + strlen(s));
Run Code Online (Sandbox Code Playgroud)
"你如何char* s在一个大小的缓冲区中反转一个不一定以空值终止的字符串n?":
std::reverse(s, std::find(s, s + n, '\0'));
Run Code Online (Sandbox Code Playgroud)
请注意,即使这样std::reverse使用swap()也会尽可能地执行:
QList<QList<int> > bigListOfBigLists;
....
std::reverse(std::begin(bigListOfBigLists), std::end(bigListOfBigLists));
Run Code Online (Sandbox Code Playgroud)
还要注意,这些都应该像手写循环一样执行,因为在可能的情况下,编译器会将这些转换为指针算法.此外,您无法干净地编写reverse像C这样的可重用,通用,高性能的函数.
对于标准库列表,它看起来像这样
std::list<X> result;
std::copy(list.rbegin(), list.rend(), result.back_inserter());
Run Code Online (Sandbox Code Playgroud)
不幸的是,Qt没有返回反向迭代器的rbegin和rend函数(从容器的末尾到它的begnning).您可以编写它们,或者您可以自己编写复制功能 - 反转列表是一个很好的例外.或者您可以注意到QList实际上是一个数组,这使得编写这样一个函数变得微不足道.或者您可以将列表转换为std :: list,并使用rbegin和rend.选择你喜欢的任何东西
反转QList将是O(n)然而你这样做,因为不保证QList将其数据连续存储在内存中(与QVector不同).您可能会考虑在需要的地方以向后的顺序遍历列表,或者使用类似QStack的东西,它允许您按照添加的相反顺序检索元素.