在c++中实现类似sql的顺序
Implementing SQL-like order in C++
是否有一个算法在c++中排序多列?或者用其他方式,比如SQL用非常简单的方式,ORDER BY <>,<>
?例如,给定SQL SillyData表:
当我做的时候SELECT * FROM SillyData ORDER BY Age, FavouriteFruet, LuckyNumber
,这产生结果:
我能想到的是一个list
的tuple
s。但然后我必须按第一个tuple
类型排序,锁定它的顺序,然后第二个,……等等......看起来又复杂又笨重。有更好的办法吗?
假设您希望对字符串进行不区分大小写的比较,这是一个起点:
#include <tuple>
#include <string>
#include <iostream>
#include <cstring>
#include <functional>
struct row
{
std::string Name;
int Age;
std::string FavouriteFruet;
int LuckyNumber;
};
auto index_order(const row& r)
{
auto as_upper = [](std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), [](auto c){return std::toupper(c); });
return s;
};
return std::make_tuple(std::cref(r.Age), as_upper(r.FavouriteFruet), std::cref(r.LuckyNumber), as_upper(r.Name));
}
int main()
{
std::vector<row> results =
{
{ "Mary", 22, "Apple", 2},
{ "Alice", 22, "Banana", 7},
{ "Bob", 21, "Orange", 8},
{ "Mark", 21, "Apple", 0},
{ "John", 22, "Banana", 3},
};
std::sort(results.begin(), results.end(),
[](auto const& l, auto const& r)
{
return index_order(l) < index_order(r);
});
for (auto const& r : results)
{
std::cout << r.Name << " | " << r.Age << " | " << r.FavouriteFruet << " | " << r.LuckyNumber << 'n';
}
}
预期输出:Mark | 21 | Apple | 0
Bob | 21 | Orange | 8
Mary | 22 | Apple | 2
John | 22 | Banana | 3
Alice | 22 | Banana | 7
您可以使用std::stable_sort。例如,我为类型info
定义了不同的单独排序函数,并将它们与std::stable_sort一起使用,以实现我想要的任何相对排序:
struct info
{
std::string name;
int age;
std::string fav_fruit;
int fav_number;
// static functions define sorting methods
static bool sort_by_name(info const& lhs, info const& rhs)
{
return lhs.name < rhs.name;
}
static bool sort_by_age(info const& lhs, info const& rhs)
{
return lhs.age < rhs.age;
}
static bool sort_by_fav_fruit(info const& lhs, info const& rhs)
{
return lhs.fav_fruit < rhs.fav_fruit;
}
static bool sort_by_fav_number(info const& lhs, info const& rhs)
{
return lhs.fav_number < rhs.fav_number;
}
// friend function provides output operator
friend std::ostream& operator<<(std::ostream& os, info const& i)
{
return os << i.name << 't' << i.age << 't' << i.fav_fruit << 't' << i.fav_number;
}
};
int main()
{
std::vector<info> infos
{
{"Mary", 22, "Apple", 2},
{"Alice", 22, "Banana", 7},
{"Bob", 21, "Orange", 8},
{"Mark", 21, "Apple", 0},
{"John", 22, "Banana", 3},
};
// std::stable_sort will not rearrange the currently sorted order
// of items that are otherwise considered equal in terms of the current
// sort condition
// NOTE: We sort them in reverse order of importance, the most significant
// ordering being the last one imposed
std::stable_sort(infos.begin(), infos.end(), info::sort_by_fav_number);
std::stable_sort(infos.begin(), infos.end(), info::sort_by_fav_fruit);
std::stable_sort(infos.begin(), infos.end(), info::sort_by_age);
std::cout << "NametAgetFruittNumber" << 'n';
std::cout << "----t---t-----t------" << 'n';
for(auto i: infos)
std::cout << i << 'n';
}
输出:Name Age Fruit Number
---- --- ----- ------
Mark 21 Apple 0
Bob 21 Orange 8
Mary 22 Apple 2
John 22 Banana 3
Alice 22 Banana 7
您可能需要一些字典顺序。
所以使用std::lexicographical_compare可能传递给一些std::sort作为比较测试。
(我希望你至少使用c++ 11)
相关文章:
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 数到第n个楼梯的路(顺序无关紧要)
- 优先顺序:智能指针和类析构函数
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- QML按钮点击功能执行顺序
- C++中数据类型修饰符的顺序
- 当比特(而不是字节)的顺序至关重要时的持久性
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 通过选项卡的文本设置QTabWidget顺序
- c++11评估顺序(未定义的行为)
- 如何使用c++在VS 2019上运行SQL查询
- 如何在C++中递归地按相反顺序打印集合
- System.InvalidCastException - SQL to C++ - safe_cast<float>
- 给定顺序中的事件处理
- 具有包含其他对象的类的对象创建顺序
- 在c++中实现类似sql的顺序