chenlifeng 发表于 2021-12-19 23:29:25

字符串移位包含问题(来自openjudge的noi)

描述
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。

给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串。

输入
一行,包含两个字符串,中间由单个空格隔开。字符串只包含字母和数字,长度不超过30。
输出
如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出true,否则输出false。
样例输入
AABCD CDAA
样例输出
true


{:9_221:}
不知道为什么我一直过不了它的测试集,救救孩子。。
我的代码:
// noi 1.7 19 字符串移位包含问题
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(void) {
        char s1 = {}, s2 = {};
        int i = 0, j = 0, found = 0, len1 = 0, len2 = 0;
        scanf("%s", s1);                               
        scanf("%s", s2);
        len1 = strlen(s1);
        len2 = strlen(s2);
       
        // part_1 : s2 是否为 s1 的子串
        for(i = 0 ; s1 != '\0' ; ++i) {
                found = 0;
                for(j = 0 ; s2 != '\0' ; ++j) {
                        if(s1[(i + j) < len1 ? (i + j) : (i + j - len1 )] != s2) {
                                found = 1;
                                break;
                        }
                }
                if( ! found ) {
                        printf("true");
                        return 0;
                }
        }
       
        // part_2 : s1 是否为 s2 的子串
        for(i = 0 ; s2 != '\0' ; ++i) {
                found = 0;
                for(j = 0; s1 != '\0' ; ++j) {
                        if(s2[(i + j) < len2 ? (i + j) : ( i + j - len2 )] != s1) {
                                found = 1;
                                break;
                        }
                }
                if( ! found ) {
                        printf("true");
                        return 0;
                }
        }
       
        printf("false");
        return 0;
}

jhq999 发表于 2021-12-20 06:45:45

本帖最后由 jhq999 于 2021-12-20 07:52 编辑

刚开始没看出毛病,除了习惯不一样
//****应该是缺这个条件语句&&len1>=len2,会出现str1="ABBCA",str2="ABBCAABBCAABBCA"的情况,if(s1[(i + j) < len1 ? (i + j) : (i + j - len1 )] != s2) 越界****
for(i = 0 ; s1 != '\0'&&len1>=len2 ; i++) {//比如这个i++和++i的效果一样,因为只是自增运算,不涉及其他运算。所以先加后加没有影响。
//****应该是缺这个条件语句&&len1>=len2,会出现str1="ABBCA",str2="ABBCAA"的情况****
                found = 0;
                for(j = 0 ; s2 != '\0' ; ++j) {
                        if(s1[(i + j) %len1] != s2) {//比如这个,效果也一样,当然len2>=2*len1楼主那个就越界了
                              found = 1;
                              break;
                        }
                }
                if( ! found ) {
                        printf("str2 是 str1的子串");//这里没有明确到底谁是谁的子串,但是样例也没表示错误
                        return 0;
                }
      }

傻眼貓咪 发表于 2021-12-20 09:22:26

本帖最后由 傻眼貓咪 于 2021-12-20 09:41 编辑

#include <stdio.h>
#include <string.h>

int isSubString(char str1[], char str2[], int a, int b){
        int flag;
        if(b > a) return 0;
        else{
                for(int i = 0; i < a; i++){
                        flag = 1;
                        for(int j = i, k = 0; j < i+b; j++, k++){ // 切片,长度一致
                                if(str1 != str2){ // 判断两个字符串是否一样
                                        flag = 0;
                                        break;
                                }
                        }
                        if(flag) return 1;
                }
        }
        return 0;
}

int main(){
        char str1, str2;
        int a, b, x, y;
        scanf("%s%s", str1, str2);
        a = strlen(str1);
        b = strlen(str2);
        x = isSubString(str1, str2, a, b);
        y = isSubString(str2, str1, b, a);
        printf(x || y ? "true" : "false");
        return 0;
}

chenlifeng 发表于 2021-12-20 16:15:44

jhq999 发表于 2021-12-20 06:45
刚开始没看出毛病,除了习惯不一样
//****应该是缺这个条件语句&&len1>=len2,会出现str1="ABBCA",str2="A ...

输入的字符串长度最大为30,我定义的长度为35,应该不会出现越界啊,字符数组的后面是接了终止符'\0'的,上面举的例子第三轮比较的开始就会是str1的’\0' 和 str2的 'A' 进行比较,比较到这里两个字符就应该会不相等跳出当前循环啊{:9_241:}

jhq999 发表于 2021-12-20 17:15:36

本帖最后由 jhq999 于 2021-12-20 17:24 编辑

chenlifeng 发表于 2021-12-20 16:15
输入的字符串长度最大为30,我定义的长度为35,应该不会出现越界啊,字符数组的后面是接了终止符'\0'的, ...
在第二层循环越界,第二层循环没有s1!='\0'的条件

chenlifeng 发表于 2021-12-20 18:36:25

本帖最后由 chenlifeng 于 2021-12-20 18:38 编辑

jhq999 发表于 2021-12-20 17:15
在第二层循环越界,第二层循环没有的条件

               for(j = 0 ; s2 != '\0' ; ++j) {
                        if(s1[(i + j) < len1 ? (i + j) : (i + j - len1 )] != s2) {
                              found = 1;
                              break;
                        }
                }
但是在第二层循环中当读到了s1 [ i ] = ‘\0‘的时候,因为已经控制了s2 [ j ] !=’\0', 则会有s1 [ i ] != s2 [ j ], 于是执行if语句块中的break, 不就不会继续第二层循环造成数组的越界了吗?{:9_241:}

jhq999 发表于 2021-12-20 18:45:55

chenlifeng 发表于 2021-12-20 18:36
for(j = 0 ; s2 != '\0' ; ++j) {
                        if(s1[(i + j) < len ...

的确
页: [1]
查看完整版本: 字符串移位包含问题(来自openjudge的noi)