劍指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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章