zoukankan      html  css  js  c++  java
  • 倒转字符串的另一种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的空间。但比起分配一个和原数组等长的栈,大大的节省了空间。

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

  • 相关阅读:
    python第二课
    python第一课
    Python基础20-类的创建与删增改查
    Python基础19模块-hashlib模块
    Python基础18模块-configerparse模块
    Python基础17模块-logging模块
    Python基础16模块-re模块
    Python基础-15模块-OS模块
    Python基础-14模块-random模块
    Python基础-13模块-时间模块
  • 原文地址:https://www.cnblogs.com/Jax/p/1718710.html
Copyright © 2011-2022 走看看