C++ c+中的通配符扩展+;
我正在试验一个递归函数来进行通配符扩展。星号“*”可以扩展为0-n个字符 示例:模式“*b*”将扩展为“bb*”,删除星号并保留“bb”。到目前为止,一切顺利。 模式“*b*”也将扩展为“*bb”,星号被删除,“bb”保留。这将创建一个副本C++ c+中的通配符扩展+;,c++,recursion,wildcard-expansion,C++,Recursion,Wildcard Expansion,我正在试验一个递归函数来进行通配符扩展。星号“*”可以扩展为0-n个字符 示例:模式“*b*”将扩展为“bb*”,删除星号并保留“bb”。到目前为止,一切顺利。 模式“*b*”也将扩展为“*bb”,星号被删除,“bb”保留。这将创建一个副本 我的问题是,我的递归代码是否存在根本性的错误。 我的目标是使扩展不创建重复项。 下面的递归代码是最简单的,我添加了代码,因此很容易看到唯一的字符串和重复的字符串 #include <stdio.h> #include <string>
我的问题是,我的递归代码是否存在根本性的错误。 我的目标是使扩展不创建重复项。 下面的递归代码是最简单的,我添加了代码,因此很容易看到唯一的字符串和重复的字符串
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// Forward declarations
void WildcardExpansion(const char* key, int nodeLevel);
size_t SeparateDuplicates(vector<string>& vec, vector<string>& dup);
// Global varables
int g_maxWordLen;
int g_minWordLen;
vector <string> g_words; // Generated words here
int main()
{
int d, u, i;
vector<string> duplicates;
g_maxWordLen = 2; // Max length of generated words
g_minWordLen = 2; // Min length
WildcardExpansion("*b*", 0); // Collects all generated words in g_words
SeparateDuplicates(g_words, duplicates); // Separates the duplicates from g_words
u = (int)g_words.size(); // Size of unique words
d = (int)duplicates.size(); // Size of duplicated words
printf("Unique count: %d\n", u);
for (i = 0; i < u; i++)
printf("%s\n", g_words[i].c_str());
printf("Duplicate count: %d\n", d);
for (i = 0; i < d; i++)
printf("%s\n", duplicates[i].c_str());
return 0;
}
////////////////////////////////////////////////////////////////////////
// Recursive function to do wildcard expansion
// Key can contain one or more wildcards, '*' but not in sequence
// (** is equal to * but is not handled here)
//
void WildcardExpansion(const char* key, int charPos)
{
int letter;
int keyLen;
int astCount;
char c;
char* p;
char keyX[20];
strcpy(keyX, key);
astCount = 0;
p = keyX;
while (*p) // Count asterisks
if (*p++ == '*')
astCount++;
keyLen = (int)strlen(keyX) - astCount; // Letter count
if (keyLen > g_maxWordLen)
return; // Too long word
do // while c
{
c = key[charPos];
switch (c)
{
case '*': // -> key[nodeLevel] == '*'
{
//
// Remove one asterisk
//
strcpy(keyX + charPos, key + charPos + 1);
WildcardExpansion(keyX, charPos); // Recurs same level
strcpy(keyX, key); // Copy original with wildcard back for replacement below
//
// Replace * with letter a-z
// *b* -> bb* -> bb AND *b* -> *bb -> bb => Duplicates!
//
for (letter = 0; letter < 26; letter++)
{
keyX[charPos] = ('a' + letter); // Replace * with letter
strcpy(keyX + charPos + 1, key + charPos); // Expanded: abc -> abc*
WildcardExpansion(keyX, charPos + 1); // Recurs next level
}
return;
} // *
case '\0': // Found a complete word without wildcards
{
if (keyLen < g_minWordLen)
return;
g_words.push_back(key);
break;
}
default: // Dive deeper
{
charPos++;
}
} // switch
} while (c);
}
///////////////////////////////////////////////////////////////////////
// Helper function to store the duplicates in a separate vector
//
size_t SeparateDuplicates(vector<string>& vec, vector<string>& dup)
{
typename std::vector<string>::iterator it;
std::sort(vec.begin(), vec.end());
it = unique(vec.begin(), vec.end(), [&dup](auto& first, auto& second) -> bool
{
if (first == second)
{
dup.push_back(second);
return true;
}
return false;
});
vec.resize(distance(vec.begin(), it));
return dup.size();
}
使用
std::set
而不是矢量来表示单词?我不理解扩展规则-主要是因为你没有给出它们。总是从左到右填充星号不是解决了这个问题吗?当你使用调试器运行程序时,你看到了什么?这正是调试器的用途。如果您不知道如何使用调试器,这是一个很好的机会,可以学习如何使用调试器一次运行一行程序,监视所有变量及其值的变化,并分析程序的逻辑执行流。了解如何使用调试器是每个C++开发人员所需的技能,没有例外。在调试器的帮助下,您应该能够快速找到您编写的以及将来编写的所有程序中的所有问题,而无需向任何人寻求帮助。“我的问题是,我的递归代码是否存在根本性的错误。”。我不明白:你的代码有效吗?如果确实如此,关于代码审查的问题是离题的;如果没有,那么您需要通过观察到的输出与预期输出,准确地显示问题的完整性
Unique count: 51
ab
ba
bb
bc
bd
be
bf
bg
bh
bi
bj
bk
bl
bm
bn
bo
bp
bq
br
bs
bt
bu
bv
bw
bx
by
bz
cb
db
eb
fb
gb
hb
ib
jb
kb
lb
mb
nb
ob
pb
qb
rb
sb
tb
ub
vb
wb
xb
yb
zb
Duplicate count: 1
bb