最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python最長(zhǎng)回文串算法

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

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

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

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

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

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

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

由于對(duì)稱性,可得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右邊存在未遍歷的字符,因此在此基礎(chǔ)上,繼續(xù)向兩邊擴(kuò)展,直到找到最長(zhǎng)的回文子串。

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

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

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

python代碼:

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

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

暴力枚舉:49.719844s

中心枚舉:0.334019s

manacher:0.008000s

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python在線和離線安裝第三方庫(kù)的方法

    Python在線和離線安裝第三方庫(kù)的方法

    這篇文章主要介紹了Python在線和離線安裝第三方庫(kù)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • python中的extend功能及用法

    python中的extend功能及用法

    Python中的extend()方法用于在列表末尾一次性追加另一個(gè)列表中的多個(gè)值,這篇文章主要介紹了python中的extend功能及用法,需要的朋友可以參考下
    2023-07-07
  • python做反被爬保護(hù)的方法

    python做反被爬保護(hù)的方法

    在本文里小編給大家整理了一篇關(guān)于python做反被爬保護(hù)的方法的方法,由此需求的同學(xué)參考學(xué)習(xí)下。
    2019-07-07
  • Python繪制分類圖的方法

    Python繪制分類圖的方法

    這篇文章主要為大家詳細(xì)介紹了Python繪制分類圖的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Python實(shí)現(xiàn)批量提取word文件中文本框內(nèi)容

    Python實(shí)現(xiàn)批量提取word文件中文本框內(nèi)容

    在日常的辦公中,有時(shí)需要提取多個(gè)word文件中的文字框的內(nèi)容,這篇文章主要為大家介紹了三種常見的方法來提取文本框的內(nèi)容,希望對(duì)大家有一定的幫助
    2024-02-02
  • Python中return用法案例詳解

    Python中return用法案例詳解

    這篇文章主要介紹了Python中return用法案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Python 性能優(yōu)化技巧總結(jié)

    Python 性能優(yōu)化技巧總結(jié)

    代碼優(yōu)化能夠讓程序運(yùn)行更快,它是在不改變程序運(yùn)行結(jié)果的情況下使得程序的運(yùn)行效率更高,根據(jù) 80/20 原則,實(shí)現(xiàn)程序的重構(gòu)、優(yōu)化、擴(kuò)展以及文檔相關(guān)的事情通常需要消耗 80% 的工作量。優(yōu)化通常包含兩方面的內(nèi)容:減小代碼的體積,提高代碼的運(yùn)行效率。
    2016-11-11
  • 基于Python實(shí)現(xiàn)自制CV剪貼板功能

    基于Python實(shí)現(xiàn)自制CV剪貼板功能

    云桌面的win10不能調(diào)出剪貼板,對(duì)于CV工程師來說十分不方便,所以這篇文章主要介紹了如何使用Python實(shí)現(xiàn)一個(gè)CV剪貼板,提升常用語(yǔ)句的復(fù)制粘貼效率,感興趣的可以了解下
    2024-02-02
  • python實(shí)現(xiàn)自動(dòng)打卡小程序

    python實(shí)現(xiàn)自動(dòng)打卡小程序

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)打卡小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • Python開發(fā)裝包八種方法詳解

    Python開發(fā)裝包八種方法詳解

    這篇文章主要為大家介紹了Python開發(fā)中裝包的八種方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10

最新評(píng)論

安吉县| 永仁县| 保康县| 江源县| 玉环县| 扎赉特旗| 安福县| 颍上县| 抚顺县| 金秀| 杭锦后旗| 玉田县| 安达市| 渭源县| 洛南县| 班玛县| 永济市| 桃园县| 原阳县| 南平市| 巴彦淖尔市| 长武县| 栖霞市| 西和县| 大悟县| 邳州市| 镇巴县| 浦县| 华容县| 枝江市| 哈尔滨市| 剑河县| 辽源市| 夏邑县| 丹阳市| 洪湖市| 康乐县| 隆林| 瑞安市| 信阳市| 嘉义县|