有没有办法以特定方式显示cpp地图
Is there a way to display cpp map in a specific way
我需要向用户显示以下座位并能够预订和取消预订。
class luxaryBus {
public:
std::map<std::string, int> seats{ {"1A", 0}, {"1B", 0}, {"1C", 0}, {"1D", 0},{"1E", 0},
{"2A", 0}, {"2B", 0}, {"2C", 0}, {"2D", 0},{"2E", 0},
{"3A", 0}, {"3B", 0}, {"3C", 0}, {"3D", 0},{"3E", 0},
{"4A", 0}, {"44", 0}, {"4C", 0}, {"4D", 0},{"4E", 0},
{"5A", 0}, {"5B", 0}, {"5C", 0}, {"5D", 0},{"5E", 0},
{"6A", 0}, {"6B", 0}, {"6C", 0}, {"6D", 0},{"6E", 0},
{"7A", 0}, {"7B", 0}, {"7C", 0}, {"7D", 0},{"7E", 0},
{"8A", 0}, {"8B", 0}, {"8C", 0}, {"8D", 0},{"8E", 0},
{"9A", 0}, {"9B", 0}, {"9C", 0}, {"9D", 0},{"9E", 0},
{"10 A", 0}, {"10B", 0}, {"10C", 0}, {"10D", 0},{"10E", 0},
{"11 A", 0}, {"11B", 0}};
void displaySeats();
}
void luxaryBus::displaySeats()
{
int test = 0;
for (const auto& p : this->seats) {
if (test == 5) {
std::cout << std::endl;
test = 0;
}
test++;
std::cout << p.first << p.second << "\t ";
}
}
显然,它以一种对我不起作用的方式对字符串进行排序:
1A 10A 10B 10C etc...
我也试过unordered_map,但无论我做什么,我都无法让地图以我想要的方式显示座位(1A、1B、1C、1D、1E)。
1A 1B 1C 1D 1E
2A 2B 2C 2D 2E ....
试图将席位名称更改为 A1 B1 C1 D1...显然我是 C++ 的新手。我知道地图是 ordered.And 我知道使用 unordered_map 我无法保证地图的显示方式。
我的问题是,我能否以特定方式使用地图,以便以我想要的方式显示它。或者,是否有另一种 C++ 数据结构可用于我的任务。
Array 是我的第一选择,但是,我发现很难跟踪售出的座位并处理取消。现在我可以使用 2 个数组,一个用于字符串表示,一个用于处理预订和取消操作。
任何人都可以给我建议如何解决这个问题吗?
std::map 使用比较 operator<
来比较映射中的键。然而,问题是字符串是按字典顺序比较的,所以 "1A"
和 "10A"
都小于 "1B"
.
但是你可以使用更复杂的映射:std::map<std::pair<int, char>, int>
其中键是数字和字符。这里数字将作为数字进行比较,字符作为字符进行比较。
像这样使用它:
std::map<std::pair<int, char>, int> map{{{1, 'B'}, 0}, {{1, 'C'}, 0}};
PS:你可以像这里一样覆盖输出:
std::ostream& operator<<(std::ostream& out, const std::map<std::pair<int, char>, int>& map)
{
for (const auto& p : map) {
out << p.first.first << p.first.second << " ";
}
return out;
}
int main() {
std::map<std::pair<int, char>, int> map{{{1, 'B'}, 0}, {{1, 'C'}, 0}};
std::cout << map;
return 0;
}
您可以放入自定义比较器,按照您想要的顺序对地图中的数据进行排序。
这个可以参考下面的代码:
auto seatCompare = [](std::string const& seat1, std::string const& seat2) -> bool {
std::smatch result1;
std::smatch result2;
std::regex pattern(R"(([0-9]+)([a-z A-Z]+))");
if (!regex_match(seat1, result1, pattern) || !regex_match(seat2, result2, pattern)) {
throw std::runtime_error("Seat name invalid!");
}
if (std::stoi(result1[1]) == std::stoi(result2[1])) {
return result1[2] < result2[2];
}
return std::stoi(result1[1]) < std::stoi(result2[1]);
};
std::map<std::string, int, decltype(seatCompare)> seats(seatCompare);
seats = { {"1A", 0}, {"1B", 0}, {"1C", 0}, {"1D", 0},{"1E", 0},
{"2A", 0}, {"2B", 0}, {"2C", 0}, {"2D", 0},{"2E", 0},
{"3A", 0}, {"3B", 0}, {"3C", 0}, {"3D", 0},{"3E", 0},
{"4A", 0}, {"4B", 0}, {"4C", 0}, {"4D", 0},{"4E", 0},
{"5A", 0}, {"5B", 0}, {"5C", 0}, {"5D", 0},{"5E", 0},
{"6A", 0}, {"6B", 0}, {"6C", 0}, {"6D", 0},{"6E", 0},
{"7A", 0}, {"7B", 0}, {"7C", 0}, {"7D", 0},{"7E", 0},
{"8A", 0}, {"8B", 0}, {"8C", 0}, {"8D", 0},{"8E", 0},
{"9A", 0}, {"9B", 0}, {"9C", 0}, {"9D", 0},{"9E", 0},
{"10A", 0}, {"10B", 0}, {"10C", 0}, {"10D", 0},{"10E", 0},
{"11A", 0}, {"11B", 0}};
或 C++98 风格
struct SeatCompare {
bool operator()(std::string const& seat1, std::string const& seat2)
{
std::smatch result1;
std::smatch result2;
std::regex pattern(R"(([0-9]+)([a-z A-Z]+))");
if (!regex_match(seat1, result1, pattern) || !regex_match(seat2, result2, pattern)) {
throw std::runtime_error("Seat name invalid!");
}
if (std::stoi(result1[1]) == std::stoi(result2[1])) {
return result1[2] < result2[2];
}
return std::stoi(result1[1]) < std::stoi(result2[1]);
}
};
std::map<std::string, int, SeatCompare> seats{
{"1A", 0}, {"1B", 0}, {"1C", 0}, {"1D", 0},{"1E", 0},
{"2A", 0}, {"2B", 0}, {"2C", 0}, {"2D", 0},{"2E", 0},
{"3A", 0}, {"3B", 0}, {"3C", 0}, {"3D", 0},{"3E", 0},
{"4A", 0}, {"4B", 0}, {"4C", 0}, {"4D", 0},{"4E", 0},
{"5A", 0}, {"5B", 0}, {"5C", 0}, {"5D", 0},{"5E", 0},
{"6A", 0}, {"6B", 0}, {"6C", 0}, {"6D", 0},{"6E", 0},
{"7A", 0}, {"7B", 0}, {"7C", 0}, {"7D", 0},{"7E", 0},
{"8A", 0}, {"8B", 0}, {"8C", 0}, {"8D", 0},{"8E", 0},
{"9A", 0}, {"9B", 0}, {"9C", 0}, {"9D", 0},{"9E", 0},
{"10A", 0}, {"10B", 0}, {"10C", 0}, {"10D", 0},{"10E", 0},
{"11A", 0}, {"11B", 0}};
我需要向用户显示以下座位并能够预订和取消预订。
class luxaryBus {
public:
std::map<std::string, int> seats{ {"1A", 0}, {"1B", 0}, {"1C", 0}, {"1D", 0},{"1E", 0},
{"2A", 0}, {"2B", 0}, {"2C", 0}, {"2D", 0},{"2E", 0},
{"3A", 0}, {"3B", 0}, {"3C", 0}, {"3D", 0},{"3E", 0},
{"4A", 0}, {"44", 0}, {"4C", 0}, {"4D", 0},{"4E", 0},
{"5A", 0}, {"5B", 0}, {"5C", 0}, {"5D", 0},{"5E", 0},
{"6A", 0}, {"6B", 0}, {"6C", 0}, {"6D", 0},{"6E", 0},
{"7A", 0}, {"7B", 0}, {"7C", 0}, {"7D", 0},{"7E", 0},
{"8A", 0}, {"8B", 0}, {"8C", 0}, {"8D", 0},{"8E", 0},
{"9A", 0}, {"9B", 0}, {"9C", 0}, {"9D", 0},{"9E", 0},
{"10 A", 0}, {"10B", 0}, {"10C", 0}, {"10D", 0},{"10E", 0},
{"11 A", 0}, {"11B", 0}};
void displaySeats();
}
void luxaryBus::displaySeats()
{
int test = 0;
for (const auto& p : this->seats) {
if (test == 5) {
std::cout << std::endl;
test = 0;
}
test++;
std::cout << p.first << p.second << "\t ";
}
}
显然,它以一种对我不起作用的方式对字符串进行排序:
1A 10A 10B 10C etc...
我也试过unordered_map,但无论我做什么,我都无法让地图以我想要的方式显示座位(1A、1B、1C、1D、1E)。
1A 1B 1C 1D 1E
2A 2B 2C 2D 2E ....
试图将席位名称更改为 A1 B1 C1 D1...显然我是 C++ 的新手。我知道地图是 ordered.And 我知道使用 unordered_map 我无法保证地图的显示方式。
我的问题是,我能否以特定方式使用地图,以便以我想要的方式显示它。或者,是否有另一种 C++ 数据结构可用于我的任务。
Array 是我的第一选择,但是,我发现很难跟踪售出的座位并处理取消。现在我可以使用 2 个数组,一个用于字符串表示,一个用于处理预订和取消操作。
任何人都可以给我建议如何解决这个问题吗?
std::map 使用比较 operator<
来比较映射中的键。然而,问题是字符串是按字典顺序比较的,所以 "1A"
和 "10A"
都小于 "1B"
.
但是你可以使用更复杂的映射:std::map<std::pair<int, char>, int>
其中键是数字和字符。这里数字将作为数字进行比较,字符作为字符进行比较。
像这样使用它:
std::map<std::pair<int, char>, int> map{{{1, 'B'}, 0}, {{1, 'C'}, 0}};
PS:你可以像这里一样覆盖输出:
std::ostream& operator<<(std::ostream& out, const std::map<std::pair<int, char>, int>& map)
{
for (const auto& p : map) {
out << p.first.first << p.first.second << " ";
}
return out;
}
int main() {
std::map<std::pair<int, char>, int> map{{{1, 'B'}, 0}, {{1, 'C'}, 0}};
std::cout << map;
return 0;
}
您可以放入自定义比较器,按照您想要的顺序对地图中的数据进行排序。
这个可以参考下面的代码:
auto seatCompare = [](std::string const& seat1, std::string const& seat2) -> bool {
std::smatch result1;
std::smatch result2;
std::regex pattern(R"(([0-9]+)([a-z A-Z]+))");
if (!regex_match(seat1, result1, pattern) || !regex_match(seat2, result2, pattern)) {
throw std::runtime_error("Seat name invalid!");
}
if (std::stoi(result1[1]) == std::stoi(result2[1])) {
return result1[2] < result2[2];
}
return std::stoi(result1[1]) < std::stoi(result2[1]);
};
std::map<std::string, int, decltype(seatCompare)> seats(seatCompare);
seats = { {"1A", 0}, {"1B", 0}, {"1C", 0}, {"1D", 0},{"1E", 0},
{"2A", 0}, {"2B", 0}, {"2C", 0}, {"2D", 0},{"2E", 0},
{"3A", 0}, {"3B", 0}, {"3C", 0}, {"3D", 0},{"3E", 0},
{"4A", 0}, {"4B", 0}, {"4C", 0}, {"4D", 0},{"4E", 0},
{"5A", 0}, {"5B", 0}, {"5C", 0}, {"5D", 0},{"5E", 0},
{"6A", 0}, {"6B", 0}, {"6C", 0}, {"6D", 0},{"6E", 0},
{"7A", 0}, {"7B", 0}, {"7C", 0}, {"7D", 0},{"7E", 0},
{"8A", 0}, {"8B", 0}, {"8C", 0}, {"8D", 0},{"8E", 0},
{"9A", 0}, {"9B", 0}, {"9C", 0}, {"9D", 0},{"9E", 0},
{"10A", 0}, {"10B", 0}, {"10C", 0}, {"10D", 0},{"10E", 0},
{"11A", 0}, {"11B", 0}};
或 C++98 风格
struct SeatCompare {
bool operator()(std::string const& seat1, std::string const& seat2)
{
std::smatch result1;
std::smatch result2;
std::regex pattern(R"(([0-9]+)([a-z A-Z]+))");
if (!regex_match(seat1, result1, pattern) || !regex_match(seat2, result2, pattern)) {
throw std::runtime_error("Seat name invalid!");
}
if (std::stoi(result1[1]) == std::stoi(result2[1])) {
return result1[2] < result2[2];
}
return std::stoi(result1[1]) < std::stoi(result2[1]);
}
};
std::map<std::string, int, SeatCompare> seats{
{"1A", 0}, {"1B", 0}, {"1C", 0}, {"1D", 0},{"1E", 0},
{"2A", 0}, {"2B", 0}, {"2C", 0}, {"2D", 0},{"2E", 0},
{"3A", 0}, {"3B", 0}, {"3C", 0}, {"3D", 0},{"3E", 0},
{"4A", 0}, {"4B", 0}, {"4C", 0}, {"4D", 0},{"4E", 0},
{"5A", 0}, {"5B", 0}, {"5C", 0}, {"5D", 0},{"5E", 0},
{"6A", 0}, {"6B", 0}, {"6C", 0}, {"6D", 0},{"6E", 0},
{"7A", 0}, {"7B", 0}, {"7C", 0}, {"7D", 0},{"7E", 0},
{"8A", 0}, {"8B", 0}, {"8C", 0}, {"8D", 0},{"8E", 0},
{"9A", 0}, {"9B", 0}, {"9C", 0}, {"9D", 0},{"9E", 0},
{"10A", 0}, {"10B", 0}, {"10C", 0}, {"10D", 0},{"10E", 0},
{"11A", 0}, {"11B", 0}};