1. 场景描述
现有一个较长的字符串S,还有另外一个字符串T,要求计算出字符串S中从位置pos开始子串T完全匹配的位置,所谓完全匹配是指S的子串与字符串T的值相等。
2. 算法概述
朴素算法,就是最容易想到的,也就是从S[pos]开始,逐个字符比较,如果不匹配,在从S[pos+1]开始比较,直至匹配。这么讲比较抽象,也不太容易想到比较的情形,下面会进行详细的介绍。
3. 详细介绍
为了直观的解释这个算法,假设字符串S=abcabcdabcdeabcdef,字符串T=abcdef,pos=0。那么,这个问题就可以具体表述为,从字符串S的第0位开始,也就是S的整个串abcabcdabcdeabcdef,找出字符串T,即abcdef第一次出现的位置,这样就可以很容易想到这个场景。
算法的执行过程如下:
首先S[0]与T[0]比较,都是‘a’,相等;
下一位S[1]与T[1]比较,都是‘b’,相等,接着往下;
一直到S[3]与T[3],发现S[3]=a, T[3]=d,不相等,所以不匹配;
S从第2位开始再比较,发现S[1]=b, T[0]=a, 还是不等;
S再往后移一位……
如此循环,直到比较到T的最后一位和S中的某一位相等,说明匹配了(T的最后一位和S的某一位相等了,说明T之前的字符也都匹配,因为一旦不匹配,就从T[0]开始了,所以最后一位匹配的先决条件就是T之前的所有自否都匹配了,还是看图比较清晰一些)。
当然,这个算法中还是又一些可以优化的地方的。比如发现S的长度比T还小时,显而易见,这是不匹配的。当pos>S.length-T.length+1时,可以想象,也是不匹配的。
4.算法复杂度
假设S的长度是m,T的长度是n,暂不考虑pos,从字符串S的开头开始比较。
最好的情况是第一次就匹配了,需要比较的次数是n.
最坏的情况下,就是上面举的这种例子,需要把整个字符串都比较完,从下面的代码中就体现为把两层循环都跑了一遍。这时候,比较的次数就是t*(s-t+1).
所以这个算法的(最坏)时间复杂度就是o(t(s-t+1)),近似为o(n2).
5.代码
/*************************************************************************
* File Name : main.c
* Author : lijun
* Email : lijundut@foxmail.com
* Created Time : 2015-10-21 01:01:15
* Last Modified: --
* Description :
*************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_STRING_SIZE 128
int indexOfSubString(char S[], char T[], int position); //declear the function
int main()
{
char s[MAX_STRING_SIZE];
char t[MAX_STRING_SIZE];
int index, result;
printf("input a long string: ");
scanf("%s", s);
printf("input the substring you want to find: ");
scanf("%s", t);
printf("input the index: ");
scanf("%d", &index);
result = indexOfSubString(s, t, index);
if (result > 0){
printf("RESULT: %s\n", s+result);
}
return 0;
}
/***********************************************************************
* @author: lijun
* @date: 2015-10-21 22:57:11
* @description: This function is used to find the position where string
* T first occurs in string S after index of position.
*
**********************************************************************/
int indexOfSubString(char S[], char T[], int position)
{
int s = strlen(S);
int t = strlen(T);
if (s < t || position < 0){
printf("wrong parameter!\n");
return -1;
}
else{
int i = 0, j = 0;
int index = position;
while (index < s-t+1){
for (j = 0, i = index; j < t; j++){
if (S[i] == T[j]){
i++;
} else {
break;
}
}
if (j < t){ //not match
j =0;
index++;
} else { //matched
return index;
}
}
printf("not matched!\n");
return -1;
}
}