剑指offer(python)---字符串类

01-替换空格

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

思路1:直接使用python自带的replace函数,replace(要替代处,替代品)

class Solution:     # s 源字符串
    def replaceSpace(self, s):
        s = s.replace(' ','%20')
        return s
    
if __name__=='__main__':
    s = Solution()
    print(s.replaceSpace('We Are Happy'))

方法2:将长度为1的空格替换为长度为3的“%20”,字符串的长度变长。 如果允许我们开辟一个新的数组来存放替换空格后的字符串,
那么这道题目就非常简单。设置两个指针分别指向新旧字符串首元素, 遍历原字符串,如果碰到空格就在新字符串上填入“%20”,
否则就复制元字符串上的内容。但是如果面试官要求 在原先的字符串上操作,并且保证原字符串有足够长的空间来存放替换后的字符串,

那么我们就得另想方法。 首先遍历原字符串,找出字符串的长度以及其中的空格数量,
根据原字符串的长度和空格的数量我们可以求出最后新字符串的长度。
设置两个指针point1和point2分别指向原字符串和新字符串的末尾位置。
(这里为什么取末尾开始遍历,而不是取起始开始遍历,是为了利用point1point2这个判断条件)
如果point1指向内容不为空格,那么将内容赋值给point2指向的位置,
如果point1指向为空格,那么从point2开始赋值“02%” 直到point1
point2时表明字符串中的所有空格都已经替换完毕。
原文:https://blog.csdn.net/Yeoman92/article/details/77865878

class Solution:
    def replaceSpace(self, oldString):
        blankNumber = 0#空格的数量
        oldStringLen = len(oldString)#原字符串的长度

        #遍历原字符串,找出字符串的空格数量
        for i in range(oldStringLen):
            if oldString[i] == ' ':
                blankNumber += 1

        #计算新字符串的长度
        newStringLen = oldStringLen + blankNumber * 2
        #声明新字符串列表(因为字符串是不可改变的)
        newStringList = [' '] * newStringLen

        #设置两个指针,分别指向那个原字符串和新字符串的末尾位置
        point1 = oldStringLen - 1
        point2 = newStringLen - 1

        #遍历替换
        while point1 != point2:#如果两个指针位置不同,则表明没有替换完成
            if oldString[point1] != ' ':#字符不为空
                newStringList[point2] = oldString[point1]
                point1 -= 1
                point2 -= 1
            else:
                newStringList[point2] = '0'
                newStringList[point2-1] = '2'
                newStringList[point2-2] = '%'
                point1 -= 1
                point2 -= 3

        #把指针恰好相同时,之前的字符也补上
        if point1 > 0:
            for i in range(point1,-1,-1):
                newStringList[i] = oldString[i]

        #把字符串数组组合为字符串
        newString = ''
        for i in range(newStringLen):
            newString += str(newStringList[i])

        return newString

#测试用例
s = Solution()
print(s.replaceSpace('We Are Happy'))

02-正则表达式匹配

题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配

思路1—直接一个条件一个条件进行匹配
解这题需要把题意仔细研究清楚,反正我试了好多次才明白的。
首先,考虑特殊情况:
1>两个字符串都为空,返回true
2>当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法
匹配成功了,而如果第一个字符串空了,第二个字符串非空,还是可能匹配成
功的,比如第二个字符串是“aaaa”,由于‘’之前的元素可以出现0次,
所以有可能匹配成功)
之后就开始匹配第一个字符,这里有两种可能:匹配成功或匹配失败。但考虑到pattern
下一个字符可能是‘
’, 这里我们分两种情况讨论:pattern下一个字符为‘’或
不为‘
’:
1>pattern下一个字符不为‘’:这种情况比较简单,直接匹配当前字符。如果
匹配成功,继续匹配下一个;如果匹配失败,直接返回false。注意这里的
“匹配成功”,除了两个字符相同的情况外,还有一种情况,就是pattern的
当前字符为‘.’,同时str的当前字符不为‘\0’。
2>pattern下一个字符为‘
’时,稍微复杂一些,因为‘’可以代表0个或多个。
这里把这些情况都考虑到:
a>当‘
’匹配0个字符时,str当前字符不变,pattern当前字符后移两位,
跳过这个‘’符号;
b>当‘
’匹配1个或多个时,str当前字符移向下一个,pattern当前字符
不变。(这里匹配1个或多个可以看成一种情况,因为:当匹配一个时,
由于str移到了下一个字符,而pattern字符不变,就回到了上边的情况a;
当匹配多于一个字符时,相当于从str的下一个字符继续开始匹配)
之后再写代码就很简单了。

# -*- coding:utf-8 -*-
class Solution:
    # s, pattern都是字符串
    def match(self, s, pattern):
        # 如果s与pattern都为空,则True
        if len(s) == 0 and len(pattern) == 0:
            return True
        # 如果s不为空,而pattern为空,则False
        elif len(s) != 0 and len(pattern) == 0:
            return False
        # 如果s为空,而pattern不为空,则需要判断
        elif len(s) == 0 and len(pattern) != 0:
            # pattern中的第二个字符为*,则pattern后移两位继续比较
            if len(pattern) > 1 and pattern[1] == '*':
                return self.match(s, pattern[2:])
            else:
                return False
        # s与pattern都不为空的情况
        else:
            # pattern的第二个字符为*的情况
            if len(pattern) > 1 and pattern[1] == '*':
                # s与pattern的第一个元素不同,则s不变,pattern后移两位,相当于pattern前两位当成空
                if s[0] != pattern[0] and pattern[0] != '.':
                    return self.match(s, pattern[2:])
                else:
                    # 如果s[0]与pattern[0]相同,且pattern[1]为*,这个时候有三种情况
                    # pattern后移2个,s不变;相当于把pattern前两位当成空,匹配后面的
                    # pattern后移2个,s后移1个;相当于pattern前两位与s[0]匹配
                    # pattern不变,s后移1个;相当于pattern前两位,与s中的多位进行匹配,因为*可以匹配多位
                    return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern)
            # pattern第二个字符不为*的情况
            else:
                if s[0] == pattern[0] or pattern[0] == '.':
                    return self.match(s[1:], pattern[1:])
                else:
                    return False

03-表示数值的字符串

题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

思路1-直接逐一条件实验

# -*- coding:utf-8 -*-
class Solution:
    # s字符串
    def isNumeric(self, s):
        # write code here
        if s is None or len(s) == 0:
            return False

        # 是否有e
        hasE = False
        # 是否有小数
        isDecimal = False
        # 是否有+-符号
        hasSign = False

        for i in range(len(s)):
            # 如果有e,只能有一个e且不能是最后一个
            if s[i] == "e" or s[i] == "E":
                if hasE or i == len(s) - 1:
                    return False
                hasE = True
            # 小数点不能重复出现或和e共线
            elif s[i] == ".":
                if hasE or isDecimal:
                    return False
                isDecimal = True
            elif s[i] == "-" or s[i] == "+":
                # 重复出现符号时,必须跟在e后面
                if hasSign and s[i - 1] != "e" and s[i - 1] != "E":
                    return False
                # 重复出现符号时,必须跟在e后面
                if not hasSign and i > 0 and s[i - 1] != "e" and s[i - 1] != "E":
                    return False
                hasSign = True
            elif s[i] < "0" or s[i] > "9":
                return False
        return True

04-字符流中第一个不重复的字符

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

思路1—直接使用count函数进行计算

# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.c=""
    def FirstAppearingOnce(self):
        for s in self.c:
            if self.c.count(s)==1:
                return s
        return "#"
    def Insert(self, char):
        self.c=self.c+(char)

类中的方法第一个参数是 self 的才可以被实例调用。
类中带 self 的参数都是 实例 的,实例对这个参数拥有所有权,即实例中所有的方法都可以使用实例的参数。
至于参数什么时候用加self什么时候不用加self,我想你只要弄白了self到底起什么作用,这个问题就不说自明了。

字符串的排列*

题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

题目分析:

  1. 字符串不能为0,同时字符串长度不超过9,即len(string)<=9

思路1:
2、将求字符串的全排列分解为两步:
第一步是确定第一个位置的字符,就是第一个位置与后边的所有字符进行交换。
第二步,就是对除了第一个位置的后边所有位置的字符进行相同处理;直至剩下一个字符,打印;
具体的算法流程如下
在这里插入图片描述
把s[0]固定在位置0上,[1,n-1]位置的数字全排(递归)
把s[1]固定在位置0上(把s[1]和s[0]交换),[1,n-1]位置的数字全排(递归)
……
如果第i个数字在前面出现过,则跳过
……
把s[n-1]固定在位置0上(把s[n-1]和s[0]交换),[1,n-1]位置的数字全排(递归)

在这里插入图片描述
递归的出口,就是只剩一个字符的时候,递归的循环过程,就是从每个子串的第二个字符开始依次与第一个字符交换,然后继续处理子串,如果有重复的,然后对结果使用set去重就可以了

# -*- coding:utf-8 -*-
class Solution:
    def Permutation(self, ss):
        if not ss:
            return []
        res = []
        self.helper(ss, res, '')
        return sorted(list(set(res)))

    def helper(self, ss, res, path):
        if not ss:
            res.append(path)
        else:
            for i in range(len(ss)):
                self.helper(ss[:i] + ss[i+1:], res, path + ss[i])

原文:https://blog.csdn.net/fuxuemingzhu/article/details/79513101 

def perm(s=''):
    if len(s) <= 1:
        return [s]
    sl = []
    for i in range(len(s)):
        for j in perm(s[0:i] + s[i + 1:]):
            sl.append(s[i] + j)
    return sl


def main():
    # 可能包含重复的串
    perm_nums = perm('abb')
    # 对结果去重
    no_repeat_nums = list(set(perm_nums))
    print('perm_nums', len(perm_nums), perm_nums)
    print('no_repeat_nums', len(no_repeat_nums), no_repeat_nums)
    pass


if __name__ == '__main__':
    main()

原文:https://blog.csdn.net/sty945/article/details/79839567 

左旋转字符串

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

思路:
思路:
可以把需要左旋的字符串看成一部分,其他的字符串看成另一部分,比如字符串“abcdef”,需要输出左移2位的结果,可以把字符串“ab”看成一部分,字符串“cdef”看成另一部分,先翻转“ab”得到“ba”,再翻转”cdef“得到”fedc“,两个字符串租在一起之后是”bafedc“,最后对整个字符串进行一次翻转得到”cdefab“,刚好是原来字符串左旋2位之后的结果

# -*- coding:utf-8 -*-
class Solution:
    def LeftRotateString(self, s, n):
        ans = []
        if s :
            lists=list(s)#字符串转换为列表
            ans = lists[n:]
            ans.extend(lists[0:n])  #前闭后开
        return ''.join(ans)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章