String Shifting(今日頭條2017秋招真題)

題目鏈接

題目

我們規定對一個字符串的shift操作如下:

shift(“ABCD”, 0) = “ABCD”

shift(“ABCD”, 1) = “BCDA”

shift(“ABCD”, 2) = “CDAB”

換言之, 我們把最左側的N個字符剪切下來, 按序附加到了右側。

給定一個長度爲n的字符串,我們規定最多可以進行n次向左的循環shift操作。如果shift(string, x) = string (0<= x <n), 我們稱其爲一次匹配(match)。求在shift過程中出現匹配的次數。

輸入

輸入僅包括一個給定的字符串,只包含大小寫字符。

樣例輸入
byebyebye

輸出

輸出僅包括一行,即所求的匹配次數。

樣例輸出
3

時間限制
C/C++語言:1000MS其它語言:3000MS
內存限制
C/C++語言:65536KB其它語言:589824KB

完整代碼

暴力
運行結果:超時
ac40%

#include<bits/stdc++.h>
using namespace std;
string shift(string str, int n){    
	string res = ""; 
    res = str.substr(n, str.length() - n) + str.substr(0, n);  
    return res;
}
int main(){    
	string str = "";  
    cin >> str;   
   
    int res = 0;   
    for(int i = 0; i < str.length(); ++i){  
            if(str == shift(str, i))         
            ++res;   
    }    
    cout << res;     
    return 0;         
}

暴力優化

  • 如果數組中每個字符都相同,則直接輸出長度
  • 移動時,移動的長度是總長度的因數時才移動
  • 結果:ac:60%,總是顯示測試用例:zzzz時出錯,但程序在輸入:zzzzz,結果就是5啊!!!
#include<bits/stdc++.h>
using namespace std;
string shift(string str, int n){    
	string res = ""; 
    res = str.substr(n, str.length() - n) + str.substr(0, n);  
    return res;
}
int main(){    
	string str = "";  
    cin >> str;   
    int  j = 1;
    while(j < str.length()){
    	if(str[j] == str[j - 1])
        	++j;
        else
        	break;
    }
    if(j == str.length()){
    	cout << j;
        return 0;
    }
    int res = 0;   
    for(int i = 0; i < str.length(); ++i){  
            if(str.length() % (i + 1))
            	continue;
            if(str == shift(str, i))         
            ++res;   
    }    
    cout << res;     
    return 0;         
}

藉助KMP算法
KMP

  • 相當於求字符串的週期,最終長度除以週期就是結果
  • 利用s.length() - next[s.length()]就是週期

ac了

#include<bits/stdc++.h>

using namespace std;

int GetNext(string s){
	vector<int> next(s.length() + 1);//注意和KMP的區別
    next[0] = -1;
    int k = -1, j = 0;
    while(j < s.length()){
    	if(k == -1 || s[k] == s[j]){//KMP的next數組未優化形式
        ++k;
        ++j;
        	next[j] = k;
        }
        else{
        	k = next[k];
        }
    }
    return next[s.length()];
}

int main(){
	string s;
    cin >> s;
    if(s.length() == 0){
    	cout << 0;
        return 0;
    }
    
    int t = s.length() - ((GetNext(s)));
    if(s.length() % t == 0)
    	cout << s.length() / t ;
    else
    	cout << 1;
	return 0;
}


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