1350 - 算法4-5:求子串位置的定位函数
时间限制 : 1 秒
内存限制 : 32 MB
在算法4-1中已经描述过一种定位子串的算法,但其依赖字符串的其他操作(使用了算法4-3描述的子串提取以及字符串比较)。
下面给出书中另一种相对独立的定位子串算法:

图:求子串位置的定位函数
书中的算法思想是这样的:分别利用计数指针i和j指示主串S和模式串T中当前正待比较的字符位置。算法的基本思想是:从主串S的第pos个字符起和模式的第一个字符比较之,若相等,则继续逐个比较后续字符,否则从主串的下一个字符起再重新和模式的字符比较之。依次类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则称匹配成功,函数值为和模式T中第一个字符相等的字符在主串中的序号,否则称匹配不成功,函数值为零。<br />
你的任务是将S中每次比较的字符输出来,并将匹配的序号输出。
题目输入
3组字符串,每组字符串占一行。每行包含由空格分隔的两个字符串,字符串仅由英文小写字母组成且长度不大于100。3组字符串,每组字符串占一行。每行包含由空格分隔的两个字符串,字符串仅由英文小写字母组成且长度不大于100。
题目输出
每组数据输出2行,第一行是S中每次比较的字符,第二行是后一个字符串在前一个字符串中的位置,如果不匹配,则输出0。
输入/输出样例
输入格式
string str thisisalongstring isa nosubstring subt
输出格式
str 1 thisisisa 5 nosubsubsttring 0
C语言解答
#include <stdio.h> int main(){ int i,j,k,n,flag; char str[100],sub[100]; // freopen("1.txt","r",stdin); while(scanf("%s %s",str,sub)!=EOF){ i=j=0; while (str[i]&&sub[j]) { printf("%c",str[i]); if (str[i]==sub[j]) { i++; j++; }else{ i=i-j+1; j=0; } } printf("\n"); if (!sub[j]) { printf("%d\n",i-j+1); }else{ printf("0\n"); } } // fclose(stdin); return 0; }
C++解答
#include <stdio.h> #include <string.h> #define MAXSTRLEN 100 typedef char SString[MAXSTRLEN+2]; void InputString(SString &str) { // 读取字符串 scanf("%s", str + 1); // 首先用scanf读取字符串 str[0] = strlen(str + 1); // 求出字符串的长度并保存在str[0]中 } int Index(SString S, SString T, int pos) { // 算法4.5 // 返回子串T在主串S中第pos个字符之后的位置。 // 若不存在,则函数值为0。 // 其中,T非空,1≤pos≤StrLength(S)。 int i = pos; int j = 1; while (i <= S[0] && j <= T[0]) { putchar(S[i]); // 只要添加这一句输出相应的字符即可 if (S[i] == T[j]) { // 继续比较后继字符 ++i; ++j; } else { // 指针后退重新开始匹配 i = i - j + 2; j = 1; } } if (j > T[0]){ return i - T[0]; } else return 0; } // Index int main(){ int i; SString S, T; // 定义存储两个字符串的变量 int index = 0; // 存储下标 for(i=0; i<3; i++){ InputString(S); // 读取两个字符串 InputString(T); index = Index(S, T, 1); // 定位子串 printf("\n%d\n", index);// 输出子串的下标 } return 0; }