元素的就地排序

Nor*_*löw 4 d in-place phobos

Phobos是否有一些可变参数算法来定义l值参考参数?就像是

int a=3;
int b=2;
int c=1;

orderInPlace(a,b,c);

// a is now 1
// b is now 2
// c is now 3
Run Code Online (Sandbox Code Playgroud)

另外,一个功能变体,比如order(a, b, c)返回一个元组也会很好.

如果没有,我想我们应该利用std.algorithm:swap.

另见http://forum.dlang.org/thread/eweortsmcmibppmvtriw@forum.dlang.org#post-eweortsmcmibppmvtriw:40forum.dlang.org.

Vla*_*eev 6

Adam的解决方案有效,尽管它使用了元素的临时副本.通过对std.algorithm的一个小修改,可以编写一个对就地元素进行排序的版本:

import std.algorithm;
import std.stdio;
import std.traits;
import std.typecons;

struct SortableRef(T)
{
    private T * _p;
    @property ref T value() { return *_p; }
    alias value this;
    void opAssign(T * value) { _p = value; }
    @disable void opAssign(SortableRef!T value);
    void proxySwap(SortableRef!T other) { swap(*_p, *other._p); }
}

template PointerTo(T) { alias T* PointerTo; }
void orderInPlace(T...)(ref T values)
    if (!is(CommonType!(staticMap!(PointerTo, T)) == void))
{
    alias CommonType!T E;
    SortableRef!E[values.length] references;
    foreach (i, ref v; values)
        references[i] = &v;
    references[].sort();
}

void main()
{
    int a=3;
    int b=1;
    int c=2;
    orderInPlace(a, b, c);
    writeln([a, b, c]);
}
Run Code Online (Sandbox Code Playgroud)

但是,只有传递给的值orderInPlace很大,不可分配或者复制不切实际时才是实用的.


Ada*_*ppe 5

我不认为Phobos有一个,但你可以这样做:

void orderInPlace(T...)(ref T t) {
    import std.algorithm;
    T[0][T.length] buffer;
    foreach(idx, a; t)
        buffer[idx] = a;
    auto sorted = sort(buffer[]);
    foreach(idx, a; t)
        t[idx] = sorted[idx];
}
Run Code Online (Sandbox Code Playgroud)

std.algorithm,sort需要一个数组,但这很容易 - 我们将元组复制到堆栈数组中,对其进行排序,然后将信息复制回元组.所以也许并不完美,但它确实有效.您可以通过返回t而不是执行ref来使其正常工作.

  • 由于这是一个模板,因此每个不同的参数集都会产生一个专门的函数. (2认同)