[编程题] 循环单词
时间限制:1秒
空间限制:32768K
如果一个单词通过循环右移获得的单词,我们称这些单词都为一种循环单词。 例如:picture 和 turepic 就是属于同一种循环单词。 现在给出n个单词,需要统计这个n个单词中有多少种循环单词。
输入描述:
输入包括n+1行:
第一行为单词个数n(1 ≤ n ≤ 50)
接下来的n行,每行一个单词word[i],长度length(1 ≤ length ≤ 50)。由小写字母构成
输出描述:
输出循环单词的种数
输入例子:
5 picture turepic icturep word ordw
输出例子:
2
解题思路:本题参考自剑指offer左旋转字符串,用set存储每类循环单词的总情况,对于每个给定单词,在set中找是否有,有的话就说明为一类,进行下一个单词的查找,如果没有,找到这个单词的所有循环单词,存入set中,并且count++
1 #include <iostream> 2 #include <vector> 3 #include <set> 4 using namespace std; 5 void Reverse(char *pStart, char *pEnd) 6 { 7 if(pStart == NULL || pEnd == NULL) 8 return; 9 while(pStart < pEnd) 10 { 11 char tmp = *pStart; 12 *pStart = *pEnd; 13 *pEnd = tmp; 14 pStart++; 15 pEnd--; 16 } 17 } 18 string LeftRotateString(string str, int n) { 19 if(!str.empty()) 20 { 21 int length = str.size(); 22 if(length > 0 && n>0 && n < length) 23 { 24 char *pFirstStart = &str[0]; 25 char *pFirstEnd = &str[n-1]; 26 char *pSecondStart = &str[n]; 27 char *pSecondEnd = &str[length-1]; 28 //翻转前n个 29 Reverse(pFirstStart,pFirstEnd); 30 //翻转第n+1个到最后 31 Reverse(pSecondStart,pSecondEnd); 32 //翻转整个字符串 33 Reverse(pFirstStart,pSecondEnd); 34 } 35 } 36 return str; 37 } 38 int main() 39 { 40 int n; 41 while(cin>>n) 42 { 43 string s[50]; 44 for(int i=0;i<n;i++) 45 { 46 cin>>s[i]; 47 } 48 set<string> t; 49 set<string>::iterator it; 50 string tmp; 51 int count = 0; 52 for(int i=0;i<n;i++) 53 { 54 it = t.find(s[i]); 55 if(it == t.end())//没找到 56 { 57 count++; 58 for(int j = 0;j<s[i].size();j++) 59 { 60 tmp = LeftRotateString(s[i],j); 61 t.insert(tmp); 62 } 63 } 64 } 65 cout<<count<<endl; 66 } 67 return 0; 68 }
网上借鉴思路:把要测试的单词后再重复下这个单词,如:picture ,变成 picturepicture
然后判断其他要测试的单词是不是这个串的子串(长度要先相等)
1 #include <string> 2 #include <iostream> 3 #include <vector> 4 using namespace std; 5 int main() 6 { 7 8 int n,num=0; 9 vector<string> twords; 10 vector<bool> checks;//判断是否已属于某种循环单词 11 cin>>n; 12 for (int i = 0; i < n; i++) 13 { 14 string t_w; 15 cin >> t_w; 16 twords.push_back(t_w); 17 checks.push_back(false); 18 } 19 for (int j = 0; j < n; j++) 20 { 21 if (!checks[j]) 22 { 23 string tt; 24 tt = twords[j] + twords[j]; 25 for (int k = j + 1; k < n; k++) 26 { 27 if (!checks[k]) 28 { 29 if (tt.find(twords[k]) !=string::npos&&twords[k].length() == twords[j].length()) 30 { 31 checks[k] = true; 32 } 33 } 34 } 35 num++; 36 } 37 } 38 cout << num << endl; 39 return 0; 40 }