实现一个比较高级的字符匹配算法,即一串很长的字符,要求找到符合要求字符的字符串

一个小的算法题,题目如题。什么意思呢?

就是一个很长的模式串例如“432A5234B5664C3243454”,再给一个目标串“ABC”,只要模式串中某一个字符串同事包含目标串中的每一个元素即可!

要求很低!很明显的用暴力匹配很容易就做出来了,但是暴力匹配算法的时间复杂度很低,是乘方级的(O(n^m))!KMP算法很难处理这种模糊的匹配。

如何才能提高效率呢,利用hash表就很容易解决这个问题,而且是一个相当简单的哈希表,非常有利于新人理解hash表。

由于字符串最多只有255位,所以这个hash表就只有0~255这些元素,根据ASCII表的码值作为hash数组的下标,如果在目标串中存在,相应的位置元素为1,

其余的位置都是0。这样我们可以构建一个数组来统计目标串的字符是否出现在模式串中。


代码时间,首先制作一个hash表,由于在main函数中,我已经将hash表的每一个元素都初始化为0,这样只要将相应位置修改即可:

[plain]  view plain copy print ?
  1. /*  
  2. 功能:实现一个比较高级的字符匹配算法,即一串很长的字符,要求找到符合要求字符的字符串  
  3. 姓名:***  
  4. 时间:0:10 2014/1/18  
  5. */  
  6.   
  7. #include<stdio.h>  
  8. #include<stdlib.h>  
  9. #include<string.h>  
  10.   
  11. /*制作hash表并初始化*/  
  12. void mkHash(char T[],char hash[],int n)  
  13. {  
  14.     if(!T)  
  15.     {  
  16.         exit(-1);  
  17.     }  
  18.     for (int i = 0 ; i< n ; i++)  
  19.     {  
  20.         hash[T[i]] = 1;     /*根据ASCII表的码值作为hash数组的下标*/  
  21.     }  
  22. }  



下面这个函数就是某个字符是否在hash中出现了

[plain]  view plain copy print ?
  1. int isExit(char str,char hash[])  
  2. {  
  3.     if(!hash)  
  4.     {  
  5.         exit(-1);  
  6.     }  
  7.     if(hash[str] == 0)  
  8.     {  
  9.         return 0;  
  10.     }  
  11.     else  
  12.     {  
  13.         return 1;  
  14.     }  
  15. }  


接下来这个是就是主要函数了,遍历模式串,主要匹配就输出没有什么难点很容易看得懂:

[plain]  view plain copy print ?
  1. void getPos(char S[] , int n , char hash[])  
  2. {  
  3.     if(!S && !hash)  
  4.     {  
  5.         exit(-1);  
  6.     }  
  7.     for (int i=0;i<n;i++)  
  8.     {  
  9.         if(hash[S[i]] == 1)  
  10.         {  
  11.             printf("%d ",i+1);  
  12.             hash[S[i]] = 0;  
  13.         }  
  14.     }  
  15. }  

再从main引导:

[plain]  view plain copy print ?
  1. int main()  
  2. {  
  3.     char S[255];  
  4.     char T[255];  
  5.   
  6.     char hash[255] = {0};  
  7.   
  8.     gets(S);  
  9.     gets(T);  
  10.   
  11.     int Slen = strlen(S);  
  12.     int Tlen = strlen(T);  
  13.   
  14.     mkHash(T,hash,Tlen);  
  15.   
  16.     getPos(S,Slen,hash);  
  17.       
  18.     system("pause");  
  19.     return 0;  
  20. }  

好,看看输出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值