我写了一个程序来确定tic-tac-toe的游戏树。 我相信大部分代码都处于良好状态。 我编写了一个函数来比较向量的元素,以确定是否有任何元素是重复的。 重复的项目可以是真正相同的,也可以是对称的。 从矢量中删除重复的元素。 我的比较功能似乎存在错误消除元素的问题。 请看一下我如何迭代向量,看看语法/逻辑是否合理。
我的猜测是使用< >运营商可能是问题的一部分。 该函数的基本逻辑是比较第一个元素和最后一个元素,然后是倒数第二个元素,依此类推。在将第一个元素与所有元素进行比较之后,再次开始将第二个元素与其他元素进行比较,依此类推......
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();
}
}
答案 0 :(得分:2)
看起来您访问end
的地方至少有一两个地方已超过容器的末尾。我没有尝试修复有些错综复杂的逻辑,而是建议:
如果您可以创建一个始终相邻排列对称解决方案的排序,则可以应用该顺序,然后将std::unique
与谓词一起使用以删除重复项。
如果你不能这样做,那么使用remove_if
而不是复杂的内循环:
void compareAllGames(move& aMove) { /* aMove is a vector of games. games are a struct of data */
vector<game>:: iterator frontIter = aMove.begin();
for (; frontIter < aMove.end() - 1; frontIter++) { /* move along the games from first to last */
aMove.erase(std::remove_if(frontIter + 1, aMove.end(), std::bind1st(checkForSymmetry, *frontIter)), aMove.end());
}
}
答案 1 :(得分:1)
for (; frontIter < rearIter; frontIter++) { /* move along the games from first to last */
你是对的:你应该使用!=
代替<
。它可能没有任何区别,但没有其他原因,你通常也想使用预增量而不是后增量,给出:
for (;frontIter != readiter; ++frontIter)
for (compIter = aMove.end(); compIter > frontIter; ) { /* move along the games from last to first */
要反向遍历集合,通常想要使用reverse_iterator:
vector<game>::reverse_iterator compIter;
for (compIter=aMove.rbegin(); compIter != frontIter; ++compIter);
Offhand我不记得你是否可以直接将迭代器与reverse_iterator进行比较 - 你可能需要将fronIter转换为reverse_iterator来进行比较。
/* checkForSymmetry compares *frontIter to all symmetries of *compIter */
if (checkForSymmetry(*frontIter, *compIter)) {
compIter--;
aMove.erase(compIter + 1);
}
else {
compIter--;
}
} /* reset iterators for next loop */
虽然转换不会完全简单,但看起来最终会变成std::remove_if
的变体,因此您可以将其更改为使用标准算法。
答案 2 :(得分:1)
这不是一个真正的答案,只是为了向OP澄清我在评论中的含义。
/* aMove is a vector of games. games are a struct of data */
void compareAllGames( move &aMove )
{
typedef vector<game>::iterator game_it;
/* move along the games from first to last */
for( game_it frontIter = aMove.begin(); frontIter != aMove.end(); ++frontIter )
{
/* move along the games from last to first */
for( game_it compIter = aMove.end(); compIter != frontIter; --compIter )
{
/* checkForSymmetry compares *frontIter to all symmetries of *compIter */
if( checkForSymmetry( *frontIter, *compIter ) )
{
compIter = aMove.erase( compIter );
}
}
}
}
答案 3 :(得分:0)
感谢所有评论。最后我简化了我的功能,它有两个令人困惑的循环,并确定不是将所有游戏添加到移动然后检查重复/对称,我可以添加一个游戏并将其与当前列表进行比较。这有两个优点:易于理解的简单编码和更低数量的比较。这段代码实际上也起作用并没有什么坏处。这些变化让我在对称函数中发现了一些错误。
这是我使用的最终功能:
bool compareAllGames(move& aMove) {
vector<game>:: iterator frontIter = aMove.begin();
vector<game>:: iterator rearIter = aMove.end() - 1;
for (; frontIter != rearIter; ++frontIter) { // move along the games from first to last
if (checkForSymmetry(*frontIter, aMove.back())) {
aMove.pop_back();
return true;
}
}
return false;
}
现在我只需要将我的代码添加到该帐户中以获取获胜者,并且我将对tic tac toe游戏树进行适当的调整计数。移动的未调整计数(忽略获胜者)为:1,2,12,38,108,174,228,174,89和23.