67 求字符串的起始位置
作者: SunCiHai时间限制: 10S章节: 字符串
问题描述 :
在程序设计中,对字符串的处理是经常遇到的一个问题。
例如,将字符串中所有的英文字母变成大写,或者将一个字符串与另一个字符串连接构成一个新的字符串。
由于此类的操作非常普遍,因此,在设计程序语言的时候,设计者就已经把这类操作的代码写好了,如果编程人员要使用这些代码,只需把该类代码的头文件包含到自己的程序中,编程人员就可以很简单的调用,这样使编程节省了不少时间。
明明是一名项目经理,他现在负责一种新的程序设计语言的开发,现在需要预先实现大量的和处理字符串有关的功能方法,以后这些方法会包含到程序设计语言中,方便程序语言使用者的开发。你是明明手下的一名软件工程师,明明分配给你一个任务,在两个字符串中,找到一个字符串在另一个字符串中的起始位置。 例如,有两个字符串,一个字符串s= “abc”,另一个字符串subs=“bc”,现在就要找出“bc”在“abc”中的其实位置,在这个例子中,“bc”的起始位置为2。
明明的问题可以归结为:输入两串字符串s和subs,求s中subs的起始位置。
输入说明 :
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据两行,每组测试数据的第一行为字符串s,s的长度小于100,每组测试数据的第二行为字符串subs,subs的长度小于100,s和subs中仅包含小写字母和数字。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明 :
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数m,即subs在s中的起始位置,如果在s中找不到subs这个子串,则m=0。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注:通常,显示屏为标准输出设备。
输入范例 :
abc
bc
aaa
bbb
输出范例 :
2
0
#include<stdio.h>
#include<string.h>
int next[50];
void GetNext(char* p, int next[])
{
int k = -1;
int j = 0;
int len=strlen(p);
next[0] = -1;
while (j < len - 1)
{
if (k == -1 || p[j] == p[k])
{
k++;
j++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int kmpSearch(char* s, char* p)
{
int i = 0;
int j = 0; // 初始化
int lenS=strlen(s);
int lenP=strlen(p);
while (i < lenS && j < lenP)
{
if (j == -1 || s[i] == p[j]) // 当前位置匹配成功
{
i++;
j++;
}
else // 当前位置匹配失败
{
j = next[j]; // i不回溯,j移动到next[j]位置,相当于模板串右移j - next[j]
}
}
if (j == lenP) // 匹配成功
return i -j+1;
else
return 0;
}
int main(){
char s[100],sub[100];
int position;
while(scanf("%s",s)!=EOF){
scanf("%s",sub);
GetNext(sub,next);
position=kmpSearch(s,sub);
if(position==0){
printf("0\n");
}else{
printf("%d\n",position);
}
}
return 0;
}