一道查找字符串的题,要求在给出的字符串中找出三段字符串a,b,c,其中a,b,c三个字符串有先后关系,且不能有交集,即原字符串中的一个字母不能被用两次。
这三个字符串拼成“anniversary”。
先后A了两次,第一次用<cstring>头文件中的strncpy和strstr函数。我再昨天也写了一篇随笔,简单介绍了这两个函数的使用方法,可移步至此。
为了确保先后关系,比如“versaryanni”,虽然可以找到“versary”和“anni”但顺序不对,所以不能,必须依次寻找,且第二次和第三次的寻找要再上一次找到的字符串末尾位置之后开始寻找,
只有到第三次也找到了,才能保证寻找到了符合题意的分割方法。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const char *word = "anniversary"; bool test(char *s) { int wordLen = strlen(word); int sLen = strlen(s); char s1[100 + 20], s2[100 + 20], s3[100 + 20]; char *r1, *r2, *r3; for( int i=1; i<wordLen; i++ ) { for( int j=i+1; j<wordLen; j++ ) { strncpy(s1, word, i); s1[i] = ‘\0‘; strncpy(s2, word+i, j - i); s2[j-i] = ‘\0‘; strncpy(s3, word + j, wordLen - j); s3[wordLen-j] = ‘\0‘; r1 = strstr(s, s1); if(r1 == NULL) continue; r2 = strstr(s + (r1 - s) + i, s2); if(r2 == NULL) continue; r3 = strstr(s + (r2 - s + j - i ), s3); if(r3 == NULL) continue; if( r3 >= (r2 + j - i) && r2 >= (r1+i) ) { return true; } } } return false; } int main() { int T; cin >> T; getchar(); while(T --) { char s[100 + 50]; gets(s); if( test(s) ) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }
第二次用了<string>头文件中string类的方法substr()和strstr()使用方法和上面的两个方法类似,当寻找不到符合的字符串时,返回string::npos;同样也是三次寻找,第二次和第三次的寻找是以前一次寻找到的情况下进行,且必须在前一次找到的字符串末尾开始查找。
#include <iostream> #include <cstring> #include <cstdio> #include <string> using namespace std; const string STR = "anniversary"; bool Found(string &str) { for(size_t i=1; i<STR.size()-1; i++) { for(size_t j=i+1; j<STR.size(); j++ ) { size_t pos = str.find(STR.substr(0, i)); if( pos == string::npos ) continue; pos = str.find(STR.substr(i, j-i), pos+i); if( pos == string::npos ) continue; pos = str.find(STR.substr(j, STR.size() - j), pos+j-i); if( pos == string::npos ) continue; return true; } } return false; } int main() { int T; cin >> T; while(T --) { string str; cin >> str; if(Found(str)) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }
时间: 2024-10-14 17:44:38