倒转字符串的另一种BT方法

比如说字符串abcdefgh,那么反转顺序为

abcdefgh => badcfehg => dcbahgfe => hgfedcba

这种算法对于字符串的位数等于2的N次方,是很简单的,比如说,一个长度8的字符串,其反转算法如下:

static string ReverseBitArray2(string str)
{
    if (str == null || str.Length == 1) return str;

    char[] arr = str.ToCharArray();

    int pow = 1;

    while (pow < arr.Length)
    {
        for (int i = 0; i < arr.Length; i = i + pow * 2)
        {
            for (int j = i; j < i + pow; j++)
            {
                char temp = arr[j];
                arr[j] = arr[j + pow];
                arr[j + pow] = temp;
            }
        }

        pow *= 2;
    }

    return new string(arr);
} 

如果字符串的位数不等于2的N次方呢?这也是大多数情况,我们需要额外进行很多判断,逻辑不要太复杂,所以未必是一种好办法。

我们不妨考虑,扩展这个需要反转的字符串,为其尾部添加一些字符,使其长度变成2的N次方,然后就可以使用我们上面的算法了,最后记得开头的若干字符是不要的哦,代码如下:

static string ReverseBitArray2(string str)
{
    if (str == null || str.Length == 1) return str;

    int pow = GetPow(str);

    if (pow == 0)
        return ReverseBitArray(str);
    else
    {
        char[] arr = new char[pow];

        int i = 0;
        while (i < str.Length)
        {
            arr[i] = str[i];
            i++;
        }

        return ReverseBitArray(arr, str.Length);
    }
} 

为此我们要重载ReverseBitArray函数,以适合最普通的情形:

static string ReverseBitArray(char[] arr, int actualLength)
{
    int pow = 1;

    while (pow < arr.Length)
    {
        for (int i = 0; i < arr.Length; i = i + pow * 2)
        {
            for (int j = i; j < i + pow; j++)
            {
                char temp = arr[j];
                arr[j] = arr[j + pow];
                arr[j + pow] = temp;
            }
        }

        pow *= 2;
    }

    return new string(arr, arr.Length - actualLength, actualLength);
}

注:这里我们用到了GetPow函数,如果str的长度是2的N次幂,就返回0;否则,返回大于str长度的最小2的N次幂:

static int GetPow(string str)
{
    int len = str.Length;
    int pow = 2;

    while (pow < len)
    {
        pow = pow << 1;
    }

    if (pow == len)
        return 0;
    else //pow>len
        return pow;
} 

但这种算法需要额外的空间,最糟糕的情况,如果字符串长度为2的N次方+1,那么我们就要多分配2的N次方-1的空间。但比起分配一个和原数组等长的栈,大大的节省了空间。

 

分而治之的思想,妙极!大家细细品味。

 

posted @ 2010-04-23 16:11  包建强  Views(4700)  Comments(28Edit  收藏  举报