我正在尝试使用递归函数来进行通配符扩展。星号“*”可以扩展为 0-n 个字符。
示例:模式 '*b*' 将扩展为 'bb*',星号被移除而 'bb' 保留。到目前为止,一切都很好。模式 '*b*' 也将扩展为 '*bb',去掉星号,保留 'bb'。这会创建一个副本。
我的问题是我的递归代码是否存在根本性错误。我的目标是让扩展不会产生重复。下面的递归代码是最低限度的,我已经添加了代码,因此很容易看到唯一的字符串和重复的字符串。
#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();
}
输入“*b*”,输出长度2。观察输出:
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