递归7小题

注:7小题全是关于字符串操作的,有
1)字符串长度
2)字符串遍历
3)字符出现次数
4)两字符串是否相同
5)字符串逆转
6)回文串
7)删除字符
,均使用递归完成,需要指针、数组、字符串的知识。第5、6、7题趣味性更强。

1.字符串长度

long getLength(char * source)//求字符串长度
{
    if(*source)	//在未到达字符串结束符之前
    {
        return 1+getLength(source+1);
    }else	//到达字符串结束符 递归的最后一层
    {
        return 0;
    }
}

2.正序遍历字符串

void traverseString(char * source)//正序遍历字符串
{
    if(*source==0)
    {
        cout<<*source<<endl;
        return;
    }
    cout<<*source;
    traverseString(source+1);
}

3.某个字符在字符串中出现的次数

long getTimes(char * source,char target)//字符target在字符串source中出现的次数
{
    if(*source==0)//到达递归的最后一层
    {
        return 0;//回归
    }
    if(*source!=target)//尚未找到字符target
    {
        return 0+getTimes(source+1,target);//继续往下找
    }
    return 1+getTimes(source+1,target);//找到一个字符target,继续找
}

4.比较两个字符串是否相同

bool compare(char * string0,char * string1)//比较两个字符串是否相同
{   
    if(*string0=='\0' && *string1=='\0')//要么它成为递归的最后一层
    {
        return true;
    }
    if(*string0!=*string1)//要么它成为递归的最后一层
    {
        return false;
    }
    return compare(string0+1,string1+1);
}

5.逆转字符串


void reverseString(char * source)//逆转字符串(从中间向两边逆置)
{
/*
	通过指针的运用,用一半的数组元素推算出字符串的长度
	当访问到数组第i个元素时,就顺便访问下数组第i+i-1个元素、数组第i+1个元素,只要两者中的任一个值为'\0',则推算结束,即可得出字符串长度
*/
    static int length=0;
    static char * p;
    length++;
    if(source[length-1]==0) //偶数个字符
    {
        length=0;//length的使命已经结束,归零
    //若length不归零,在该函数第二次调用时就不能正确地逆转字符串
        p=source;
        return;
    }
    if(source[length]==0)   //奇数个字符
    {
        length==0;//length的使命已经结束,归零
        p=source+1;
        return;
    }
    reverseString(source+1);
    char t=*p;
    *p=*source;
    *source=t;
    p++;
}

6.回文串


bool isPalindrome0(char * back,char * advance)//从中间向两边进行两两互换
{
    //cout<<*back<<"--------"<<*advance<<endl;
    if(*advance==0)
    {
        return true;
    }
    if(*back!=*advance)
    {
        return false;
    }
    return isPalindrome0(back-1,advance+1);
}

bool isPalindrome(char * source)//是否为回文字符串 主函数中调用它
{
    static int length=0;
    length++;
    /*下面两个if语句是用字符串的一半长度推算出字符串完整的长度,包括结束符'\0'
        由此得出字符串的中间字符所在的地址
    */
    if(source[length-1]=='\0')  //偶数个字符
    {
        length=0;//静态变量length在最后一层必须归零
        return isPalindrome0(source-1,source);
    }
    if(source[length]=='\0')    //奇数个字符
    {
        length=0;//静态变量length在最后一层必须归零
        return isPalindrome0(source-1,source+1);
    }
    return isPalindrome(source+1);
}

7.删除字符串中指定字符

#include<iostream>
#include<cstring>
using namespace std;

void remove(char * source,char target)	//非递归版 与递归版思路一致,操作方式不同
{
	int k=0;
	for(int i=0;source[i];i++)
	{
		if(source[i]==target)
		{
			continue;
		}
		source[k]=source[i];
		k++;
	}
	source[k]='\0';

}

void removeInRecursion(char * source,char target)
{
/*
 指针变量source只管向前运动
 指针变量begin负责寻找非target字符的存储位置
 source和begin的初始值相同,即两者都指向字符串的首字节指针
1)尚未找到字符target时,source、begin同时向前运动,并执行*begin=*source
2)找到一个target时,souce向前运动、begin暂停运动
反复1)、2)



 */
	static char * begin=source;
	if(*source=='\0')	//到达递归的最后一层
	{
		*begin=*source;
		begin=NULL;	//避免外部函数(递归调用不算)多次调用,而导致静态变量begin的值产生混乱
		return;
	}
	if(begin==NULL)
	{
		begin=source;	
	/*
	 没有直接将source的值赋给begin,
	 主要原因:
	 在整个程序运行过程中,
	 1)静态变量begin在该函数执行结束后仍未销毁
	 2)待该函数再次执行时,静态变量begin还是上次的静态变量begin,其值还是上次存储的值
	 3)给静态变量begin直接赋值失效
	 static char * begin=source;就是这句
	 函数第一次被外部函数调用,执行了
	 再次被外部函数调用,不执行了
	 故在递归的最后一层里将bgin归零


	*/
	}
	if(*source!=target)
	{
		*begin=*source;
		begin++;
	}
	removeInRecursion(source+1,target);
}


int main()
{

	char * s=new char[1024];
	char target;
	char exit[]="exit";
	while(true)
	{
		cout<<"original string:\t";
		cin>>s;
		if(strcmp(s,exit)==0)
		{
			break;
		}
		cout<<"character to be removed:\t";
		cin>>target;
		removeInRecursion(s,target);
		cout<<"after deleting:\t";
		cout<<s<<endl;
		
		
	}
	
	delete []s;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值