字符串常见问题总结(一)
2013-11-15 15:51
447 查看
字符串处理中的常见问题总结(一)
C语言中字符串处理方面的问题非常普遍,常见问题如:查找,替换,复制,移动,插入,删除,排序,单词统计,字符串类型与其他类型(整形,实型,长整形)之间的相互转换等。
一、 字符串的查找
C语言库函数<string.h>中有很多有关的函数,如:int strcpm(char * src, char*dest); int strncpm(char*,char*);char *strstr(char*, char*) (从字符串str1中查找是否有字符串str2,如果有,从str1中的str2位置起,返回str1中str2起始位置的指针,如果没有,返回null。); char* strchr(char*, char)(查找字符串s中首次出现字符c的位置)
其中strcmp(); strncmp();已经在常用库函数实现一文中说明了。下面给出strstr()和strchr()两个函数的实现。
首先是strchr();这个函数的实现比较简单,只需要一次遍历字符串就可以了,算法效率O(n)。
其次实现strstr()函数,也就是模式串匹配的问题,这个问题有多种不同的解决办法,它们的执行效率也不相同。
首先是朴素匹配法(暴力检索),这种方法是比较容易想到的,但是它的执行效率O(n*m),即对回溯的对父串进行匹配。
另一种比较常用的方法是KMP算法,该算法具有较高的效率,该算法的时间效率为O(m+n)m,n分别为父串和模式串的长度。该方法是基于不对父串回溯的方法,分析模式串得出next[]数组,然后利用next数组可以实现BMP算法,具体的分析可以参考http://blog.csdn.net/yaochunnian/article/details/7059486
此处也可以利用求next数组的方法求取一个字符串的最大相等前缀和后缀,不过此时要有些小的变动。
应用实例:从键盘上读入一批单词,统计其中某个单词出现的次数(如good);
以上所用的KMP都可以用C语言的库函数strstr()代替,但是strstr()函数(查看visual studio 2010中的库函数)采用的是朴素搜索法,因此自己编写的KMP的效率是比库函数中的效率高的。KMP是一个必须要掌握的算法,以后会经常用到,在多次编写后会增加对其的理解。
C语言中字符串处理方面的问题非常普遍,常见问题如:查找,替换,复制,移动,插入,删除,排序,单词统计,字符串类型与其他类型(整形,实型,长整形)之间的相互转换等。
一、 字符串的查找
C语言库函数<string.h>中有很多有关的函数,如:int strcpm(char * src, char*dest); int strncpm(char*,char*);char *strstr(char*, char*) (从字符串str1中查找是否有字符串str2,如果有,从str1中的str2位置起,返回str1中str2起始位置的指针,如果没有,返回null。); char* strchr(char*, char)(查找字符串s中首次出现字符c的位置)
其中strcmp(); strncmp();已经在常用库函数实现一文中说明了。下面给出strstr()和strchr()两个函数的实现。
首先是strchr();这个函数的实现比较简单,只需要一次遍历字符串就可以了,算法效率O(n)。
char * Mystrchr( const char * src, char ch) { assert(NULL!=src); do { if(*src== ch) { return const_cast<char*>(src); /*由于传入的是一个const指针,因此在此要对其进行去const转换,这样不会影响结果。*/ }}while('\0' != *(src++)); return NULL; }
其次实现strstr()函数,也就是模式串匹配的问题,这个问题有多种不同的解决办法,它们的执行效率也不相同。
首先是朴素匹配法(暴力检索),这种方法是比较容易想到的,但是它的执行效率O(n*m),即对回溯的对父串进行匹配。
char * Mystrstr_bf(char * par, char *form) { assert(NULL!=par&&NULL!=form); char * tempS = par; char *tempF = form; int len = strlen(form); while('\0'!=*par&&strlen(par)>= strlen(form)) { while(*tempS == *tempF&& *tempF!= '\0') { tempS ++; tempF ++; } if(*tempF == '\0') return tempS - len; tempF = form; par++; tempS = par; } return NULL; }
另一种比较常用的方法是KMP算法,该算法具有较高的效率,该算法的时间效率为O(m+n)m,n分别为父串和模式串的长度。该方法是基于不对父串回溯的方法,分析模式串得出next[]数组,然后利用next数组可以实现BMP算法,具体的分析可以参考http://blog.csdn.net/yaochunnian/article/details/7059486
char * KMP(const char *str, const char * pat) //KMP 实现方法 { assert(NULL!=str && NULL!=pat); int j = 0, k =-1; int slen = strlen(str); int plen = strlen(pat); if(slen < plen) return (char*)str; int *next = new int [plen]; next[0] = -1; while(j < plen) { if(k == -1 || pat[j] == pat[k]) { j++; k++; next[j] = k; } else k = next[k]; } for(int i =0; i<plen; i++) { cout<<next[i]; } cout<<endl; /*
求取next数组,并输出next数组
*/ int ppos = 0, spos = 0; while(ppos<plen && spos <slen) { if(ppos == -1 ||str[spos] == pat[ppos]) { ppos++; spos++; } else ppos = next[ppos]; } delete [] next; if(ppos < plen) return NULL; else { for(int i =0; i <spos-plen; i++) str++; return (char*)str; } }
此处也可以利用求next数组的方法求取一个字符串的最大相等前缀和后缀,不过此时要有些小的变动。
char *My_next(char *str) { assert(NULL!= str); int j =0, k =-1; int len = strlen(str); int *next = new int [len +1]; next[0] = -1; while(j <= len) //此时选择的是<=len { if(k == -1 || str[j] == str[k]) { j++; k++; next[j] = k; } else k = next[k]; } char *temp = str + len - next[len]; delete []next; return temp; }
应用实例:从键盘上读入一批单词,统计其中某个单词出现的次数(如good);
int main() { char a[100]; char b[] = "good"; gets(a); char *p1 = a; char *p2 = b; char *temp = NULL; int n =0; //char* result = KMP(a,b); //cout<<result<<endl; while(strlen(p1)>=strlen(p2)) { if(temp = KMP(p1,p2)) { p1 = temp; n++; } p1++; } cout<<n<<endl; return 0; }
以上所用的KMP都可以用C语言的库函数strstr()代替,但是strstr()函数(查看visual studio 2010中的库函数)采用的是朴素搜索法,因此自己编写的KMP的效率是比库函数中的效率高的。KMP是一个必须要掌握的算法,以后会经常用到,在多次编写后会增加对其的理解。
相关文章推荐
- 判断List、Map、Set是否为空及效率比较
- awk linux
- rcp(插件开发) 去掉plugin_customization.ini文件,在代码中实现配置功能
- 黑马程序员—(JAVA)多线程
- 获取ScrollView的可见高度,和获取HorizontalScrollView的可见宽度
- 面向对象编程的一些思考
- 不知道算不算另类的ASP.NET MVC4 Ajax分页
- 三种排序的比较(基数排序,qsort,sort)
- Jquery实现页面上所有的checkbox只能选中一个
- 而路边的快乐的翅膀花草都被熏得低下了头
- 漂亮的CSS后台管理登录界面
- 【ios 网络篇 3】 图片下载及缓存
- 环保车伸出了八条腿
- 老师一听到声音就会走下讲台巡视
- Android 修改拨号盘匹配规则 M
- [Unity3d]制作打包并载入AssetBundle
- javascript:随机十六位颜色函数
- 四本的哪怕只捐一本
- [Unity3d]制作打包并载入AssetBundle
- 移动研究院笔试题