/*
1、使用stringstream分割字符串
2、KMP字符匹配算法
3、Kmp字符串匹配算法改进版
4、KMP算法之二
*/
/////////////////////////////////////////////////////////////////////////////
//使用stringstream分割字符串,可以逐个输出
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string s;
s = "stringstream provides an interface to manipulate strings as if they were input/output streams";
string val;
stringstream ss;
ss << s;
cout << "output:" << endl;
for (int i = 0; i < 6; i++) {
ss >> val;
cout << val << endl;
}
system("PAUSE");
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////
//KMP字符匹配算法
/* kmp算法是一种改进的字符串匹配算法,KMP算法的关键是根据给定的模式串T,定义一个next函数。
next函数包含了模式串本身局部匹配的信息。 */
//KmpAlgorithm.h
#ifndef KMPALGORITHM_H
#define KMPALGORITHM_H
void Get_next(char *T,int *next);
int Index_Kmp(char *s,char *T,int pos);
#endif //KMPALGORITHM_H
/////////////////////////////////
//method.cpp
#include "stdafx.h"
#include "KmpAlgorithm.h"
#include <string.h>
void Get_next(char *T,int *next) //求模式串T的next函数
{
int i,j;
i = 0;
j = -1;
next[0] = -1;
while(T[i] != '\0') //T串没有结束就循环
{
if(j == -1 || T[j] == T[i]) //T[i]表示后缀的单个字符,T[j]表示前缀的单个字符
{
++i;
++j;
next[i] = j;
}
else
j = next[j]; //若字符不相同,则回溯
}
}
int Index_Kmp(char *s,char *t,int pos) //pos不为零,则是从主串的第pos个字符开始匹配
{
int i = pos - 1; //数组下标是从零开始的
int j = 0;
int next[255];
Get_next(t,next);
while(s[i] != '\0' && t[j] != '\0')
{
if(j == -1 || s[i] == t[j]) //两个字符相等则继续比较,j == -1是在回溯时产生的,因为next[0]
{ //回溯到j == -1,不在字符数组内
++i;
++j;
}
else
j = next[j]; //不相等则回溯
}
if(t[j] == '\0') //如果相等返回在主串中的位置
return i - strlen(t) + 1;
else
return -1;
}
//////////////////////////////////
//main.cpp
#include "stdafx.h"
#include "KmpAlgorithm.h"
#include <stdio.h>
#include <string.h>
int main()
{
char s[255],t[255];
int pos = 0;
int position = 0;
memset(s,0,sizeof(char)*255);
memset(t,0,sizeof(char)*255);
printf("请输入主串的内容:\n");
scanf("%s",s);
printf("请输入子串的内容:\n");
scanf("%s",t);
printf("请输入从主串的第几个字符开始匹配:\n");
scanf("%d",&pos);
position = Index_Kmp(s,t,pos);
if(position == -1)
printf("子串没有在主串中出现");
else
printf("子串在主串的第%d个位置出现\n",position);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
//Kmp字符串匹配算法改进版
//KmpAlgorithm.h 和 main.cpp同上KMP算法
//menthod.cpp
#include "stdafx.h"
#include "LinkList.h"
#include <string.h>
void Get_Next(char *T,int *next)
{
int i = 0;
int j = -1;
next[0] = -1;
while(T[i] != '\0')
{
if(j == -1 || T[j] == T[i]) //T[j]为前缀的单个字符,T[i]为后缀的单个字符
{ //T[-1]不存在所以在回溯到j == -1时直接++j
++j;
++i;
if(T[j] != T[i]) //当前字符串与前缀字符不同
next[i] = j; //j为next在i位置的值
else
next[i] = next[j]; // 相同则将前缀字符的next值赋给next在i位置的值
}
else
j = next[j]; //如果不相等则回溯
}
}
int Index_Kmp(char *s,char *t,int pos) //Kmp字符串匹配函数
{ //pos不为1,则从主串s的第pos个字符开始与t串匹配
int i = pos - 1; //数组的下标从零开始
int j = 0;
int next[255];
Get_Next(t,next);
while(s[i] != '\0' && t[j] != '\0') //如果字符串未结束则继续循环
{
if(s[i] == t[j])
{
++i;
++j;
}
else
{
j = next[j]; //不相等则回溯
if(j == -1)
{
++j;
++i;
}
}
}
if(t[j] == '\0')
return i - strlen(t) + 1;
else
return -1;
}
/////////////////////////////////////////////////////////////////////////////////////////
//KMP算法之二
#include<stdio.h>
#include<string.h>
int kmp_index(const char *s, const char *p,int *next) {
int n = strlen(s);
int m = strlen(p);
int i = 0, j = 0;
while( i<n && j < m) {
if((j== -1) || (s[i] == p[j])) {
i++;
j++;
}
else {
j = next[j];
}
}
if( j == m)
return (i - j);
else
return -1;
}
void get_next(const char *p, int *next) {
int m = strlen(p);
next[0] = -1;
int i = 1, j = 0, k = 0;
while( i < m) {
k = i - 1;
j = next[k];
label:
if((j == -1) || (p[k] == p[j])) {
j++;
next[i] = j;
i++;
}
else {
j = next[j];
goto label;
}
}
}
void main()
{
char p[] = "abcaabcacd";
char s[] = "abcac";
int next[sizeof(s)-1];
get_next(s,next);
for(int i = 0; i<sizeof(s)-1; ++i)
printf("%d,",next[i]);
printf("\n%d\n",kmp_index(p,s,next));
}
////////////////////////////////////////////////////////////////////////////////////////
//sunday算法
#include <iostream>
using namespace std;
void SUNDAY(char *text, char *patt)
{
size_t temp[256];
size_t *shift = temp;
size_t i, patt_size = strlen(patt), text_size = strlen(text);
cout << "size : " << patt_size << endl;
for( i=0; i < 256; i++ )
*(shift+i) = patt_size+1;
for( i=0; i < patt_size; i++ )
*(shift+(unsigned char)(*(patt+i))) = patt_size-i;
//shift['s']=6 步,shitf['e']=5 以此类推
size_t limit = text_size-patt_size+1;
for( i=0; i < limit; i += shift[ text[i+patt_size] ] )
{
if( text[i] == *patt )
{
char *match_text = text+i+1;
size_t match_size = 1;
do
{// 输出所有匹配的位置
if( match_size == patt_size )
cout << "the NO. is " << i << endl;
}
while( (*match_text++) == patt[match_size++] );
}
}
cout << endl;
}
int main(void)
{
char text[] = {"abcdebadcbadk"};
char patt[] = {"bad"};
SUNDAY(text, patt);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////
//BM算法
#include <stdio.h>
#include <string.h>
/**
* 字符串模式匹配BF算法
*/
int Find(const char *pstr, const char *psubstr, int start)
{
int lenstr = strlen(pstr);
int lensbustr = strlen(psubstr);
int i=start;
int j=0;
while(i<lenstr && j < lensbustr)
{
if(pstr[i] == psubstr [j])
{ // 匹配
i++;
j++;
}
else
{
i = i-j+1; // ???? 为什么
j=0;
}
if(j>=lensbustr)
{ // 匹配成功
return i - lensbustr;
}
}
return -1;
}
int main(void)
{
char pstr[] = {"abcdefvf"};
char psubstr[] = {"cd"};
printf("%d", Find(pstr, psubstr, 0));
return 0;
}
//////////////////////////////////////////////////////////////////////////////////