流行的print("If You want to start the game, please enter 'start'." + "\n" +
"Otherwise please enter 'quit' in order to quit the game.")
startGame = True
def StartGame_int(answer):
if answer.lower() == "start":
startGame = False
return "Welcome to Vahlderia!"
elif answer.lower() == "quit":
startGame = False
return "Thank You for playing Vahlderia!" + "\n" + "You can now close
the window."
else:
return "Please enter either 'r' to start or 'q' to quit the game."
def StartGame():
answ = input("- ")
StartGame_int(answ)
while startGame == True:
StartGame()
- remove_if
成语保留了容器中保留的元素的顺序。我有一个案例,我想删除一些元素,但我不关心其余元素的顺序,因为它们将在以后被移动,无论如何。我想,那不是使用erase
- remove_if
,我可以扫描向量,并且 - 当找到要删除的元素时 - 我可以将它与向量的最后一个有效元素交换。我称之为成语erase
- swap
,可以轻松实现如下:
erase
由于不需要移动元素,我希望这个代码在大的向量或包含大对象的向量上始终比template<typename Object, typename Condition>
void swap_erase(std::vector<Object>& v, const Condition& condition) {
// Keeps track to one past the last element we want to keep.
auto iter_to_last = v.end();
for(auto it = v.begin(); it < iter_to_last; ++it) {
// If the erasure condition is fulfilled...
if(condition(*it)) {
// Increase by one to the left the "tail" of the
// vector, made by elements we want to get rid of;
// Swap the two elements.
// Rewind the current iterator by 1, so at the
// next iteration we test the element we just swapped.
std::iter_swap(it--, --iter_to_last);
}
}
// Erase the elements we pushed at the end of the queue.
v.erase(iter_to_last, v.end());
}
- remove_if
更快。
但是,a quick benchmark显示两个are roughly equivalent由gcc 7.3.0和erase
编译,在我的i7上为2.6GHz。
我的假设,实施或基准测试的方式错了吗?
编辑:事实证明我的假设是错误的。这是-Ofast
的一种可能实现,它清楚地表明它不需要移动任何元素:
remove_if
答案 0 :(得分:3)
您对remove_if
如何运作的假设可能是错误的。也许你应该明确说明。
基本上remove_if
最多移动一次未删除的元素,因此如果删除大多数元素,它会特别快。 (它可以通过首先扫描未被删除的数组的初始部分进行优化,在这种情况下,如果删除少量元素并且第一个删除的元素接近结尾,它也会很快。)
您的交换算法为每个要删除的元素执行一个swap
,因此如果删除的元素很少,则最快。但是swap
是不必要的,并且在某些情况下不必要地慢,因为它需要三个动作。你可以移动最后一个元素超过被删除元素的顶部,可能会保存两个数据副本。