查找字符串的所有可能版本,其字符可能具有多个变体
Find all possible versions of a string whose characters may have multiple variants
我正在寻找一些有关如何查找字符串的所有可能版本的提示,这些字符串的字符可能具有多个变体。
一个简单的例子:"澳门"是起始字符串。字符"a"具有变体"ä",字符"o"具有变体"ö"。
目标是从上述信息中获取以下列表:
Macao
Mäcao
Macäo
Mäcäo
Macaö
Mäcaö
Macäö
Mäcäö
到目前为止,我的方法是识别和提取带有变体的字符以简化事情。这个想法是在各自的字符上工作,而不是整个单词。
aao
äao
aäo
ääo
aaö
äaö
aäö
ääö
以下代码查找我们正在使用的变体。
std::vector<std::string> variants;
variants.push_back("aä");
variants.push_back("oö");
std::string word = "Macao";
std::vector<std::string> results;
for (auto &variant : variants) {
for (auto &character : word) {
if (variant.front() == character) {
results.push_back(variant);
}
}
}
std::cout << "The following characters have variants: ";
for (auto &i : results) {
std::cout << i.front();
}
std::cout << std::endl;
下一步是找到相应字符的所有可能组合。为此,我编写了以下函数。它从 results
中每个字符串的第一个字符创建一个新字符串。
std::string read_results(std::vector<std::string> &results)
{
std::string s;
for (auto &c : results) {
s.push_back(c.front());
}
return s;
}
这个想法是然后以这样一种方式更改存储在results
中的字符串,以获得所有可能的组合,这就是我卡住的地方。我注意到std::rotate
似乎会有所帮助。
倒
排索引可能很有用。
您可以按顺序将具有多个变体的所有字母按顺序存储在一个向量中,并且每个字母都有一个分组索引的向量,以便第 i 个字母属于组I[i]
,并且索引与 I[i]
相同的所有字母都是来自同一字母的变体:
string L = "aoäöâô"; // disclaimer: i don't know if this is really in order
unsigned int I[] = {0,1,0,1,0,1};
// this means that "aäâ" belong to group 0, and "oöô" belong to group 1
您可以为前一个L
构建倒排索引,并使用如下所示的内容进行I
:
vector<vector<unsigned int> > groups;
// groups[k] stores the indices in L of the letters that belongs to the k-th group.
// do groups.reserve to make this operation more efficient
for(size_t i = 0; i < L.size(); ++i)
{
unsigned int idx = I[i];
if(idx <= groups.size()) groups.resize(idx+1);
groups[idx].push_back(i);
}
重要的是,L
中的字母是有序的,所以你可以稍后对它进行二叉搜索,这需要O(logn)
而不是O(n)
通常的循环。然后,一旦你有了你的字母组,你就可以找到它的变体,有一个倒排索引:
char letter = 'a';
string::iterator it = std::lower_bound(L.begin(), L.end(), letter);
if(it != L.end() && *it == letter)
{
unsigned int idx = I[ it - L.begin() ];
// the letter has variants because it belongs to group idx
const vector<unsigned int>& group = groups[idx];
for(vector<unsigned int>::const_iterator git = group.begin();
git != group.end(); ++git)
{
// now, L[*git] is one of the variants of letter
...
}
}
相关文章:
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 将 NULL 与 C 的字符* 字符串一起使用
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- 无法将常量字符字符串传递给模板类
- 如何组合一个宽字符字符串,中间插入一些空字符
- 如何将二维数组类型字符(字符串)作为函数参数传递?
- 从给定索引返回子字符字符串的函数
- 字符 [](c 字符串)的初始化标准
- 如何将字符字符串用作数学运算符
- 将 Unicode 字符/字符串写入文件
- C++,字符* 字符串修改
- 如何有效地用不同的整数元素替换字符字符串的元素
- C++:如果我们在字符串中添加一些整数,为什么它会从开头删除该数量的字符?(字符串 + 整数)
- strcpy正在复制sth字符i字符串.如何解决此错误
- 在C++中将双精度转换为字符*/字符串
- C 中的宽字符字符串
- 如何提取C 中的字符/字符串之间的字符串
- 无法将字符/字符串转换为int
- 带有指针的反转字符字符串
- 反转字符串中的 n 个字符(字符串中没有空格),而不使用 c++ 中的内置函数