字符串基本处理算法

最近想写写字符串处理方面的东西。前面已经写写了字符串分割函数的实现。下面再将几种常见的字符串处理算法实现了下。

第一个为统计字符串的长度函数,很简单,定义一个指针指向字符串首位,然后从头遍历到字符串的尾部,遇到'\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);

}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值