筆試面試之最大對稱字串

2021-09-30 04:11:38 字數 3856 閱讀 9668

字串

2010-07-31 12:51:20

閱讀147

字型大小:大中小

題目:輸入乙個字串,輸出該字串中對稱的子字串的最大長度。比如輸入字串「

google

」,由於該字串裡最長的對稱子字串是「

goog

」,因此輸出

4。分析:可能很多人都寫過判斷乙個字串是不是對稱的函式,這個題目可以看成是該函式的加強版。

要判斷乙個字串是不是對稱的,不是一件很難的事情。我們可以先得到字串首尾兩個字元,判斷是不是相等。如果不相等,那該字串肯定不是對稱的。否則我們接著判斷裡面的兩個字元是不是相等,以此類推。基於這個思路,我們不難寫出如下**:

// whether a string between pbegin and pend is symmetrical?

bool issymmetrical(char* pbegin, char* pend)

if(pbegin == null || pend == null || pbegin > pend)

return false;

while(pbegin < pend)

if(*pbegin != *pend)

return false;

pbegin++;

pend --;

return true;

要判斷乙個字串

pstring

是不是對稱的,我們只需要呼叫

issymmetrical(pstring, &pstring[strlen(pstring) – 1])

就可以了。

現在我們試著來得到對稱子字串的最大長度。最直觀的做法就是得到輸入字串的所有子字串,並逐個判斷是不是對稱的。如果乙個子字串是對稱的,我們就得到它的長度。這樣經過比較,就能得到最長的對稱子字串的長度了。於是,我們可以寫出如下**:

// get the longest length of its all symmetrical substrings

// time needed is o(t^3)

int getlongestsymmetricallength_1(char* pstring)

if(pstring == null)

return 0;

int symmeticallength = 1;

char* pfirst = pstring;

int length = strlen(pstring);

while(pfirst < &pstring[length - 1])

char* plast = pfirst + 1;

while(plast <= &pstring[length - 1])

if(issymmetrical(pfirst, plast))

int newlength = plast - pfirst + 1;

if(newlength > symmeticallength)

symmeticallength = newlength;                         

plast++;

pfirst++;

return symmeticallength;

我們來分析一下上述方法的時間效率。由於我們需要兩重

while

迴圈,每重迴圈需要o(

n)的時間。另外,我們在迴圈中呼叫了

issymmetrical

,每次呼叫也需要o(

n)的時間。因此整個函式的時間效率是o(

n3)。通常o

(n3)不會是乙個高效的演算法。如果我們仔細分析上述方法的比較過程,我們就能發現其中有很多重複的比較。假設我們需要判斷乙個子字串具有

aaa的形式(a是

aaa的子字串,可能含有多個字元)。我們先把

pfirst

指向最前面的字元a,把

plast

指向最後面的字元

a,由於兩個字元相同,我們在

issymtical

函式內部向後移動

pfirst

,向前移動

plast

,以判斷

a是不是對稱的。接下來若干步驟之後,由於

a也是輸入字串的乙個子字串,我們需要再一次判斷它是不是對稱的。也就是說,我們重複多次地在判斷

a是不是對稱的。

造成上述重複比較的根源在於

issymmetrical

的比較是從外向裡進行的。在判斷

aaa是不是對稱的時候,我們不知道

a是不是對稱的,因此需要花費o(

n)的時間來判斷。下次我們判斷

a是不是對稱的時候,我們仍然需要o(

n)的時間。

如果我們換一種思路,我們從裡向外來判斷。也就是我們先判斷子字串

a是不是對稱的。如果

a不是對稱的,那麼向該子字串兩端各延長乙個字元得到的字串肯定不是對稱的。如果

a對稱,那麼我們只需要判斷

a兩端延長的乙個字元是不是相等的,如果相等,則延長後的字串是對稱的。因此在知道

a是否對稱之後,只需要o(

1)的時間就能知道

aaa是不是對稱的。

我們可以根據從裡向外比較的思路寫出如下**:

// get the longest length of its all symmetrical substrings

// time needed is o(t^2)

int getlongestsymmetricallength_2(char* pstring)

if(pstring == null)

return 0;

int symmeticallength = 1;

char* pchar = pstring;

while(*pchar != '/0')

// substrings with odd length

char* pfirst = pchar - 1;

char* plast = pchar + 1;

while(pfirst >= pstring && *plast != '/0' && *pfirst == *plast)

pfirst--;

plast++;

int newlength = plast - pfirst - 1;

if(newlength > symmeticallength)

symmeticallength = newlength;

// substrings with even length

pfirst = pchar;

plast = pchar + 1;

while(pfirst >= pstring && *plast != '/0' && *pfirst == *plast)

pfirst--;

plast++;

newlength = plast - pfirst - 1;

if(newlength > symmeticallength)

symmeticallength = newlength;

pchar++;

return symmeticallength;

由於子字串的長度可能是奇數也可能是偶數。長度是奇數的字串是從只有乙個字元的中心向兩端延長出來,而長度為偶數的字串是從乙個有兩個字元的中心向兩端延長出來。因此我們的**要把這種情況都考慮進去。

在上述**中,我們從字串的每個字串兩端開始延長,如果當前的子字串是對稱的,再判斷延長之後的字串是不是對稱的。由於總共有o(

n)個字元,每個字元可能延長o(

n)次,每次延長時只需要o(

1)就能判斷出是不是對稱的,因此整個函式的時間效率是o(

n2)。

對稱子字串的最大長度

題目 輸入乙個字串,輸出該字串中對稱的子字串的最大長度。比如輸入字串 google 由於該字串裡最長的對稱子字串是 goog 因此輸出4。方法 1.值得注意的是,回文的2種形式,aba,abba 1.對於aba的形式,從字串中的每乙個位置i,像兩邊擴充套件一位如果a i 1 a i 1 那麼繼續擴充...

對稱子字串的最大長度

題目 輸入乙個字串,輸出該字串中對稱的子字串的最大長度。比如輸入字串 google 由於該字串裡最長的對稱子字串是 goog 因此輸出4。方法 1.值得注意的是,回文的2種形式,aba,abba 1.對於aba的形式,從字串中的每乙個位置i,像兩邊擴充套件一位如果a i 1 a i 1 那麼繼續擴充...

C 對稱字串的最大長度

題目 輸入乙個字串,輸出該字串中對稱的子字串的最大長度。比如輸入字串 google 由於該字串裡最長的對稱子字串是 goog 因此輸出4。求對稱字串最大長度.cpp 定義控制台應用程式的入口點。include stdafx.h include int getmaxlen char str else ...