Q1.3

/*Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two
additional variables are fine. An extra copy of the array is not.
FOLLOW UP
Write the test case for this method
*/

/*不能使用额外的一份数组拷贝时指根本不允许开一个数组,还是说可以开一个固定大小,与问题规模(即字符串长度)无关的数组??*/

//只能使用额外的一到两个变量 O(n^2)
/*依次访问这个数组的每个元素,每访问一个,就将该元素到字符串结尾的元素中相同的元素去掉(比如设置为'\0')*/
/*
测试用例包括:
1. 不包含重复字符的字符串;
2. 字符串全是重复字符;
3. 空字符串;
4. 重复字符连续出现;
5. 重复字符不连续出现; 
*/
#include <iostream>
#include <string>
#include <cstring>
#include <set> 
using namespace std;

// O(n^2)依次访问数组中的每个元素,每访问一个,就将该元素到字符串结尾的元素中相同的元素去掉(置为'\0') 
void removeDuplicate(char s[])
{
	int len = strlen(s);
	if(len<2) return;
	int p=0;
	for(int i=0; i<len; ++i)
	{
		if(s[i]!='\0')
		{
			s[p++] = s[i];
			for(int j=i+1; j<len; ++j)
			{
				if(s[j]==s[i])
					s[j]='\0';
			}
		}
	} 
	s[p]='\0';
} 

//利用set的元素不可重复的特性来存储字符串中的字符,然后输出set中的字符 
void removeDuplicate1(char s[])
{
	int len = strlen(s);
	set<char> su;
	set<char>::iterator si;
	for(int i=0; i<len; ++i)
	{
		su.insert(s[i]);
	}	
	for(si=su.begin(); si!=su.end(); ++si)
		cout << *si;
	cout << endl;
}

//用一个数组来表征每个字符的出现(假设是ASCII字符,则数组大小为256),这样只需要遍历一遍字符串即可,时间复杂度为O(n)
void removeDuplicate2(char s[])
{
	int len = strlen(s);
	if(len<2) return;
	bool c[256];
	memset(c,0,sizeof(c));
	int p = 0;
	for(int i=0; i<len; ++i)
	{
		if(!c[s[i]])
		{
			s[p++]=s[i];
			c[s[i]] = true;
		}
	}
	s[p] = '\0';
} 

//字符集只是a-z,即字符串只包含小写字母,那么使用一个int变量中的每一位来表征每个字符的出现,可以在O(n)的时间里移除重复字符,而且还不需要额外开一个数组.
void removeDuplicate3(char s[])
{
	int len = strlen(s);
	if(len<2) return;
	int check=0, p=0;
	for(int i=0; i<len; ++i)
	{
		int v=(int)(s[i]-'a');
		if((check & (1<<v))==0)
		{
			s[p++]=s[i];
			check |= (1<<v);
		}
	}
	s[p]='\0';
} 

int main()
{
	char s1[] = "abcde";
	char s2[] = "aaabbb";
	char s3[] = "";
	char s4[] = "ababababc";
	char s5[] = "ccccc";
	removeDuplicate3(s1);
	removeDuplicate3(s2);
	removeDuplicate3(s3);
	removeDuplicate3(s4);
	removeDuplicate3(s5);
	removeDuplicate1(s5);
	cout << "removeDuplicate(abcde) = " << s1 << endl;
	cout << "removeDuplicate(aaabbb) = " << s2<< endl;
	cout << "removeDuplicate() = " << s3 << endl;
	cout << "removeDuplicate(ababababac) = " << s4<< endl;
	cout << "removeDuplicate(ccccc) = " << s5 << endl;
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值