左旋转字符串

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

左旋字符串(循环左移字符串):左移串长length位后和原来一样,所以需要左移的是n % str.length()位

 

JS:substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符。

stringObject.substr(start,length)

一个新的字符串,包含从 stringObject 的 start(包括 start 所指的字符) 处开始的 length 个字符。如果没有指定 length,那么返回的字符串包含从 start 到 stringObject 的结尾的字符。

class Solution {
public:
    //左旋字符串(循环左移字符串):左移串长length位后和原来一样,所以正真需要左移的是n % str.length()位
    string LeftRotateString(string str, int n) {
        int len = str.length();
        int trueSet = n % len;
        if(n == 0 || len <= 1)//空串和单字符串左移无意义
            return str;
        return str.substr(n) + str.substr(0, n);
    }
};

小明同学需要对一个长度为 N 的字符串进行处理,他需要按照要求执行若干步骤,每个步骤都均为下面 2 种操作中的一种,2 种操作如下:
TYPE 1. 从字符串结尾开始算起,将第 X 个字符之前的字符移动到字符串末尾
TYPE 2. 输出字符串索引为 X 的字符
小明尝试了很久没能完成,你可以帮他解决这个问题吗?

输入描述:

第一行,包含两个整数,字符串的长度 N 和操作次数T;
第二行为要操作的原始字符串;

之后每行都是要执行的操作类型 TYPE 和操作中 X 的值,均为整数。

输入范围:
字符串长度 N:1 <= N <= 10000
操作次数 T:1 <= T <= 10000
操作类型 TYPE:1 <= TYPE<= 2
变量 X:0 <= X < N

输出描述:

操作的执行结果

示例1

输入

复制

6 2
xiaomi
1 2
2 0

输出

复制

m

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int N,T;   //字符串长度N,操作次数T
    cin >> N >> T;
    cin.ignore();   //cin后用getline前一定要ignore吃回车
    string str;
    getline(cin,str);
    while(T--)
    {
        int type,x;
        cin >> type >> x;   
        if(type == 1) //type=1将字符串的倒数第x字符前的字符全移动到字符串末尾
        {
            string t = str.substr(0,str.length()-x);
            //cout << t << endl;
            str = str.substr(str.length()-x,x) + t;
            //cout << str << endl;
        }
        else  //type=2将字符串的第x个字符进行输出
        {
            cout << str[x] << endl;
        }
    }
    return 0;
}

 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

join()函数同时也是操作字符串的一个非常重要的函数,join与split可以说是俩个互逆的函数。split()函数可用来通过某个标识符将字符串拆分为集合,而join()函数则是把一个集合中所有的值按照自定义的分隔符连接起来,eg:

 

>>> letter1=['a','b','c','d','e']

>>> letter2='f','g','h','i','j'

>>> sep='-'

>>> print sep.join(letter1);

a-b-c-d-e

>>> print"/".join(letter2)

f/g/h/i/j

>>

实例:列车路线查询系统。首先在列表中国保存每条线路的站点,当用户输入目的城市的拼音简写时,程序将相应的路线通过join()方法截取并且返回在显示控制台提供用户参考。

Split()字符串截取

该函数用来将字符串通过某些标识符进行分割为序列,

strip用于去除字符串的首位字符。

lstrip用于去除左边的字符

rstrip用于去除右边的字符。​

PYTHON

class Solution:
 # s 源字符串
 def replaceSpace(self, s):
     # write code here
     if not s:
        return ''
     return  '%20'.join(s.split(' '))
    
      

 

描述

Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串

语法

split() 方法语法:

str.split(str="", num=string.count(str)).

参数

  • str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
  • num -- 分割次数。默认为 -1, 即分隔所有。

返回值

返回分割后的字符串列表。

实例

以下实例展示了 split() 函数的使用方法:

实例(Python 2.0+)

#!/usr/bin/python # -*- coding: UTF-8 -*- str = "Line1-abcdef \nLine2-abc \nLine4-abcd";

print str.split( ); # 以空格为分隔符,包含 \n

print str.split(' ', 1 ); # 以空格为分隔符,分隔成两个

以上实例输出结果如下:

['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']//以空格为分隔符,不会将字符串中的元素减少

以下实例以 # 号为分隔符,指定第二个参数为 1,返回两个参数列表。

实例(Python 2.0+)

#!/usr/bin/python # -*- coding: UTF-8 -*- txt = "Google#Runoob#Taobao#Facebook" # 第二个参数为 1,返回两个参数列表 x = txt.split("#", 1) print x

以上实例输出结果如下:

['Google', 'Runoob#Taobao#Facebook']

str.split(' ')
———————————————————————————————————————————————————
1.按某一个字符分割,如‘.’

>>> s = ('www.google.com')
>>> print(s)
www.google.com
>>> s.split('.')
['www', 'google', 'com']

2.按某一个字符分割,且分割n次。如按‘.’分割1次;参数maxsplit位切割的次数

>>> s = 'www.google.com'
>>> s
'www.google.com'
>>> s.split('.', maxsplit=1)
['www', 'google.com']

3.按某一字符串分割。如:‘||’

>>> s = 'WinXP||Win7||Win8||Win8.1'
>>> s
'WinXP||Win7||Win8||Win8.1'
>>> s.split('||')
['WinXP', 'Win7', 'Win8', 'Win8.1']
>>> 

' '.join(str)
 

Python中有join()和os.path.join()两个函数,具体作用如下:
               join():    连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串
              os.path.join():  将多个路径组合后返回

#对序列进行操作(分别使用' '与':'作为分隔符)
  
>>> seq1 = ['hello','good','boy','doiido']
>>> print ' '.join(seq1)
hello good boy doiido
>>> print ':'.join(seq1)
hello:good:boy:doiido

#对字符串进行操作
  
>>> seq2 = "hello good boy doiido"
>>> print ':'.join(seq2)
h:e:l:l:o: :g:o:o:d: :b:o:y: :d:o:i:i:d:o

#对元组进行操作
>>> seq3 = ('hello','good','boy','doiido')
>>> print ':'.join(seq3)
hello:good:boy:doiido

#对字典进行操作
>>> seq4 = {'hello':1,'good':2,'boy':3,'doiido':4}
>>> print ':'.join(seq4)
boy:good:doiido:hello

#合并目录
>>> import os
>>> os.path.join('/hello/','good/boy/','doiido')
'/hello/good/boy/doiido'

str.strip()

声明:s为字符串,rm为要删除的字符序列

s.strip(rm)        删除s字符串中开头、结尾处,位于 rm删除序列的字符;

s.lstrip(rm)       删除s字符串中开头处,位于 rm删除序列的字符;

s.rstrip(rm)       删除s字符串中结尾处,位于 rm删除序列的字符;

1. 当rm为空时,默认删除空白符(包括'\n', '\r',  '\t',  ' ')

      例如:


>>> a = '123abc'
>>> a.strip('21')
'3abc'   结果是一样的
>>> a.strip('12')
'3abc'

2.这里的rm删除序列是只要边(开头或结尾)上的字符在删除序列内,就删除掉。

    例如 :

>>> a = '123abc'
>>> a.strip('21')
'3abc'   结果是一样的
>>> a.strip('12')

'3abc'

1.调用自带的函数:



public class Solution {
    public String replaceSpace(StringBuffer str) {
        return str.toString().replace(" ", "%20");
    }
}

2.用新的数组存:


import java.util.*;
public class Solution {
    public String replaceSpace(StringBuffer str) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<str.length();i++){
            char c = str.charAt(i);
            if(c == ' '){
                sb.append("%20");
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

3.正则表达式: 

function replaceSpace(str) {
    return str.replace(/ /g, "%20");
}

4.双指针:

因为字符串是不可变的,所以如果直接采用从头到尾遍历原字符串检查空格,并且做替换。那么每次检查到空格后,都需要重新生成字符串。整个过程时间复杂度是 O(N^2)。

优化的关键:提前计算替换后的字符串的长度,避免每次都对字符串做改动。

整体思路如下:

  1. 遍历原字符串,统计空格和非空格字符个数,计算替换后的新字符的长度
  2. 准备两个指针,指针 j指向原字符串,指针 i指向新字符串
  3. j从头开始遍历原字符串
    • str[j]是非空格,那么将 j指向的字符放入新字符串的 i位置。i 和 j 都增加 1。
    • str[j]是空格,那么 j指向的位置依次填入%20。j增加 1,i增加 3。

时间复杂度是 O(N)。因为需要对新字符串开辟容器,空间复杂度是 O(N)。


function replaceSpace(str) {
    if (!str || !str.length) {
        return "";
    }
 
    let emptyNum = 0,
        chNum = 0;
    for (let i = 0; i < str.length; ++i) {
        if (str[i] === " ") {
            ++emptyNum;//第一次循环找到这个字符串里面空格的个数
        } else {
            ++chNum;//非空字符串的个数 
        }
    }
 
    const length = emptyNum * 2 + chNum;//新的替换后的长度
    const chs = new Array(length);
    // i 是新字符串的下标
    // j 是原字符串的下标
    for (let i = 0, j = 0; j < str.length; ++j) {
        if (str[j] === " ") {
            chs[i++] = "%";
            chs[i++] = "2";
            chs[i++] = "0";
        } else {
            chs[i++] = str[j];
        }
    }
 
    return chs.join("");//加上双引号
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值