如何使用STL算法找到字符串中分隔两个不同字母的最短星号序列
How to find the shortest sequence of asterisks separating two distinct letters in a string using STL algorithms?
我有一个这样的字符串:
A*A**B***A**
我对两个不同字母之间的星号序列感兴趣,特别是我需要找到最短序列的长度。对于上面的字符串,答案当然是2:A**B
我可以使用传统的循环很容易地解决这个问题,我习惯了这样的循环:
const string s = "A*A**B***A**";
string::size_type last_letter=-1, min_seq_len=s.size();
for(int i = 0; i < s.size(); i++) {
if(last_letter == -1 || s[i] == '*' || s[i] == s[last_letter]) {
if(s[i] != '*') {
last_letter = i;
}
} else {
min_seq_len = min(min_seq_len, i-last_letter-1);
last_letter = i;
}
}
但是,使用C++算法库、迭代器等有什么方法可以做到这一点吗?
我问这个问题是因为我注意到我在学习如何使用这些工具来解决算法问题时遇到了困难,相反,我发现手工编写循环更容易。最后,我想学习C++算法、范围、迭代器等的操作。
我对两个不同字母之间的星号序列感兴趣,特别是我需要找到最短的这样的序列的长度。
-
您需要最小化某些内容。您可以使用
std::min_element
。 -
这个东西是一堆"字母+星号+字母"块。使用
std::find_if
可以找到非星号。
然后你需要在算法之间写一些胶水,这样你就可以隐藏在类似STL的接口后面。示例:
auto letter_pairs = letter_pair_generator(s);
const auto min_seq_len = std::min_element(
std::begin(letter_pairs), std::end(letter_pairs),
[](const auto& x) { return x.asterisk_count(); });
其中,letter_pair_generator
是std::string
上的适配器,它公开了一个类似容器的接口,该接口返回两对不同的字母,字母之间带有星号。示例:
string s = "A*A**B***A**";
for(const auto& p : letter_pair_generator(s)) cout << p;
A*A**B
A**B
A***B***A
B***A
相反,我发现手动写循环更容易
有时一个循环比多次调用<algorithm>
更清晰、更快。这本身并没有什么错。使用一个循环并将其包装成一个更安全/更好的界面。
您也可以使用string
中的find_first_not_of
。
size_t min(str.length()), prev(0), found(0);
while((found = str.find_first_not_of("*", prev)) != std::string::npos) {
if (str[found] != str[prev] && found - prev < min) {
min = found + 1 - prev;
}
prev = found + 1;
}
演示
我需要说的是,使用标准库并不能带来巨大的改进。但以std::regex
为例,如果没有明确的字母要求,则示例会简单得多。不管怎样,这是我的尝试。
-
std::string::find_first_not_of
使用int best = s.size(); int prev = -1; int next; while ((next = s.find_first_not_of("*", prev+1)) >= 0) { if (prev >= 0 && s[prev] != s[next]) { best = min(best, next - prev - 1); } prev = next; }
可跑步:https://ideone.com/xdhiQt
-
std::regex
用法:regex r("(?=([^*][*]*[^*]))"); int best = s.size(); for (auto i = sregex_iterator(s.begin(), s.end(), r); i != sregex_iterator(); ++i) { int pos = i->position(1); int len = i->length(1); if (s[pos] != s[pos + len -1]) { best = min(len-2, best); } }
可跑步:https://ideone.com/2UdRGG
- 使用 Dijkstra 算法跟踪两个节点之间的最短路径
- 使用C++具有两个数字的最短路径算法.(C++)
- 如何通过 stl 容器和算法库计算两个向量的内积?
- C++ std::向量插入两个元素替代算法失败
- OPENCV:如何使用5点算法从来自不同相机的两个图像之间的特征匹配来计算必需矩阵
- NTRUEncrypt:使用开源标准算法中的描述无法正确找到两个多项式的GCD,无法定义是否存在多边形的逆
- 关于合并两个列表的算法的一些问题
- 是否存在用于按以下方式对两个范围进行排序和分区的标准算法?
- 使用 Dijkstra 算法计算两个节点之间的最短路径
- 如何在没有 c++ 中的数组/算法的情况下对两个条件的字符串进行排序
- 控制两个顶点之间的中间点数量 - 布雷森汉姆算法的扩展
- Dijkstra算法找到两个顶点之间的最短距离 c++
- 具有两个不同缓冲区的指针算法
- 如何使用STL算法找到字符串中分隔两个不同字母的最短星号序列
- 带有两个递归调用的递归算法的时间复杂性
- 正确的方法比较两个指向算法中使用的指向算法
- 在两个方向上寻找搜索算法 - c / c ++ / awk
- 如何设计一种算法,将两个浮点数相乘而不带"*"?
- 两个袋子的背包算法
- 3D 'shooter'跳跃算法 - C++低级缺陷。两个相同的双打在应该相等的时候并不相等。4.0 != 4.0 显然