【发布时间】:2012-07-26 00:56:31
【问题描述】:
这个函数接受一个包含'*'和'?'的字符串wild通配符,并用 nodeT *w 的树数据库中的可能字符替换通配符。 out 保存一个临时字符串。每个候选者都被添加到一个引用的 bst 中。
void Lexicon::matchRegExpHelper(nodeT *w, string wild, Set<string> &matchSet, string out)
{
if (wild == "") matchSet.add(out);
else {
if (wild[0] != '*' || wild[0] != '?') { //this parses up to the wildcard, earlier versions used a position parameter and looped through the prefix chars recursively
for (int j = 0; j < w->alpha.size(); j++)
if (wild[0] == w->alpha[j].letter) matchRegExpHelper(w->alpha[j].next, wild.substr(1), matchSet, out+=wild[0]);
} else {
for (int i = 0; i < w->alpha.size(); i++) {
if (wild[0] == '?') matchRegExpHelper(w->alpha[i].next, wild.substr(1), matchSet, out+=w->alpha[i].letter);//follow path
else { //logically, wild[0] == '*' must be true
if (ontLength == (wild.length() + out.length())) matchRegExpHelper(w->alpha[i].next, wild.substr(1), matchSet, out+=w->alpha[i].letter); //ontology is full, treat like a '?'
else matchRegExpHelper(w->alpha[i].next, wild.substr(1), matchSet, out+=(w->alpha[i].letter+'*')); //keep adding chars
}
}
}
}
}
当到达第一个通配符时,函数重新开始 - 我尝试使用 for 循环、不使用循环和不同的“修剪”方法重写它。我缺少一些基本的东西,并怀疑这是一个回溯问题。最终堆栈溢出。
问题:1)我在概念上缺少什么,以及 2)如何修复此功能?
没有for循环的版本 - 测试用例有点不同但相似,我必须测试它才能再次找到它
else {
if (wild[0] == '?'){
matchRegExpHelper(w, wild, ++pos, matchSet, out);//return and check next path
matchRegExpHelper(w->alpha[pos].next, wild.substr(1), 0, matchSet, out+=w->alpha[pos].letter);//follow path
}
if (wild[0] == '*'){
matchRegExpHelper(w, wild, ++pos, matchSet, out);//return and check next path
if (ontLength == (wild.length() + out.length()))matchRegExpHelper(w->alpha[pos].next, wild.substr(1), 0, matchSet, out+=w->alpha[pos].letter); //ontology is full, treat like a '?'
else matchRegExpHelper(w->alpha[pos].next, wild.substr(1), 0, matchSet, out+=(w->alpha[pos].letter+'*')); //keep adding chars
}
if (wild[0] == w->alpha[pos].letter) matchRegExpHelper(w->alpha[pos].next, wild.substr(1), 0, matchSet, out+=wild[0]);
matchRegExpHelper(w, wild, ++pos, matchSet, out);//check next path
}
for (int i = 0; i < w->alpha.size(); i++) matchRegExpHelper(w->alpha[i].next, wild.substr(1), 0, matchSet, out+=wild[0]);//step over char
最后的 for 循环试图修复溢出,我认为某些线程可能没有案例,但我希望将它们修剪,所以不知道该怎么做
【问题讨论】:
-
你试过使用调试器吗?
-
@Basile_Starynkevitch 也许我不知道调试器是什么,但我按下了“开始调试”的绿色箭头 - 所以我认为答案是肯定的。
-
您需要学习如何使用您的开发工具进行调试。花时间阅读一些文档不会有害。您需要设置断点并查看回溯。
-
我将搜索“回溯”——我不是程序员,这是我的研究生实验,这或多或少是我需要重写的最后一个函数。我在整个过程中放置了断点并遵循了路径,但我还没有看到用于回溯的工具。
-
每次到达通配符时,它都会从调用函数的位置重新开始。此外,我阅读的前几个网页令人困惑——我仍然不知道回溯是什么。也许调用堆栈有问题,但查看调用堆栈并没有太大帮助,它只是一遍又一遍地使用相同的函数。
标签: visual-studio-2008 recursion stack-overflow backtracking