• 左旋转字符串 【微软面试100题 第二十六题】


    题目要求:

      定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。

      例如:把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转函数。

      参考资料:剑指offer第42题、编程珠玑第二章

    题目分析:

      方法1 临时空间法:将前i个元素先复制到临时空间中,然后将余下的n-i个元素前移i个位置,最后再把临时空间中的元素放到余下的位置。【分析:如果前i个元素数据量很大,那么临时空间将会很消耗。】

      方法2 逐步旋转法:定义一个函数(其功能是将整个向量左旋1位),然后重复调用这个函数i次。【分析:这样会很耗时。】

      方法3 杂技法:把a[0]放入一个临时元素中,然后把a[i]放到a[0],a[2i]放到a[i],以此类推(前提是ki < n。如果ki > n,则ki对n取余,如果余数不等于a[0],则继续循环,否则结束本次循环);然后把a[1]放到一个临时元素中,进行和a[0]一样的操作;然后...a[m]。其中m的大小是i和n的最大公倍数。

      方法4 块变换法:我们将需要旋转的向量x看成是由向量a和b组成的,那么旋转向量x实际上就是将向量ab的两个部分交换为向量ba,这里向量a代表x的前i个元素。那么整体的变换步骤就可以总结如下了(假设a比b短):    

        1)将b分割为bl和br两个部分,使得br的长度和a的长度一样(等于i)

       2)交换a和br,即ablbr转换成了brbla。通过本次变换,序列a就位于它的最终位置了。

       3)我们需要集中精力交换b的两个部分了,这个时候就回到了最初的问题上了。

      方法5 翻手算法:时间、空间复杂度和代码简单程度综合性价比最高的算法。

      

    代码实现:

    杂技法:

    #include <stdio.h>
    
    int Gcd(int n,int i);
    void Sort(int a[],int rotate,int len,int gcd);
    
    int main(void)
    {
        int a[5]={1,2,3,4,5};
        int gcd;
    
        gcd = Gcd(5,4);
        Sort(a,4,5,gcd);
    
        for(gcd=0; gcd < 5;gcd++)
        {
            printf("%d",a[gcd]);
        }
        printf("
    ");
    
        return 0;
    }
    int Gcd(int n,int i)
    {
        while(i != n)
        {
            if(i > n)
            {
                i -= n;
            }
            else
            {
                n -= i;
            }
        }
        return i;
    }
    void Sort(int a[],int rotate,int len,int gcd)
    {
        int i,temp,next,before;
        for (i = 0; i < gcd; i++)
        {
            temp = a[i];
            before = i;
            while (1) 
            {
                next = (before + rotate) % len;
                if (next == i) 
                {
                    break;
                } 
                else 
                {
                    a[before] = a[next];
                    before = next;
                }
            }
        a[before] = temp;
        }
    }
    View Code

    块变换法:

    #include <stdio.h>
    
    #define  MAX 10
    char x[MAX] = "abcdefgh";
    
    /* *
        aStart : The start index of block a.
        bStart : The start index of block b.
        length : The size to be swapped.
     */        
    void swap(int aStart, int bStart, int length)
    {
        char tmp;
        while(length-- > 0)
        {
            tmp = x[aStart];
            x[aStart] = x[bStart];
            x[bStart] = tmp;
            aStart++;
            bStart++;
        }
    }
    
    void rotate(int rotdist, int n)
    {
        int i,j;
        int p;
        /* check rotdist */
        if (rotdist == 0 || rotdist == n)
        {
            return;
        }
    
        /* split the array to two block */
        i = p = rotdist;
        j = n - rotdist;
    
        while (i != j)
        {
            if (i > j)
            {
                /* The start of block b never changed
                */
                swap(p - i, p, j);
                i -= j;
            }
            else
            {
                swap(p - i, p+j-i,i);
                j -=i;
            }
        }
    
        /* i == j */
        swap(p-i,p,i);
    }
    
    int main()
    {
        rotate(4,8);
        printf("%s",x);
        return 0;
    }
    View Code

    翻手算法:

    #include <stdio.h>
    
    void reverse(int a[],int start,int end);
    void TurnHands(int a[],int i,int n);
    
    int main(void)
    {
        int a[9]={1,2,3,4,5,6,7,8,9};
        int i;
    
        TurnHands(a,5,9);
    
        for(i = 0;i < 9;i++)
        {
            printf("%d",a[i]);
        }
        printf("
    ");
        return 0;
    }
    void reverse(int a[],int start,int end)
    {
        if(a==NULL)
            return;
        int i=start,j=end,temp;
        for(;i < j;i++,j--)
        {
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    void TurnHands(int a[],int i,int n)
    {
        if(a==NULL)
            return;
        if(i<=0 || n<=0 || i>n)
            return;
        reverse(a,0,i-1);
        reverse(a,i,n-1);
        reverse(a,0,n-1);
    }
    View Code
  • 相关阅读:
    Caused by: java.lang.ClassNotFoundException: com.njupt.libgdxbase.MainActivity
    linux清除邮件队列
    Eclipse+Tomcat部署项目的一些总结
    Eclipse启动Tomcat时45秒超时的解决方法
    easyui的validatebox重写自定义验证规则的几个实例
    几个常用的正则表达式
    easyui的combobox下拉框初始化默认值以及保持该值一直显示的方法
    字符串集合或字符串数组转换成json数组
    spring实战六之使用基于java配置的Spring
    Date类型和Long类型的相互转换
  • 原文地址:https://www.cnblogs.com/tractorman/p/4059594.html
Copyright © 2020-2023  润新知