gpt4 book ai didi

ORDER BY 在结构上的 C++ 实现

转载 作者:可可西里 更新时间:2023-11-01 16:39:58 25 4
gpt4 key购买 nike

我在这里和其他网站上也进行了很多搜索,但没有找到令人满意的内容。

我需要的是非常简单的任务——主要是在 C++ 中构造 ORDER BY 运算符。这意味着我有许多不同数据类型成员的结构,我需要一个比较器来配置成员和排序。这是我的伪代码想法:

comparator.add(&MyStruct::member1, std::less);
comparator.add(&MyStruct::member2, std::greater);
std::sort(my_vector.begin(), my_vector.end(), comparator);

然后我得到按 member1 排序的数据,如果相等则由 member2 决定,依此类推。

我不太擅长 STL 和模板,但我可以阅读和破译一些代码并发现这是非常合适的解决方案:https://stackoverflow.com/a/11167563

不幸的是,在我的工作中,我必须使用带有错误 32 位编译器的 C++ 构建器,该编译器拒绝编译此正确代码。它确实support almost nothing from c++11 , 它有 boost 1.39 可用。

有人可以利用我的资源提供适合我的解决方案吗?提前谢谢你

编辑:

我得到了非常专业的解决方案,其中包含我知道的硬写比较运算符,但在这里效果不佳。我在我的问题中错过了这个。我的结构至少有 15 个成员,正如我所写的,我需要经常更改成员/列(asc、desc)的个人排序方向。同样,我需要经常更改排序成员集,例如,就像在 sql 中按运算符排序一样。我也不能使用 stable_sort 之类的东西,因为我只是在为某个类的 OnCompare 事件之类的东西编写比较器。

最佳答案

这并不难。首先,考虑“规范”排序关系:

struct Compare
{
bool operator()( C const& lhs, C const& rhs ) const
{
return lhs.a < rhs.a
|| ( !(rhs.a < lhs.a) && lsh.b < rhs.b )
|| ( !(rhs.a < lhs.a) && !(rhs.b < lhs.b) && lhs.c < rhs .c )
|| ...
}
};

显然,实际上没有人会写这样的东西,但是它完全符合什么是的正式定义需要。

当然,如果我们可以把数据成员想象成一个数组,我们可以将其重写为一个循环,利用之前的成立!(rhs[i-1] < lsh[i-1]在每种情况下:

struct Compare
{
bool operator()( C const& lhs, C const& rhs ) const
{
int i = 0;
while ( i != N && !(lhs[i] < rhs[i]) && !(rhs[i] < lhs[i]) ) {
++ i;
}
return i != N && lhs[i] < rhs[i];
}
};

或者,如果所有元素都是完全有序的,那么 ==是也定义在他们身上,我们可以假设它对应于弱偏建立的等价关系订购:

struct Compare
{
bool operator()( C const& lhs, C const& rhs ) const
{
int i = 0;
while ( i != N && !(lhs[i] == rhs[i]) ) {
++ i;
}
return i != N && lhs[i] < rhs[i];
}
};

剩下的就是以某种方式将其转化为某种东西可以处理任意元素的任意排序类型。有句老话说,解决所有问题是一个额外的间接级别,它适用于此。

首先,我们需要一些方法来处理不同类型的每个元素。多态性似乎是合适的(尽管如果模板可以工作评估的元素在编译时是固定的):

struct CompareOneElementOfC
{
virtual bool isLessThan( C const& lhs, C const& rhs) const = 0;
virtual bool isEqual( C const& lhs, C const& rhs) const = 0;
};

template <typename T, T C::*ptr>
struct ConcreteCompareOneElementOfC : public CompareOneElementOfC
{
virtual bool isLessThan( C const& lhs, C const& rhs) const
{
return lhs.*ptr < rhs.*ptr;
}
virtual bool isEqual( C const& lhs, C const& rhs) const
{
return lhs.*ptr == rhs.*ptr;
}
};

根据元素的类型,你可能需要手工写出具体的具体事例。如果任何元素不支持总排序,你将不得不省略 isEqual , 并相应修改以下代码。

到目前为止,我们只需要一个静态实例具体比较:

ConcreteCompareOneElementOfC<int, &C::a> const c1;
ConcreteCompareOneElementOfC<double, &C::b> const c2;
// ...

最后把这些实例的地址放到一个表中:

CompareOneElementOfC const* const cmp[] = { &c1, &c2 ... };

您可以针对不同的顺序使用不同的表格。如果有只有少数,为每个定义静态表,并完成它。如果顺序可以是任意的,则在在每个排序之前按照所需的顺序飞行。

最后:

class Compare
{
CompareOneElementOfC const* const* begin;
CompareOneElementOfC const* const* end;
public:
template< size_t N >
Compare( CompareOneElementOfC const* const (&cmp)[N] )
: begin( cmp )
, end( cmp + N )
{
}
bool
operator()( C const& lhs, C const& rhs ) const
{
auto current = begin;
while ( current != end && (*current)->isEqual( lhs, rhs ) ) {
++ current;
}
return current != end && (*current)->isLessThan( lhs, rhs );
}
}

(请注意,我还没有实际测试过这段代码,所以可能是拼写错误和其他错误。仍然是基本思想应该在那里。)

关于ORDER BY 在结构上的 C++ 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18781212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com