为学论坛“每日一题”系列---删除所有的a,复制所有的b(待修改)

题目

给定一个字符串,请删除所有的字符a并且复制所有的b。

要求:不要开辟新空间。其他字符顺序和个数保存不动。


先贴我自己的代码,待最后修改再写思路。因为我的解法中只有当a的个数等于b的时候才会正确。当a >= b的时候,则会有a会留下来。(代码后附上我自己的测试数据)


时间复杂度:O(2n)。虽然我的代码中的循环有三重循环,但是实际上我的程序最多只会遍历两次字符串。第一次是找出符合条件的索引,第二次是移动字符。


代码:

#include<stdio.h>
#include<string.h>

const int N = 100 ;
char szStr[N] ;
char *Process(char *szStr) ;

int main(void)
{
	int t ; 

	freopen("in.txt","r",stdin) ;

	scanf("%d",&t) ;
	while(t-- > 0)
	{
		scanf("%s",szStr) ;
		printf("%s\n",Process(szStr)) ;
	}
	return 0 ;
}

char* Process(char* szStr)
{
	int nLen = strlen(szStr) ;
	int fMovDir = -1, fReset = 0 ;
	int j,nB,nA,nBeg,nEnd ;
	int sp = -1 ;

	int i = 0 ;
	while(szStr[i] != '\0')
	{
		if(-1 == fMovDir && 'b' == szStr[i])
		{
			fMovDir = -1 ;
			fReset = 0 ;
			nB = 1 ;
			nA = 0 ;
			nBeg = i ;

			for(j = i+1 ; j < nLen ; ++j )
			{
				if('b' == szStr[j])
				{
					nB++ ;
				}
				else if('a' == szStr[j])
				{
					nA++ ;
					if(nA >= nB)
					{
						nEnd = j ;
						sp = nEnd+1 ;
						i = nEnd ; //更新索引

						while(nEnd >= nBeg)
						{
							if('b' ==  szStr[nEnd])
							{
								szStr[--sp] = szStr[nEnd] ;
								szStr[--sp] = szStr[nEnd] ;
							}
							else if(szStr[nEnd] != 'a')
							{
								szStr[--sp] = szStr[nEnd] ;
							}
							nEnd-- ;
						} //while
						fReset = 1 ;
					} //if nA >= nB

					if(1 == fReset)
					{
						fReset = 0 ;
						break ;
					}
				}
			}
		} // if
		else if( -1 == fMovDir && 'a' == szStr[i] )
		{
			fMovDir = -1 ;
			fReset = 0 ;
			nB = 0 ;
			nA = 1 ;
			nBeg = i ;

			for(j = i+1 ; j < nLen ; ++j )
			{
				if('b' == szStr[j])
				{
					nB++ ;
					if(nB >= nA)
					{
						nEnd = j ;
						i = nEnd ;
						sp = nBeg - 1 ;

						while(nBeg <= nEnd)
						{
							if('b' == szStr[nBeg])
							{
								szStr[++sp] = szStr[nBeg] ;
								szStr[++sp] = szStr[nBeg] ;
							}
							else if(szStr[nBeg] != 'a')
							{
								szStr[++sp] = szStr[nBeg] ;
							}
							nBeg++ ;
						}
						fReset = 1 ; 
					}
					if(1 == fReset)
					{
						fReset = 0 ;
						break ;
					}
				}
				else if('a' == szStr[j])
				{
					nA++ ;
				}
			}
		}
		i++ ;
	} //while
	return szStr ;
} //Process


测试数据:

11
bccbbcaccacaab
ab
ba
aba
aabb
bbaa
abab
aaab
baaa
ababba
bbbaaaaaabbb



当a的个数大于b的个数时:

#include<stdio.h>
#include<string.h>
#include<memory.h>

const int N = 100 ;
char szStr[N] ;
char *Process(char *szStr) ;

int main(void)
{
	int t ; 

	freopen("in.txt","r",stdin) ;

	scanf("%d",&t) ;
	while(t-- > 0)
	{
		scanf("%s",szStr) ;
		printf("%s\n",Process(szStr)) ;
	}
	return 0 ;
}

char* Process(char* szStr)
{
	int nLen = strlen(szStr) ;
	int fMovDir = -1, fReset = 0 ;
	int j,nB,nA,nBeg,nEnd ;
	int sp = -1 ;

	/*用于a和b个数不相等的情况*/
	int nSumA = 0,nSumB = 0 ;
	int fFirst = -1 ;
	/*******************/

	int i = 0 ;
	while(szStr[i] != '\0')
	{
		if(-1 == fMovDir && 'b' == szStr[i])
		{
			fMovDir = -1 ;
			fReset = 0 ;
			nB = 1 ;
			nA = 0 ;
			nBeg = i ;

			/*用于a和b个数不相等的情况*/
			nSumB++ ;
			if(-1 == fFirst)
			{
				fFirst = 1 ;
			}
			/*******************/
					

			for(j = i+1 ; j < nLen ; ++j )
			{
				if('b' == szStr[j])
				{
					/*用于a和b个数不相等的情况*/
					nSumB++ ;
					/*******************/

					nB++ ;
				}
				else if('a' == szStr[j])
				{
					/*用于a和b个数不相等的情况*/
					nSumA++ ;
					/*******************/

					nA++ ;
					if(nA >= nB)
					{
						nEnd = j ;
						sp = nEnd+1 ;
						i = nEnd ; //更新索引

						while(nEnd >= nBeg)
						{
							if('b' ==  szStr[nEnd])
							{
								szStr[--sp] = szStr[nEnd] ;
								szStr[--sp] = szStr[nEnd] ;
							}
							else if(szStr[nEnd] != 'a')
							{
								szStr[--sp] = szStr[nEnd] ;
							}
							nEnd-- ;
						} //while
						fReset = 1 ;
					} //if nA >= nB

					if(1 == fReset)
					{
						fReset = 0 ;
						break ;
					}
				}
			}
		} // if
		else if( -1 == fMovDir && 'a' == szStr[i] )
		{
			fMovDir = -1 ;
			fReset = 0 ;
			nB = 0 ;
			nA = 1 ;
			nBeg = i ;

			/*用于a和b个数不相等的情况*/
			nSumA++ ;
			if(-1 == fFirst)
			{
				fFirst = 0 ; //a第一个发现
			}
			/*******************/

			for(j = i+1 ; j < nLen ; ++j )
			{
				if('b' == szStr[j])
				{
					/*用于a和b个数不相等的情况*/
					nSumB++ ;
					/*******************/

					nB++ ;
					if(nB >= nA)
					{
						nEnd = j ;
						i = nEnd ;
						sp = nBeg - 1 ;

						while(nBeg <= nEnd)
						{
							if('b' == szStr[nBeg])
							{
								szStr[++sp] = szStr[nBeg] ;
								szStr[++sp] = szStr[nBeg] ;
							}
							else if(szStr[nBeg] != 'a')
							{
								szStr[++sp] = szStr[nBeg] ;
							}
							nBeg++ ;
						}
						fReset = 1 ; 
					}
					if(1 == fReset)
					{
						fReset = 0 ;
						break ;
					}
				}
				else if('a' == szStr[j])
				{
					/*用于a和b个数不相等的情况*/
					nSumA++ ;
					/*******************/
					nA++ ;
				}
			}
		}
		i++ ;
	} //while


	/*用于a和b个数不相等的情况*/
	if(nSumA > nSumB)
	{
		if(0 == fFirst) //在a较多的情况下,a首先被发现
		{
			i = 0 ;
			while(szStr[i] != '\0' && szStr[i] == 'a')
			{
				i++ ;
			}
			memcpy(szStr,szStr+i,strlen(szStr+i)+1) ;

			i = 0 ;
			while(szStr[i] != 0 && szStr[i] != 'a')
			{
				++i ;
			}
			szStr[i] = '\0' ;
		}
		else //b首先被发现
		{
			i = 0 ;
			while(szStr[i] != 0 && szStr[i] != 'a')
			{
				++i ;
			}
			szStr[i] = '\0' ;
		}
	}
	/*******************/
	return szStr ;
} //Process


测试数据:

12
abaaaaa
aacacacbbc
bccbbcaccacaab
ab
ba
aabb
bbaa
abab
aaab
baaa
ababba
bbbaaaaaabbb










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值