亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python最長回文串算法

 更新時間:2018年06月04日 08:37:08   作者:熊熊不愛說話  
這篇文章主要為大家詳細介紹了python最長回文串算法的實踐,具有一定的參考價值,感興趣的小伙伴們可以參考一下

給定一個字符串,要求在這個字符串中找到符合回文性質(zhì)的最長子串。所謂回文性是指諸如 “aba”,"ababa","abba"這類的字符串,當然單個字符以及兩個相鄰相同字符也滿足回文性質(zhì)。

看到這個問題,最先想到的解決方法自然是暴力枚舉,通過枚舉字符串所有字串的起點,逐一判斷滿足回文性的子串,記錄長度并更新最長長度。顯然這種算法的時間復雜度是很高的,最壞情況可以達到O(N*N)。所以呢,這里提出一個優(yōu)化的方案,通過枚舉字符串子串的中心而不是起點,向兩邊同時擴散,依然是逐一判斷子串的回文性。這種優(yōu)化算法比之前的算法在最壞的情況下(即只有一種字符的字符串)效率會有很大程度的上升。

由上述的優(yōu)化方案,我們知道了枚舉中心要比枚舉起點效率要好,然而這并不是最優(yōu)的算法。由于枚舉中心的算法同時影響的是中心兩邊的字符,所以我們可以通過枚舉中心的左邊字符作為中心的子串的回文性判斷枚舉中心右邊的字符作為中心得子串的回文性,這就是manacher算法。

manacher算法思想非常巧妙,首先遍歷字符串,假設 i 為枚舉中心,則 j (j<i) 為中心的最長回文子串長度發(fā)f[j] 便已經(jīng)求出,此時 j 的影響范圍便是[j-f[j]/2,j+f [j]] 。為了使左邊的字符 j 對枚舉中心右邊的影響最大,需要使 j+f[j]/2 最大。找到滿足j+f[j]/2最大的 j 之后,若 i 在[j,j+f[j]/2]中,則分兩種情況:

1 . i 關于 j 對稱的字符i'的影響范圍完全包含在j的影響范圍內(nèi),則由于回文性,i 的影響范圍大于等于i'的影響范圍,即f[i]>=f[i']

2. i 關于 j 對稱的字符i'的影響范圍不完全包含在j的影響范圍內(nèi),此時i的右側影響范圍大于等于[j-f[j]/2,i'],即i+f[i]/2>=i'-j+f[j]/2

由于對稱性,可得i+i" = 2*j。因此第一種情況下,f[i]>=f[2*j-i];第二種情況下,f[i]>=f[j]+2*j-2*i。

綜上1,2,可得f[i]>=min(f[2*j-i],f[j]+2*j-2*i)。由于i右邊存在未遍歷的字符,因此在此基礎上,繼續(xù)向兩邊擴展,直到找到最長的回文子串。

若i依然在j+f[j]/2后面,則表示i沒有被前面的字符的影響,只能逐一的向兩邊擴展。

這個算法由于只需遍歷一遍字符串,擴展的次數(shù)也是有限的,所以時間復雜度可以達到O(N)。

下面是Pthon3的程序,為了檢測算法的效率,依然提供最初的暴力枚舉算法作為最壞算法的參照。

python代碼:

#求最長回文串類 
class LPS:      
 #初始化,需要提供一個字符串 
 def __init__(self,string): 
  self.string = string 
  self.lens = len(self.string) 
  
 #暴力枚舉:作為算法效率參照 
 def brute_force(self): 
  maxcount = 0 
  for j in range(self.lens):      
   for k in range(j,self.lens): 
    count = 0 
    l,m = j,k 
    while m>=l: 
     if self.string[l]==self.string[m]: 
      l,m = l+1,m-1 
     else: 
      break 
    if m<l: 
     count = k-j+1 
    if count>maxcount : 
     maxcount = count 
  return maxcount 
  
 #優(yōu)化版:枚舉子串中心 
 def brute_force_opti(self): 
  maxcount = 0 
  if self.lens == 1:        #只有一個字符直接返回1 
   return 1 
  for j in range(self.lens-1):     #枚舉中心 
   count,u = 1,j 
   #對于奇數(shù)子串,直接擴展 
   for k in range(1,j+1):      #兩邊擴展 
    l,m = u+k,j-k 
    if (m>=0)&(l<self.lens): 
     if(self.string[l]==self.string[m]): 
      count += 2 
     else: 
      break 
   if count>maxcount :       #更新回文子串最長長度 
    maxcount = count 
   if self.string[j]==self.string[j+1]:  #處理偶數(shù)子串,將兩個相鄰相同元素作為整體 
    u,count= j+1,2 
   for k in range(1,j+1):      #兩邊擴展 
    l,m = u+k,j-k 
    if (m>=0)&(l<self.lens): 
     if(self.string[l]==self.string[m]): 
      count += 2 
     else: 
      break 
   if count>maxcount :       #更新回文子串最長長度 
    maxcount = count 
  return maxcount 
   
 #manacher算法 
 def manacher(self): 
  s = '#'+'#'.join(self.string)+'#'    #字符串處理,用特殊字符隔離字符串,方便處理偶數(shù)子串 
  lens = len(s) 
  f = []           #輔助列表:f[i]表示i作中心的最長回文子串的長度 
  maxj = 0          #記錄對i右邊影響最大的字符位置j 
  maxl = 0          #記錄j影響范圍的右邊界 
  maxd = 0          #記錄最長的回文子串長度 
  for i in range(lens):       #遍歷字符串 
   if maxl>i:         
    count = min(maxl-i,int(f[2*maxj-i]/2)+1)#這里為了方便后續(xù)計算使用count,其表示當前字符到其影響范圍的右邊界的距離 
   else :          
    count = 1 
   while i-count>=0 and i+count<lens and s[i-count]==s[i+count]:#兩邊擴展 
    count +=1 
   if(i-1+count)>maxl:       #更新影響范圍最大的字符j及其右邊界 
     maxl,maxj = i-1+count,i               
   f.append(count*2-1) 
   maxd = max(maxd,f[i])      #更新回文子串最長長度 
  return int((maxd+1)/2)-1      #去除特殊字符 

通過上面的程序,使用字符串為長度1000的純‘a(chǎn)'字符串作為樣例,經(jīng)過測試:

暴力枚舉:49.719844s

中心枚舉:0.334019s

manacher:0.008000s

由此可見,長度為1000時,暴力枚舉的耗時已經(jīng)無法忍受了,而相比而言,中心枚舉在效率上已經(jīng)有很大幅度的提升,最優(yōu)的manacher耗時則為更短。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 兩個使用Python腳本操作文件的小示例分享

    兩個使用Python腳本操作文件的小示例分享

    這篇文章主要介紹了兩個使用Python腳本操作文件的小示例分享,兩個程序包括創(chuàng)建和讀寫文件等功能,需要的朋友可以參考下
    2015-08-08
  • Python實現(xiàn)批量將符合要求的文件自動復制到新文件夾

    Python實現(xiàn)批量將符合要求的文件自動復制到新文件夾

    這篇文章主要為大家詳細介紹了如何使用Python實現(xiàn)批量將文件名稱符合要求的文件自動復制到新文件夾,文中的示例代碼講解詳細,有需要的小伙伴可以參考下
    2023-10-10
  • Python爬蟲基礎講解之scrapy框架

    Python爬蟲基礎講解之scrapy框架

    scrapy是一個使用Python語言(基于Twisted框架)編寫的開源網(wǎng)絡爬蟲框架,目前由scrapinghub Ltd維護.Scrapy簡單易用、靈活易拓展、開發(fā)社區(qū)活躍,并且是跨平臺的.在Linux、MaxOS以及windows平臺都可以使用,需要的朋友可以參考下
    2021-06-06
  • python中線程和進程有何區(qū)別

    python中線程和進程有何區(qū)別

    在本篇文章里小編給大家整理的是一篇關于python中線程和進程的區(qū)別相關知識點,有需要的朋友們可以參考下。
    2020-06-06
  • python3 與python2 異常處理的區(qū)別與聯(lián)系

    python3 與python2 異常處理的區(qū)別與聯(lián)系

    這篇文章主要介紹了python3 與python2 異常處理的區(qū)別與聯(lián)系的相關資料,需要的朋友可以參考下
    2016-06-06
  • opencv改變imshow窗口大小,窗口位置的方法

    opencv改變imshow窗口大小,窗口位置的方法

    下面小編就為大家分享一篇opencv改變imshow窗口大小,窗口位置的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • pyecharts的Tab和Legend布局詳情

    pyecharts的Tab和Legend布局詳情

    這篇文章主要介紹了pyecharts的Tab和Legend布局,pyecharts是百度開源的一款第三方繪圖模塊,結合的python語言的簡易性和Echarts的強大繪圖特性,可以用python對其調(diào)用,輸出交互性好,精美乖巧且符合審美的圖表,下文我們就來學習pyecharts的Tab和Legend煩人布局布局
    2022-03-03
  • Python prettytable模塊應用詳解

    Python prettytable模塊應用詳解

    PrettyTable 是python中的一個第三方庫,可用來生成美觀的ASCII格式的表格,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-09-09
  • SymPy庫關于矩陣的基本操作和運算

    SymPy庫關于矩陣的基本操作和運算

    本文主要介紹了SymPy庫關于矩陣的基本操作和運算,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Pandas中DataFrame.head()函數(shù)的具體使用

    Pandas中DataFrame.head()函數(shù)的具體使用

    DataFrame.head()是Pandas庫中一個非常重要的函數(shù),用于返回DataFrame對象的前n行,本文主要介紹了Pandas中DataFrame.head()函數(shù)的具體使用,感興趣的可以了解一下
    2024-07-07

最新評論