数据结构(c++)字符串 模式匹配算法问题,对高手来说只要写一点点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(c++)字符串 模式匹配算法问题,对高手来说只要写一点点相关的知识,希望对你有一定的参考价值。

1、在串堆存储表示的基础上串匹配的BF算法实现
前置条件:串已存在
输入:输入子串对象ss,输入从主串第i位开始查找子串
动作:寻找子串在在主串第i位后子串第一次出现的位置。
输出:返回匹配子串的位置,否则不匹配则返回-1值。
后置条件:无

核心部分参考:
template <class T1>
int string<T1>::index(const string<T1> &T,int pos)
//在S串中从pos开始查找一个与串T相同的子串
if (pos<1||pos>length) throw "pos不合法!";
int i=pos,j=1;
while (i<=length &&j<=T.length)

if (s[i]==T.s[j])

i++;
j++;

else

i=i-j+2;
j=1;//回溯


if (j>T.length) return (i-j+1);
else return -1;


2、在串堆存储表示的基础上串匹配的KMP算法实现
前置条件:串已存在
输入:输入子串对象ss,输入从主串第i位开始查找子串
动作:寻找子串在在主串第i位后子串第一次出现的位置。
输出:返回匹配子串的位置,否则不匹配则返回-1值。
后置条件:无

核心部分参考:
template <class T1>
void string<T1>::getnext(const string<T1> &T,int *next)

int i=0,j=-1;
next[i]=-1;
while(i<T.length)

if(j==-1||T.s[i]==T.s[j])
//当ti=tj时,i和j分别加1,同时计算next[j],再继续比较;
//当j==-1时,则使si+1与t0比较,同上。

i++;
j++;
next[i]=j;//给数组next的元素赋值

else j=next[j];//不匹配,则给出新j值


//============================================================
template <class T1>
int string<T1>::index(const string<T1> &T,int pos)

int *next=new int[T.length];
getnext(T,next);
int i=pos-1,j=0;
while ( i<length && j<T.length )

if (j==-1|| s[i]==T.s[j] ) ++i;++j;
//不失配则继续比较后续字符
else j=next[j];
//S的i指针不回溯,从T的k位置开始匹配

if(j>=T.length)
return i-T.length+1; //子串结束,说明匹配成功位置
else return -1;


如上,对于1、2,分别写出完整的可直接运行的main函数,不一定要用模板(最好不用),这对高手来说是小菜一碟吧,复制粘贴,写个主函数,加点东西,再修改修改就好了,万分感谢,测试成功再补100分!!!
在线等,很急,测试成功,立即给分,加分!!!!!
-------------------------------------------------------
已经不需要了,nnd,白白浪费了200分……

参考技术A #include <string>
using namespace std;

string s = "zabcdefg";

int index1(const string ss, int pos)

if (pos<0 || pos>s.length())
printf("pos²»ºÏ·¨£¡");
int i = pos, j = 0;

while (i < s.length() && j < ss.length())
if (s[i]==ss[j])
i++;
j++;
else
i=i-j+1;
j=0;



if (j>=ss.length())
return (i-j+1);
else
return -1;

void getnext(const string ss, int *next)

int i = 0, j = -1;
next[i] = -1;
while (i < ss.length())
if (j == -1 || s[i] == ss[j])
i++;
j++;
next[i]=j;
else
j = next[j];



int index2(const string ss, int pos)

int *next = new int[ss.length()];
getnext(ss, next);

int i = pos, j = 0;
while (i < s.length() && j < ss.length())
if (j==0 || s[i]==ss[j] )
++i;
++j;
else
j = next[j];



if (j >= ss.length())
return i-ss.length()+1;
else
return -1;


int main()

string ss = "abc";
printf("index1: %d, index2: %d\n", index1(ss, 0), index2(ss, 0));

return 0;
参考技术B 唉,还是去CSDN问吧,百度知道太水了,都是些弱智题。以后不来了。。 参考技术C 恩,百度提问太差了 我都丢了几次高分都没有成功!
我估计丢了500分了不是乱答就是没通过,分又没有

数据结构第四章学习小结

     第四章主要是串和数组的学习,之前对串和数组的应用仅限于对其单独处理,本章学习着重于对具体题目的实际操作,实践了串的模式匹配算法,对其有了更深入的了解,数组的应用拓展到了稀疏矩阵的存储的实现。

一.串

串的模式匹配

BF算法

首先未匹配到串尾时,将两个字符串一一匹配,可用C++自带的length()函数实现

while(i<=S.length()&&j<=T.length())

 

接下来就是匹配的过程

if(S[i]==T[j]){
        i++;j++;
        }//若匹配则继续比较下一位
else{
        pos++;
        i=pos;
        j=0;
        }//若不匹配则i回溯到之前比较的首位的下一位,j回溯到首位 

 

BF算法简单粗暴容易理解,但最坏情况下时间复杂度高,使用改进算法KMP算法j不必回溯,减少了时间复杂度。

 

二.数组:

数组是一种随机存取结构,使用数组存储的数据,可以通过其规律性,由下标计算其存储位置

C(i)= L(i=n)

C(i)=C(i+1)*b(i+1)

用二维数组可以表示一些特殊矩阵,如对称矩阵、三角矩阵、对角矩阵及稀疏矩阵,本章着重于实现用二维数组存储稀疏矩阵的方法。

稀疏矩阵

在稀疏矩阵中,我们要做的就是存储非0元素的信息,首先单独思考一个非0元素,我们要存储的是它的行号、列号、值,可以用一个三元组实现。

typedef struct{//定义一个三元组存放稀疏矩阵中非0元素的信息 
    int i;
    int j;
    int value;
}node;

 

再将眼光放远到整个矩阵中,我们要存储的信息的是矩阵的行数、列数、非0元素的个数和信息,于是我们在矩阵的类中嵌套进三元组类。

typedef struct{//存放矩阵信息 
    int m;//矩阵行数 
    int n;//矩阵列数 
    int N;//非0元素的个数 
    node a[500];//非0元素信息 
}Matrix;

接下来就是输入输出啦

三、AI核心代码

该题目的具体要求主要是:1.删除多余空格 2.大写转小写 3.I,me换成you  4.?换! 5.can you换I can,了解具体要求后,我们就可以先开始写主函数形成大体解题框架,再通过具体函数的编写实现程序。

  解题过程中有几个比较重要的点:

1.     平时对字符扫描时一般用习惯for,但具体用for还是while还是要根据条件来判断,有规律逐个扫描用for,无规律用while。在该题中,我们需要有规律地逐个扫描字符,于是用for语句定位到第一个非空字符串。

for(i=0;s[i]!=&&s[i]== ;i++); 

 

2.  在实现大写转小写时编写代码比较复杂,而像这样操作一般都会有函数可以直接调用,平时可以多积累一些函数需要用到时直接调用,如该题可以直接调用tolower函数程序会简洁许多

if(s[i]!=I){
      t[j]=tolower(s[i]);//大写转小写 
      ++j,++i;
      continue; 
          }
       else
       t[j++]=s[i++];

 

3.  题目中要求被转化的词是独立的,我们可以编写一个函数确保被转化的词的独立性,通过判断是否前后是否为分隔符来判断,而分隔符种类很多不能一一列举,于是我们可以往相反方向思考,除了字母和数字之外都是分隔符

bool independent(char ch){//判断是否为分隔符(除字母和数字) 
    ch=tolower(ch);
    if(ch>=0&&ch<=9||ch>=a&&ch<=z)
    return false;
    else
    return true;
}

 

分隔符问题要考虑溢出,当字符前面没有分隔符即i=0时该字符头部也是独立的

j==0||independent(t[j-1])

 

该语句可以解决这个问题,当||前面条件成立时不判断后面条件是否成立,直接判断为字符前无分隔符,头部独立。

再做相似题目时,先写出大体框架,再一步步完善未考虑到的溢出及边界问题

 

四、总结

KMP算法还是没能研究出来怎么写,希望之后能一点点消化它的思想。虽然写出了AI核心代码的题目,但大部分还是在老师带领下写的,希望之后能自主写出这样一段神奇有趣的代码。

以上是关于数据结构(c++)字符串 模式匹配算法问题,对高手来说只要写一点点的主要内容,如果未能解决你的问题,请参考以下文章

数据结构关于串的KMP算法的理解高手请进

数据结构第四章学习小结

kmp算法字符串匹配算法

数据结构(C++)笔记:04.字符串与多维数组

C++ 算法进阶系列之从 Brute Force 到 KMP 字符串匹配算法的优化之路

数据结构与算法——字符串匹配问题(KMP算法)