Array.Reverse算法?

时间:2010-05-28 16:48:15

标签: c# .net algorithm

什么样的算法Array.Reverse(字符串a),在场景后面用来反转字符串?

6 个答案:

答案 0 :(得分:9)

可能是标准的就地反转算法。

function reverse-in-place(a[0..n])
 for i from 0 to floor(n/2)
     swap(a[i], a[n-i])

来源

答案 1 :(得分:9)

更新:请参阅本答案的底部,了解在.NET中就地转换字符串的一个真正令人恐怖的分支。


“好”答案

在.NET中,没有Array.Reverse重载需要string。也就是说,如果它存在的话,这就是如何实现的:

static string ReverseString(string str) {
    char[] reversed = new char[str.Length];
    for (int i = 0; i < reversed.Length; ++i)
        reversed[i] = str[str.Length - 1 - i];
    return new string(reversed);
}

请注意,在.NET中,此方法必须返回一个string,因为System.String类型是不可变的,因此您无法就地反转。< / p>


可怕答案

好的,actually, it is possible to reverse a string in-place in .NET

这是一种方法,需要在unsafe模式下进行编译:

static unsafe void ReverseString(string str) {
    int i = 0;
    int j = str.Length - 1;

    fixed (char* fstr = str) {
        while (i < j) {
            char temp = fstr[j];

            fstr[j--] = fstr[i];
            fstr[i++] = temp;
        }
    }
}

这是另一种使用反射的方法,需要在unsafe模式下编译:

static void ReverseString(string str) {
    int i = 0;
    int j = str.Length - 1;

    // what a tricky bastard!
    MethodInfo setter = typeof(string).GetMethod(
        "SetChar",
        BindingFlags.Instance | BindingFlags.NonPublic
    );

    while (i < j) {
        char temp = str[j];

        setter.Invoke(str, new object[] { j--, str[i] });
        setter.Invoke(str, new object[] { i++, temp });
    }
}

完全不明智和鲁莽,是的 - 更不用说它可能会有可怕的表现。但仍有可能。


恐怖

哦,顺便说一句,万一你怀疑自己应该从不做这样的事情:请注意我所使用的ReverseString方法之一上面提供的实际上允许你编写以下完全奇怪的程序:

ReverseString("Hello!");
Console.WriteLine("Hello!");

以上代码将输出,信不信由你:

!olleH

所以是的,除非你想要在你的代码中彻底解决问题,否则不要在原地反转字符串。即使技术上你可以;)

*如果你不相信我,你可以自己试试。

答案 2 :(得分:3)

该算法可能使用两个指针 i j ,它们分别从0开始,长度 -1。然后交换位置 i j 的字符(借助时间变量), i 递增, j < / em>递减1.重复这些步骤,直到两个指针彼此相交( i j )。

在伪代码中:

i := 0;
j := a.length-1;
while (i < j) do
    tmp := a[i];
    a[i] := a[j];
    a[j] := tmp;
    i := i+1;
    j := j-1;
endwhile;

答案 3 :(得分:3)

根据Reflector,Array.Reverse(Array)(没有字符串变体)首先调用名为TrySZReverse的东西,我找不到实现。我认为它是某种经过大量优化的原生方法..

如果失败了,它会做这样的事情:

int num = index;
int num2 = (index + length) - 1;
while (num < num2)
{
    object obj2 = objArray[num];
    objArray[num] = objArray[num2];
    objArray[num2] = obj2;
    num++;
    num2--;
}

所以,一个就地算法,它在每一端交换值,然后重复向内移动。

答案 4 :(得分:2)

这是一个通用的,与语言无关的,适合问题的答案:它将输入字符串复制到输出字符串,从一端读取​​并写入另一端。

答案 5 :(得分:0)

我的建议:

    private string Reverse(string text)
    {
        char[] c = text.ToCharArray(0, text.Length);
        Array.Reverse(c);
        return new string(c);
    }