【发布时间】:2011-04-06 04:01:18
【问题描述】:
我编写了一个程序来确定井字游戏的游戏树。 我相信大部分代码都井井有条。 我编写了一个函数来比较向量的元素以确定是否有任何元素重复。 重复的项目可以是真正相同的,也可以是对称的。 从向量中删除重复的元素。 我的比较功能似乎存在错误地消除元素的问题。 请看看我是如何遍历向量的,看看语法/逻辑是否合理。
我的猜测是使用 运算符可能是问题的一部分。 该函数的基本逻辑是将第一个元素与最后一个元素进行比较,然后是倒数第二个元素,依此类推。在将第一个元素与所有元素进行比较后,您再次开始将第二个元素与其他元素进行比较,依此类推...
void compareAllGames(move& aMove) { /* aMove is a vector of games. games are a struct of data */
vector<game>:: iterator frontIter = aMove.begin();
vector<game>:: iterator rearIter = aMove.end() - 1;
vector<game>:: iterator compIter;
for (; frontIter < rearIter; frontIter++) { /* move along the games from first to last */
for (compIter = aMove.end(); compIter > frontIter; ) { /* move along the games from last to first */
/* checkForSymmetry compares *frontIter to all symmetries of *compIter */
if (checkForSymmetry(*frontIter, *compIter)) {
compIter--;
aMove.erase(compIter + 1);
}
else {
compIter--;
}
} /* reset iterators for next loop */
compIter = aMove.end();
rearIter = aMove.end();
}
}
【问题讨论】:
-
你能举一个产生错误的简单例子吗?
-
你能解释一下比较逻辑吗?如果您可以创建一个总订单,您可能会在一次通过中对向量进行排序并删除重复项。这将比您目前拥有的算法更快。
-
值得一提的是
std::vector::erase()将迭代器返回到您刚刚删除的元素之后的下一个元素。这意味着您可以写入compIter = aMove.erase(compIter);并将--compIter移动到for()作为递减步骤。 -
错误示例 - 在 tictactoe 中有 3 种可能的第一次移动:中心、角落、侧面。在检查对称性之前,有 24 个第二步。对称性检查后,它们应该是 12,但我想出了 11 并验证了一个被错误地移动了。后来的 cmets 证实了我对迭代器的怀疑......
-
我尝试了
compIter = aMove.erase(compIter);,但这导致了无限循环。.erase下方的 else 条件也使得 for 循环内的--compIter不起作用。