我需要帮助排序元素向量并随后处理已排序向量的范围。字符串向量最初使用默认运算符<谓词
考虑以下未排序字符串向量
std::vector<std::string> strings = {
"1A", "3C1", "1B", "1C1", "4D", "1C1"
}
std::sort(strings.begin(), strings.end(), std::less <std::string > );
排序后,最终将字符串排序为以下字符串排序:
"1A", "1B", "1C1", "1C1", "3C1", "4D"
在我的情况下,我想迭代这些有序的字符串,将它们分成 [begin,end] 范围,使用第一个数字字符作为值比较器 - 我不知道如何在没有获得视觉工作室指示&#34;序列未订购&#34;
"1A", "1B", "1C1", "1C1"
第二组应包含
"3C1"
和最后一组
"4D"
我一直在使用仅搜索前导数字的谓词来试验 std :: equal_range ,但它一直指示&#34;序列未被排序&#34; (编辑 - 这是我遇到的一个错误,因为我使用的是比较器,而不是尊重底层集合的现有顺序的<_ strong>)。我认为这是因为现有的排序范围(使用std :: less作为谓词与我的谓词不同,以提取子范围是问题的根源。有关如何将此有序列表分解为子范围的任何帮助都将非常感谢。
编辑注意事项:虽然回答了上述问题,但我想通过一个可靠的例子让问题更加清晰,以便其他人可以了解我的动摇。我过度简化了我试图解决的问题,实际问题使用了一个包含4个字段的类(1个可选),因此,我没有提供足够的细节来显示我在使用equal_range参数时遇到问题(特别是我传递的值)进入相等的范围和相应的比较器,用于严格按照这个比较器排序元素 - 这也必须尊重基础集合的现有顺序)。事实证明,问题解决起来非常简单 - 我只需要更改显式默认 PriorityValue 构造函数 - 将这4个args转换为非显式构造函数,我可以在其中传递&#34; channel& #34; field作为单个arg构造函数参数。因此,我对equal_range的调用如下:
// lambda to compare channels in ascending order
const auto channelComp = [](const PriorityLevel& a, const PriorityLevel& b) {
return a.getChannel() < b.getChannel();
};
auto range = std::equal_range(gPriorities.begin(), gPriorities.end(), 1, channelComp);
// print all common channel entries
std::cout << "priorites with channel [1]" << std::endl;
std::cout << "Channel, PriorityChar, filename, [optional sequence]" << std::endl;
std::copy(range.first, range.second,
std::ostream_iterator<PriorityLevel>(std::cout, "\n"));
我在 coliru 中有一个实例,说明我修复问题的位置 - 我希望这很有用。
unsorted
Channel, PriorityChar, filename, [optional sequence]
1A[foo._dr]
3A[bar._dr]
1B[foo._dr]1
1B[bar._dr]1
1B[foo._dr]2
1B[bar._dr]2
1B[foo._dr]3
1B[foo._dr]3
1B[foo._dr]4
1B[foo._dr]5
2A[foo._dr]
2B[foo._dr]1
2B[foo._dr]2
2B[foo._dr]3
2B[foo._dr]2
sorted - ascending
Channel, PriorityChar, filename, [optional sequence]
1A[foo._dr]
1B[bar._dr]1
1B[bar._dr]2
1B[foo._dr]1
1B[foo._dr]2
1B[foo._dr]3
1B[foo._dr]3
1B[foo._dr]4
1B[foo._dr]5
2A[foo._dr]
2B[foo._dr]1
2B[foo._dr]2
2B[foo._dr]2
2B[foo._dr]3
3A[bar._dr]
priorites with channel [1]
Channel, PriorityChar, filename, [optional sequence]
1A[foo._dr]
1B[bar._dr]1
1B[bar._dr]2
1B[foo._dr]1
1B[foo._dr]2
1B[foo._dr]3
1B[foo._dr]3
1B[foo._dr]4
1B[foo._dr]5
priorites with channel [2]
Channel, PriorityChar, filename, [optional sequence]
2A[foo._dr]
2B[foo._dr]1
2B[foo._dr]2
2B[foo._dr]2
2B[foo._dr]3
答案 0 :(得分:2)
这是一个有效的例子:
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <iostream>
#include <ostream>
bool initial_char_comp( std::string const& s1, std::string const& s2)
{
if (s1.size() == 0 || s2.size() == 0) {
return s1.size() < s2.size();
}
return s1[0] < s2[0];
}
int main(int argc, char ** argv) {
std::vector<std::string> strings = {
"1A", "3C1", "1B", "1C1", "4D", "1C1"
};
std::sort(strings.begin(), strings.end(), std::less<std::string>());
for (auto i = strings.cbegin(); i != strings.cend(); ++i) {
std::cout << *i << " ";
}
std::cout << std::endl;
for (char c = '1'; c < '5'; ++c) {
auto range = std::equal_range( strings.cbegin(), strings.cend(), std::string(1, c), initial_char_comp);
std::cout << "range starting with '" << c << "': ";
for (auto i = range.first; i != range.second; ++i) {
std::cout << *i << " ";
}
std::cout << std::endl;
}
return 0;
}