在我的假设应用程序中,我收到了服务器上的酒店列表。
struct Hotel
{
std::string name; // e.g. Hilton, Ritz
int stars; // In range [0..5], 0 stands for "unrated"
int freeRoomCount; // Number of available rooms [0..N]
int parkingPlacesAvailable; // Number of parking places availalble [0..M]
}
std::vector<Hotel> hotels;
所有这些项目都以简单的列表视图显示 我必须提供不同类型的排序。排序规则也由中央服务器决定。
排序规则如下:
std::string sortingRules;
// "s" - sort by stars count
// "f" - sort by free room count
// "p" - sort by parking places available
// The sortingRules string can be a combination of those values. E.g.:
// "ps" - first goes who has the most number of parking places available,
// then goes hotels who has more stars
// More combinations available:
// "s", "sf", "fp", "pf", "spf", "" etc.
// (16 possible combinations, the empty string means alphabetical sorting)
所以问题是:如何在C ++中解释这个?枚举和位掩码值不起作用,因为它们不提供“顺序”控件。
我很好奇社区将如何解决这类任务?我觉得有一种方法可以解决这类问题,这就是为什么我不想直截了当地编写如下代码:
if (sortingRules[0] == "s") ...
我正在使用C ++ 11和Qt 5.4。没有提升。
答案 0 :(得分:3)
我使用一个读取字符的简单解析器,将std::stable_sort
与字符的相关比较谓词一起应用,然后继续使用下一个字符。
stable_sort部分非常重要。这意味着,如果您首先按星号排序项目,然后按停车位排序,则星号的顺序将保留。
答案 1 :(得分:2)
您可以在他们的选择和仿函数之间制作地图,例如
using SortFun = bool(*)(Hotel const&, Hotel const&);
std::map<char, SortFun> sorters {
{'s', [](Hotel const& lhs, Hotel const& rhs){ return lhs.stars < rhs.stars; }},
{'f', [](Hotel const& lhs, Hotel const& rhs){ return lhs.freeRoomCount < rhs.freeRoomCount; }},
{'p', [](Hotel const& lhs, Hotel const& rhs){ return lhs.parkingPlacesAvailable < rhs.parkingPlacesAvailable; }}
};
然后,您可以通过要求用户输入排序条件键来使用它,然后您可以使用std::stable_sort
查找要排序的正确lambda。对于排序标准的组合,例如"ps"
,您可以按相反的顺序循环遍历每个排序键和std::stable_sort
。
int main()
{
using SortFun = bool(*)(Hotel const&, Hotel const&);
std::map<char, SortFun> sorters {
{'s', [](Hotel const& lhs, Hotel const& rhs){ return lhs.stars < rhs.stars; }},
{'f', [](Hotel const& lhs, Hotel const& rhs){ return lhs.freeRoomCount < rhs.freeRoomCount; }},
{'p', [](Hotel const& lhs, Hotel const& rhs){ return lhs.parkingPlacesAvailable < rhs.parkingPlacesAvailable; }}
};
std::vector<Hotel> hotels {{"foo", 5, 4, 10},
{"bar", 3, 8, 20},
{"baz", 4, 5, 15},
{"fab", 3, 6, 18}};
std::string choice;
std::cout << "Pick a sort criteria s, f, p: ";
std::cin >> choice;
for (auto rit = choice.rbegin(); rit != choice.rend(); ++rit)
{
auto match = sorters.find(*rit);
if (match != sorters.end())
{
std::stable_sort(begin(hotels), end(hotels), match->second);
}
}
for(auto const& hotel : hotels)
{
std::cout << "Name: " << hotel.name << " Stars: " << hotel.stars << " Rooms: " << hotel.freeRoomCount << " Parking: " << hotel.parkingPlacesAvailable << std::endl;
}
}
输出为(working demo)
Pick a sort criteria s, f, p: sf
Name: fab Stars: 3 Rooms: 6 Parking: 18
Name: bar Stars: 3 Rooms: 8 Parking: 20
Name: baz Stars: 4 Rooms: 5 Parking: 15
Name: foo Stars: 5 Rooms: 4 Parking: 10
要从最高到最低排序,只需在lambda函数中将所有<
切换为>
。