字符串(1)

字符串面試題的特點
廣泛性
1.字符串可以看做字符類型的數組,與數組排序、查找、調整有關
2.很多其它類型面試題可看作自字符串類型的面試題。

需掌握的概念
1.迴文
題目(1)
判斷一個字符串是否爲迴文
解法:遞歸
遞歸思路:一個迴文字符串其中內部也是迴文。所以,我們只需要以去掉兩端的字符的形式一層層檢查,每一次的檢查都去掉了兩個字符,這樣就達到了縮少問題規模的目的。新問題與原問題有着相同的形式當去掉兩端字符後的字符串,其產生的新問題同樣是檢查這個字符串是否迴文。

遞歸的結束需要簡單情景
①. 字符串長度可能會奇數或偶數:
如果字符串長度是奇數,字符串會剩下最中間那位字符,但其不影響迴文。當檢查到長度爲1的時候即代表此字符串是迴文
如果字符串長度是偶數,當兩端的字符串兩兩比較檢查後不會剩下字符。即檢查到長度爲0的時候即代表此字符串是迴文
②. 如果檢查到兩端兩個字符不相同。則說明此字符串不是迴文,直接返回0,不需要繼續檢查

#include<iostream>
#include<string>
using namespace std;
int huiwen(int low,int high,char str[],int length){
    if(length==0||length==1){
      return 1;
    }
    if(str[low]!=str[high]){
      return 0;
    }
    huiwen(low+1,high-1,str,length-2);
}
int main(){
    char str[20];
    cin>>str;
    int length=strlen(str);
    int a=huiwen(0,length-1,str,length);    
    if(a==1){
        cout<<"迴文!";
    }
    else
        cout<<"不迴文!";
}

題目(2)
要求你,給你一個字符串,可在任意位置添加字符,最少再添加幾個字符,可以使這個字符串成爲迴文字符串。
輸入
第一行給出整數N(0

#include<iostream>
#include<string>
using namespace std;
int huiwen(int low,int high,char str[],int length){
    if(length!=0&&length!=1){
        if(str[low]==str[high]){
            return huiwen(low+1,high-1,str,length-2);
        }
        else 
            return min(huiwen(low+1,high,str,length-1),huiwen(low,high-1,str,length-1))+1;
    }
    return 0;
}
int main(){
    char str[20];
    cin>>str;
    int res=0;
    int length=strlen(str);
    int a=huiwen(0,length-1,str,length);    
    cout<<a;
}  

第二種思路:(在我看來,該代碼用到了動態規劃,我還不太懂
其實就是最長公共子序列的變種,將原序列str倒置後得到tmp。求出最長公共子序列的長度,則這些就是迴文字串,剩下的就是沒有匹配的字符的個數。用總長度減去最長公共子序列的長度,就得到需要添加的字符數量。
代碼如下:

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<string>  
#include<algorithm>  
using namespace std;  
#define MAX 1010  
int res[MAX][MAX];  

int main()  
{  
    int ncase, i, j;  
    scanf("%d", &ncase);  
    while(ncase--)  
    {  
        string str, tmp;  
        cin>>str;  
        tmp = str;  
        reverse(tmp.begin(), tmp.end()); //倒置  
        for(i = 0; i < str.size(); ++i)  
        {  
            for(j = 0; j < tmp.size(); ++j) //res[i][j]爲最長公共子序列的長度  
            {  
                if(str[i] != tmp[j])  
                    res[i + 1][j + 1] = max(res[i + 1][j], res[i][j + 1]);  
                else  
                    res[i + 1][j + 1] = res[i][j] + 1;  
            }  
        }  
        printf("%d\n", str.size() - res[i][j]); //總長度減去res[i][j]就是不匹配字符個數  
    }  
}

2.子串(連續)
3.子序列(不連續)
4.前綴樹(Trie樹)
參考了博客trie樹(前綴樹)

#include<iostream>
#include<string>
using namespace std;
#define  MAX    26 //字符集大小

struct TrieNode{  
    bool isStr; //標識是否是一個完整的字符串  
    struct TrieNode *next[MAX];  
}; 

/*插入*/  
void Insert(TrieNode *root , char *word)  
{  
    TrieNode *location=root;
    while(*word){
        if(location->next[*word-'a']==NULL){
            TrieNode *newNode=new TrieNode();
            newNode->isStr=false;
            memset(newNode->next,NULL,sizeof(newNode->next));//初始化
            location->next[*word-'a']=newNode;  
        }
    location=location->next[*word-'a'];//location指向字符串在前綴樹中下一個位置
    word++; //當前字符在字符串中位置
    }

    //字符串已經全部添加到前綴樹
    //標識前綴樹到該節點位置爲完整字符串
    location->isStr=true;
}  

//查找  
bool Search(TrieNode *root , char *word)  
{  
    TrieNode *location=root; 
    while(*word&&location!=NULL){
      location=location->next[*word-'a'];
      word++;
    }
    return(location!=NULL&&location->isStr );
}

void Delete(TrieNode *location){
    for(int i=0;i<MAX;i++){
        if(location->next[i]!=NULL){
            Delete(location->next[i]);
        }
    }
    delete location;    
}
int main(){
    //初始化前綴樹的根節點,注意這裏結構體指針的初始化
    TrieNode *root=new TrieNode();
    root->isStr =false;

    //前綴樹中每一個節點的下一個節點,分配空間,注意memset的使用
    memset(root->next,NULL,sizeof(root->next));

    Insert(root,"a");
    Insert(root,"bcd");
    Insert(root,"xyz");
    Insert(root,"abcdef");

    if(Search(root,"bcd"))
       cout<<"exist"<<endl;
    else
        cout<<"no exist"<<endl;

    Delete(root);
}

5.後綴樹和後綴數組
6.匹配
7.字典序

需掌握的操作
1.與數組有關的操作:增刪改查
2.字符的替換
3.字符串的旋轉

字符串題目常見類型
規則判斷
1.判斷字符串是否符合整數規則
2.判斷字符串是否符合浮點數規則
3.判斷字符串是否符合迴文字符串規則
等等

數字運算
用字符串實現大整數
與大整數相關的加減乘除操作,需要模擬筆算的過程。

與數組操作有關的類型(重點)
1.數組有關的調整、排序等操作需要掌握
2.快速排序的劃分過程,需要掌握和改寫。

字符計數
1.哈希表
2.固定長度的數組(代替哈希表)
3.常見問題:滑動窗口問題,尋找無重複字符子串問題,計算變位詞等問題。

動態規劃問題
1.最長公共子串
2.最長公共子序列
3.最長迴文子串
4.最長迴文子序列

搜索類型
1.寬度優先搜索
2.深度優先搜索

高級算法與數據結構解決的問題
1.Manacher算法解決最長迴文子串問題(馬拉車算法)
2.KMP算法解決字符串匹配問題
3.前綴樹結構
4.後綴樹與後綴數組
5.通常面試很少出現。

發佈了48 篇原創文章 · 獲贊 2 · 訪問量 9808
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章