C#:交换方法的好/最佳实现

问题描述 投票:11回答:6

我读了此post about card shuffling,在许多改组和排序算法中,您需要交换列表或数组中的两个项目。但是,一种有效且高效的Swap方法是什么样的?

假设T[]List<T>。您如何最好地实现在这两个项目中交换两个项目的方法?

Swap(ref cards[i], ref cards[n]);   // How is Swap implemented?
c# sorting shuffle
6个回答
25
投票

[好,您发布的代码(ref cards[n])只能与数组(而不是列表)一起使用-但您可以简单地使用(其中foobar是两个值):

static void Swap(ref int foo, ref int bar) {
    int tmp = foo;
    foo = bar;
    bar = tmp;
}

或者可能(如果需要原子的话:

Interlocked.Exchange(ref foo, ref bar);

就个人而言,我不认为我会为交换方法烦恼-只需直接执行;这意味着您可以使用(用于列表或数组):

int tmp = cards[n];
cards[n] = cards[i];
cards[i] = tmp;

如果您真的想编写对列表数组有效的交换方法,则必须执行以下操作:

static void Swap(IList<int> list, int indexA, int indexB)
{
    int tmp = list[indexA];
    list[indexA] = list[indexB];
    list[indexB] = tmp;
}

((使它通用)将是微不足道的-但是,在数组上工作的原始“内联”版本(即,不是方法)会更快。


4
投票

用途:

void swap(int &a, int &b)
{
    // &a != &b
    // a == b OK
    a ^= b;
    b ^= a;
    a ^= b;
    return;
}

我没有意识到我在C#部分中。这是C ++代码,但应该具有相同的基本思想。我相信^在C#中也是XOR。看起来好像不需要&,您可能需要“ ref”(?)。我不确定。


3
投票

良好的交换是您不交换内容的交换。在C / C ++中,这类似于交换指针而不是交换内容。这种交换方式很快,并带有一些例外保证。不幸的是,我的C#太生锈了,无法将其放入代码中。对于简单的数据类型,此样式不能给您太多帮助。但是一旦您习惯了并且不得不处理更大(或更复杂)的对象,它便可以挽救您的生命。


3
投票

那呢?这是交换方法的通用实现。 Jit只会为您的封闭类型创建一个编译版本,因此您不必担心性能!

/// <summary>
/// Swap two elements
/// Generic implementation by LMF
/// </summary>
public static void Swap<T>(ref T itemLeft, ref T itemRight) {
    T dummyItem = itemRight;
    itemLeft = itemRight;
    itemRight = dummyItem;
}

HTH洛伦佐


0
投票

对于任何想知道的人,也可以使用扩展方法(.NET 3.0及更高版本)来进行交换。

[通常,似乎没有办法说扩展方法“ this”的值为ref,因此您需要返回它并覆盖旧值。

public static class GeneralExtensions {
    public static T SwapWith<T>(this T current, ref T other) {
        T tmpOther = other;
        other = current;
        return tmpOther;
    }
}

然后可以这样使用此扩展方法:

int val1 = 10;
int val2 = 20;    
val1 = val1.SwapWith(ref val2);

0
投票

11年后,我们有元组...

(foo, bar) = (bar, foo);
© www.soinside.com 2019 - 2024. All rights reserved.