Python數據結構與算法-字符串

1:字符串的循環左移

給定一個字符串s[0..........N-1],要求把S的前k個字符移動到S的尾部,如把字符串"abcdef"前面的2個字符'a','b'移動到字符串的尾部得到'cdefab',即左移k

循環左移k=循環右移n-k

核心公式:XY to YX

(X'T')'=YX

def stringLeftReverse(s,n,k):
    s=[i for i in s] #轉化爲列表
    s=transportation(s,0,k-1) #X'
    s=transportation(s,k,n-1) #Y'
    s=transportation(s,0,n-1) #(X'Y')'
    s=''.join(s) #將字符串列表轉化爲字符串
    
    return s
    
      
def transportation(s,left,right): #字符串子序列的轉置
    while left<right:
        #首尾交換
        s[right],s[left]=s[left],s[right]#這樣的操作只能是可變的序列,像字符串這樣的不可修改,需要將字符串轉化爲列表操作,之後轉化爲字符串
        #指針移動
        left+=1
        right-=1
        
    return s #返回字符串本身
    




if __name__=='__main__':
    s='asdfeg'
    n=len(s)
    k=2
    print(stringLeftReverse(s,n,k))

2:字符串的全排列

給定字符串s[0....N-1],設計算法,枚舉字符串的全排列

eg:1234,

1---234全排列

2---134全排列

3---124全排列

4---123全排列

由上述可知這是一個遞歸問題。

(1)遞歸法---字符串的全排列:

def  arrangementString(s,left,right):
    
    if left==right: 
        print(''.join(s)) #將列表轉化爲字符串
    for i in range(left,right+1): #left爲當前遞歸序列的左邊界,right爲右邊界
        #i表示與當前遞歸序列首元素left要交換的元素
        if isRepeat(s,left,i): #判斷是否有重複字符 ,(left,i)注意這裏要查詢的範圍
            continue
        s[i],s[left]=s[left],s[i]
        arrangementString(s,left+1,right) #遞歸全排列 
        s[i],s[left]=s[left],s[i]

        
def isRepeat(s,left,right): #注意
    flag=False
    for i in range(left,right):
        if s[i]==s[right]:
            flag=True
            break
    return flag
               
        
if __name__=='__main__':
    s='ABA'
    s=[i for i in s] #將字符串轉化爲列表
    left=0
    right=len(s)-1
    arrangementString(s,0,right)

(2)非遞歸法---字符串的全排列:

思路:先找出最小的;之後依次找出他的下一個比他大的排列。

問題化解爲:下一個排列問題。

下一個排列問題:思路:從最末尾向前依次查找,當不滿足升序停止。之後從停止位置向後查找,找出所有大於停止位置數值的元素,且找出最小的。之後交換停止位元素和最小元素。之後翻轉,停止位之後的元素。

總結爲:後找,大小,交換,反轉。

def arrangementString(s,left,right):
    s=sorted(s)
    res=[]
    while True:
        res.append(''.join(s))
        s=nextArrangeString(s,left,right) #尋找下一個大的全排列
        if not s:
            break
    return res

def nextArrangeString(s,left,right):
    
    #後找
    i=right-1 
    while i>=0:
        if s[i]>=s[i+1]:
            i-=1
        else:
            break
    #判斷有無升序,即是否爲最後一個全排列   
    flag=True
    if i==-1:
        flag=False
        return flag
    #大小
    j=i+1
    while j<=right:
        if s[j]>s[i]:
            j+=1
        else:
            break
    minimum=min(s[i+1:j])
    ind=s.index(minimum)
    #交換
    s[i],s[ind]=s[ind],s[i]
    #翻轉
    s[i+1:right+1]=sorted(s[i+1:right+1])
    s=s[0:i+1]+s[i+1:right+1]
    return s
    
    
if __name__=='__main__':
    s='211'
    s=[i for i in s] #將字符串轉化爲列表
    left=0
    right=len(s)-1
    print(arrangementString(s,left,right))

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章