字符串基本处理算法
2015-06-27 17:32
357 查看
最近想写写字符串处理方面的东西。前面已经写写了字符串分割函数的实现。下面再将几种常见的字符串处理算法实现了下。
第一个为统计字符串的长度函数,很简单,定义一个指针指向字符串首位,然后从头遍历到字符串的尾部,遇到'\0'就停止,同时定义一个变量累加。下面直接贴代码:
然后beta版本加入单词次序调整,先利用alpha版本进行整个字符串的反转,然后对每个单词处理,目前区别单词主要是,遇到空格、‘\0’进行单词的反转。然后再参考具体代码进行理解:
字符互换函数:
字符串反转函数:
再看beta版本的函数,首先定义一个整形的数组alpha,长度为26,初始化为0,这个数组用以存储各个字符出现的次数,然后再定义一个index变量用来表示字符,然后遍历字符串为index赋值为str[i]-'a',这样就完成了26个下标的表示。然后数组下标相同累加,这样就将所有的字符出现的频数统计出来存储到了数组alpha中。
下面看看代码的实现:
到此四个简单的函数完全实现了,进行测试:
第一个为统计字符串的长度函数,很简单,定义一个指针指向字符串首位,然后从头遍历到字符串的尾部,遇到'\0'就停止,同时定义一个变量累加。下面直接贴代码:
int stringlen(char *str) { int length=0; while(*str++!='\0') length++; return length; }第二函数为字符串拷贝函数strcpy的实现,一般思路就是定义两个指针,一个指针指向源字符串首位,另一个指向待复制的字符串数组,将源字符串的字符依次赋值给目的字符串。这里实现了两个版本的alpha版本的就是简单的复制,beta版本加入了内存重叠检测,检查目的与源的长度是否匹配,这个版本的更加安全。代码实现如下:
char* strcopyalpha( char *src,char *dst) { assert(dst!= NULL && src!= NULL); char *ret = dst; do{ *dst++=*src++; }while(*src!='\0'); return ret; } char* strcopybeta(char *src,char *dst) { assert(dst != NULL && src != NULL); char *ret = dst; int cnt=stringlen(src)+1; if (dst >= src && dst <= src+cnt-1) { dst = dst+cnt-1; src = src+cnt-1; while (cnt--) *dst-- = *src--; } else { while (cnt--) *dst++ = *src++; } return ret; }第三个函数是字符串反转函数的实现,由于本函数实现的时候,是将字符互换,所以先定义了一个字符互换函数swap(char *str,int i,int j)。这里也实现两个版本的函数,alpha版本的函数只是简单地进行反转,不考虑单词可读性的问题,算法的主要思想就是,两个动态坐标begin与end。begin赋值为0,end赋值为字符串的长度减一;然后以begin与end作为字符数组的下标,并互换,然后begin后移,end前移,终止条件为begin与end相等。
然后beta版本加入单词次序调整,先利用alpha版本进行整个字符串的反转,然后对每个单词处理,目前区别单词主要是,遇到空格、‘\0’进行单词的反转。然后再参考具体代码进行理解:
字符互换函数:
void swap(char *str,int i,int j) { char temp; temp = str[i]; str[i] = str[j]; str[j] = temp; }
字符串反转函数:
char* reversestralpha(char *str,int begin,int end) { char *ret; ret=str; if(str!=NULL) while(begin<=end){ swap(str,begin,end); begin++; end--; } return ret; } char* reversestrbeta(char *str) { int i,j; char *ret; int begin=0,end=0; int length=stringlen(str)-1; ret=str; reversestralpha(str,0,length); printf("%s\n",str); for(i=0;i<length;i++) { if(str[i]==' '||str=='\0') { end=i-1; if(begin<end) { reversestralpha(str,begin,end); } begin=i+1; } /*else if(!isalpha(str[i])) { begin=i+1; }*/ } return ret; }第四个函数是对字符串中重复字符进行统计。本函数实现同样是两个版本,两个版本都可以达到要求,但是算法的复杂度不同。首先,看第一种,思路最简单,先固定一个字符分别与其他的字符相比较,相同则累加,不同则不进行累加,同时找出最大的值,这个算法需要两层循环,算法的复杂度为O(n*n)。
再看beta版本的函数,首先定义一个整形的数组alpha,长度为26,初始化为0,这个数组用以存储各个字符出现的次数,然后再定义一个index变量用来表示字符,然后遍历字符串为index赋值为str[i]-'a',这样就完成了26个下标的表示。然后数组下标相同累加,这样就将所有的字符出现的频数统计出来存储到了数组alpha中。
下面看看代码的实现:
int maxcharalpha(char *str) { int i,j,flag; int count=0; int max=0; int length=stringlen(str); for(i=0;i<length;i++) { for(j=0;j<length;j++) { if(str[i]==str[j]) ++count; } if(count>max) { max=count; flag=i; } count=0; } printf("%c:%d\n",str[flag],max); return max; } int maxcharbeta(char *str) { int alpha[26]={0}; int i; int length=stringlen(str); int index; int max,min,maxflag,minflag; for(i=0;i<length;i++) { if(isalpha(str[i])) { index=str[i]-'a'; alpha[index]++; } } for(i=0;i<26;i++) { if(alpha[i]!=0) { max=min=alpha[i]; maxflag=minflag=i; break; } } /**Find max character**/ for(i=0;i<26;i++) { if(alpha[i]!=0) { if(alpha[i]>max) { max=alpha[i]; maxflag=i; } } /**Find min character**/ if(alpha[i]!=0) { if(alpha[i]<min) { min=alpha[i]; minflag=i; } } } if(maxflag!=minflag) printf("max:\n%c:%d\nmin:\n%c:%d\n",maxflag+'a',max,minflag+'a',min); else printf("two type characters and equal\n"); return max; }
到此四个简单的函数完全实现了,进行测试:
#include<stdio.h> #include<assert.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<ctype.h> /*添加函数在此处*/ int main() { char str[1024]; char test[1024]; printf("string you wanna:\n"); scanf( "%[^\n]",str); /**Test string function**/ reversestrbeta(str); printf("reversestr:\n%s\n",str); strcopybeta(str,test); printf("%s:%d\n",test,stringlen(test)); maxcharbeta(str); }
相关文章推荐
- DIV横向排列_CSS如何让多个div盒子并排同行显示
- (转)内联(inline)函数与虚函数(virtual)的讨论
- Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
- awk调用系统命令
- 各种排序算法的分析及java实现
- python的logging模块详解
- POJ3253
- MacBook 连接Centos服务器
- AngulatJS多个控制器内数据共享
- java 16进制负数
- 论开辟经济发展的第二战场
- php的入门第一个例子(包括linux的环境安装与包括页面跳转,以及curl命令的调用)
- 正确的解决GridLayout在安卓4.0以下版本中兼容问题
- 2015.6.24 XJOI T1.不可视境界线
- LeetCode Multiply Strings
- Log4j —— 初步了解和使用
- js 变量 函数名的提升
- 坚持教学与科研相结合
- 【Oracle篇】Oracle的服务
- 【华为oj】查找组成一个偶数最接近的两个素数