关于字符串问题的拓展

字符串相关问题

字符串问题 ,一直以来是编程人员练习的 ,各种稀奇古怪的问题层出不断,让我们感到很难缠。。
下面是我总结的一些字符串问题 :
如 果想要了解字符串库函数模拟  string库函数
让我们来看看吧!!!

1、字符串的翻转

翻转问题,一个很常见的问题,就是将一个字符串逆序输出。。。。
代码分析
char *my_reverse(char *left,char* right )//left为字符串左端,right为字符串右端
{
	char *ret = left;
	assert(left);
	assert(right);
	while(left<right)
	{
		char str = *left;//两端交换
		*left  = *right;
		*right = str;
		left++;
		right--;
	}
	return  ret;
}
当然有时候
老师,会让我们用递归的方法来完成这个问题
例如 "abcdefg"
现将字符串的第一个字符保存起来 将最后一个放到第一个字符处 ,最后一位赋上“\0”;
字符串指针++;
如果条件满足就进入 递归 
否则就将  保存的字符 传 给  最后 一个地址处

流程是;
abcdefg   
gbcdef\0      
gfcde\0\0b
gfed\0\0\0c
gfedc\0\0
gfedcb\0
gfedvba

代码分析
char *my_reverse(char *str)
{
    char  tem = *str; 
    int len  = strlen(str);  
    *str = *(str+len -1);  
    *(str+len -1) ='\0';  
    if(strlen(str+1)>1)  //表示没有走到最中间
    {  
          my_reverse(str+1);  
    }  
    *(str+len-1)=tem;  //将前面的字符放到后面
    return str;  
}

2、字符串有序翻转

有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
要求:
不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)
这个问题看成是先将字符串整个翻转 ,然后将每个单词 翻转
char *Part_reverse(char *str)
{
	char *left = str;
	char *right = str;
	char *ret = str;
	int len = 0;
	assert(str);
	while(*str)//求字符串的右端
	{
		str++;
	}
	str--;
	my_reverse(ret,str);//将字符串整个翻转
	while(*left)
	{
		while(*right!=' '&&*right!='\0')//遇到空格 和\0停下
		{
			right++;
		}
		right--;
		my_reverse(left,right);//单词翻转
		right++;
		if(*right)
			right++;
		left  =right;

	}
	return ret;
}

3、字符串替换空格

请实现一个函数,把字符数组中的每个空格替换成“%20”。
例如输入
“we are happy.”,则输出“we%20are%20happy.”
这字符串问题就是将空格换成%20    所以原字符串空间大小一定要充足,足够将替换后的字符串放入
我做的方法是这样的 ,先找出字符串中有几个空格,判断出要往后移动几个字节
然后,遇到空格后替换
char *replace_blank(char *str)
{
	char *ret = str;
	int n =0 ;
	assert(str);
	while(*str)
	{
		if(*str==' ')//计算空格个数
		{
			n++;
		}
		str++;
	}
	while(n)
	{
		while(*str !=' ')
		{
			*(str+2*n) = *str;//将单词后移
			str--;
		}
		*(str+2*n)='0';//替换空格
		*(str+2*n-1)='2';
		*(str+2*n-2)='%';
		str--;
		n--;//递减空格
	}
	return ret;
}

4、字符串的左旋和右旋

左旋

实现一个函数,可以左旋字符串中的k个字符。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
实现这个函数有两种方法 :
1、就是先全体翻转,再部分翻转;
2、就是死办法  ——一个一个的前移;
方法一代码:
char *Left_move(char *dest,size_t n)//n不为0;
{
	char *ret= dest;
	char *start  = dest;
	char *end   = NULL;
	assert(dest);
	end = start+strlen(dest) - 1;//字符串结尾指针
	my_reverse(start,end);//先整个翻转
	my_reverse(start,end-n);//左半部分翻转
	my_reverse(end-n+1,end);//右半部分翻转
	return dest;
}

翻转的代码 ,前面第一个就是;
但是这个代码旋转数为 0时 ,会有问题;
方法二代码:
char *Left_move(char *dest,size_t n)
{
	char *ret = dest;
	char *cp = dest;
	assert(dest);
	while(n--)
	{
		char temp = *cp;//保存第一个字符
		while(*(cp+1))//向前移动
		{
			*cp = *(cp+1);
			cp++;
		}
		*cp = temp;//将第一个字符放到结尾
		cp = dest;
	}
	return  ret;
}

右旋

实现一个函数,可以右旋字符串中的k个字符。
AABCD右旋一个字符得到
D A ABC
AABCD右旋两个字符得到 CD AA B
实现这个函数同样也有两种方法 :
1、就是先全体翻转,再部分翻转;
2、就是死办法  ——一个一个的后移;

代码1:
char * Right_move(char *str,size_t n)//右旋函数  n为旋转量  
{  
    char *ret = str;  
    char *start= str;  
    char *end = str;  
    int len =0 ;//不含‘\0’  
    assert(str);  
    len = strlen(str);  
    end = (start+len-1);  
    my_reverse(start,end);  //整个翻转
    my_reverse(start,start+ n-1);  //左半部分翻转
    my_reverse(start+n,end);  //右半部分翻转
    return ret;  
}  
同样的 n  不为0;

代码2:

char * Right_move(char *dest,size_t n)//右旋函数  n为旋转量
{
	char *ret = dest;
	char *cp = dest+strlen(dest)-1;
	assert(dest);
	while(n--)
	{
		char temp = *cp;//保存最后一个字符
		while(cp!=dest)//向后移动
		{
			*cp = *(cp-1);
			cp--;
		}
		*cp = temp;//将最后一个字符放到开头
		cp = dest+strlen(dest)-1;
	}
	return  ret;
}

5、模拟实现atoi函数

atoi  函数是什么意思,大家都很清楚 ————就是用来将一个字符串转化输出成整数

比如输入"12345",就会输出整型 数12345 

现在我们就来实现一下这个函数    StrToInt()函数

atoi函数的参数类型与返回值类型是

int atoi( const char *string );

代码分析
int  myatoi(const  char  *  str)
{
	assert(str);
	int ret = 0 ;
	char *  str1 = (char*) str;
	bool state = true;
	int num = 1;//表示正负号
	while(isblank(*str1))
	{
		*str1++;
	}
	if(*str1 == '-'||*str1 == '+')
	{
		if(*str1 == '-')
		{
			num =-1;
		}
		++str1;
	}
	while(isdigit(*str1))
	{
		ret *= 10;
		ret += *str1 - '0';
		++str1;
	}
	return ret*num;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值