zoukankan      html  css  js  c++  java
  • 算法题002 程序员编程艺术第一章 左旋转字符串

      算法题002 程序员编程艺术第一章 左旋转字符串

     

    题目描述

      题目来源:http://blog.csdn.net/v_JULY_v/article/details/6322882

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

      如把字符串abcdef左旋转2位得到字符串cdefab。

      请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)

     

    题目分析

      如果采用每次将数组中的元素移动一位,循环K次的方法,则时间复杂度为O(K * n),只需要额外的一个存储空间。但是这是不合时间复杂度要求的。

      另外需要注意的是K不一定会小于n,所以需要取K = K % n。

      但是这还是不能实现线性复杂度,编程之美上通过右移字符串提出了一个三次翻转的算法。

     

    三次翻转的算法

      可以看到不管是左移还是右移,其结果都是两段子串交换了位置。

      如123abcd这个串,左移三位得到abcd123,实际上是123和abcd交换了位置。

      怎么在线性复杂度内实现这种位置交换呢?三次翻转是这样做到的:

      首先,将123翻转成逆序:321abcd

      然后,将abcd翻转成逆序:321dcba

      最后,将整个串再翻转一遍:abcd123(得到左移结果)。

      通常情况的描述:

      1.根据要移动的位数把字符串划分成两段:XY;

      2.翻转X子段;

      3.翻转Y子段;

      4.将得到的结果整个翻转。

    实现代码

    LeftRotate实现
    #include <iostream>
    #include <string>
    using namespace std;
    
    void ReverseString(string &str)
    {
        int startID = 0;
        int endID = str.size() - 1;
        char temp = ' ';
    
        while(startID < endID)
        {
            temp = str[startID];
            str[startID] = str[endID];
            str[endID] = temp;
    
            ++startID;
            --endID;        
        }
            
    
        //cout<<str<<endl;
    
    
    }
    
    int main(int argc, char* argv[])
    {
    
        string str;
        int k;
        while(cin >> str >> k)
        {
            //首先将k取余数,避免k比串长还大的情况
            k = k % str.size();
    
            //cout << "k: "<< k << endl;
    
            //得到子串
            string x = str.substr(0,k);
            //cout << "x: " << x << endl;
            
            string y = str.substr(k,str.size());
            //cout << "y" << y << endl;
    
    
            //需要注意substr()方法含左不含右
    
            //三次翻转算法
            ReverseString(x);
            ReverseString(y);
            string result = x + y;
            ReverseString(result);
    
            cout << "The final result is: " << result << endl;
    
        }
        return 0;
    }

      

    测试用例

      因为没找到Online Judge,所以自己设计的测试用例:

      输入:

    1234567ABDCD 3

    123 6

    abcd 25

    1234567 0

    g 10

      输出

    The final result is: 4567ABDCD123

    The final result is: 123

    The final result is: bcda

    The final result is: 1234567

    The final result is: g

     

     

    参考资料

      程序员编程艺术第一~二十七章集锦与总结

    http://blog.csdn.net/v_july_v/article/details/7506231

      程序员编程艺术第一章 左旋转字符串

    http://blog.csdn.net/v_JULY_v/article/details/6322882

      搜索到的实现:

    http://www.cnblogs.com/aLittleBitCool/archive/2011/02/22/1961267.html

    http://www.cnblogs.com/mingzi/archive/2009/08/04/1538482.html

     

  • 相关阅读:
    CodeForces 543d Road Improvement
    UVA Foreign Exchange
    ZOJ 1825 Compound Words
    UVA 10125 Sumsets
    CodeForces
    32位linux(centos)下mongoDB的安装
    关于PHP 采集类
    关于微信支付零时工代码的修正方法
    微信公众号申请,微信支付全攻略 2
    简介CentOS与 Ubuntu的不同
  • 原文地址:https://www.cnblogs.com/mengdd/p/2952275.html
Copyright © 2011-2022 走看看