找出字符串中第一个只出现一次的字符

find the first unique character in  a string and you can just traverse this string only one time. if there is no such character, just return '#' and '#' will not appear in the string, else return the character you find.

for example: "aAbBABac", return 'b', and to "aBBa" return '#' as the final result. 

方法一:

大家熟知的,以往我们找一个字符串中第一个只出现一次的字符的时候都允许重新遍历字符串,解决的思路是建立一个hash表,hash[256],遍历一遍字符串,记录每个字符出现的次数,然后在重新遍历字符串,查看每个字符出现的次数,如果出现的次数为1,则打印出此字符,遍历停止。 然而,当只要求遍历一遍字符串的时候,只能得到每个字符出现的次数,不能得到字符原来在字符串中的排列顺序。只要能想到这一点,就能够解决问题了。再重新设定一个order数组来记录字符出现的次序,然后遍历次序数组,取出第几次出现的是哪个字符,然后在到hash表中找它出现的次数,如果次数为1,那么就找到符合要求的字符串了。代码如下:

char first_unique_word(char *s)
{
	if (strlen(s)==0)  exit(0);
	if (strlen(s)==1)  return s[0];
	const unsigned int length=strlen(s);
	vector<int> num(256,0);
	vector<int>order(256,0);
	char res='#';
	for (int i=0;i<length;i++)
	{
		if (s[i]!='/0')
		{
			num[s[i]]++;
			order[i]=s[i];//i顺序记录出现的元素
		}
	}
	for (int j=0;j<length;j++)
	{
		if (num[order[j]]==1)
		{
			res=order[j];
			break;
		}
	}
	return res;
}
方法二

方法一利用一个order数组记录顺序出现的元素,在遍历完原字符串后,还需便利一次order数组,时间复杂度为O(2n),其实在字符串中就已经记录了字符出现的先后顺序,我们可以找一种方法,不用遍历order数组,直接读取其中字符即可。因为要求的是字符串中第一次出现的唯一字符,此字符是唯一的。所以我们从后往前遍历这个字符串,最后一个新加入order的元素就是从来没有出现的且是第一次出现的。代码如下:

char first_unique_word1(char *s)
{
	if (strlen(s)==0)  exit(0);
	if (strlen(s)==1)  return s[0];
	const unsigned int length=strlen(s);
	vector<int> num(256,0);
	vector<int>order(256,0);
	char res='#';
	int j=0;
	for (int i=length-1;i>=0;i--)
	{
		if (s[i]!='/0')
		{
			num[s[i]]++;
			if (num[s[i]]==1)
			{
				order[j]=s[i];
				j++;
			}
		}
	}
	if (num[order[j-1]]==1)
	{
		res=order[j-1];
	}
	return res;

}

完整代码如下:

#include<iostream>
#include <vector>
using namespace std;
char first_unique_word(char *s);
char first_unique_word1(char *s);
void main()
{
	char s[]="abbfabbcde";
	cout<<first_unique_word(s)<<endl;
	cout<<first_unique_word1(s)<<endl;

}
char first_unique_word(char *s)
{
	if (strlen(s)==0)  exit(0);
	if (strlen(s)==1)  return s[0];
	const unsigned int length=strlen(s);
	vector<int> num(256,0);
	vector<int>order(256,0);
	char res='#';
	for (int i=0;i<length;i++)
	{
		if (s[i]!='/0')
		{
			num[s[i]]++;
			order[i]=s[i];
		}
	}
	for (int j=0;j<length;j++)
	{
		if (num[order[j]]==1)
		{
			res=order[j];
			break;
		}
	}
	return res;
}
char first_unique_word1(char *s)
{
	if (strlen(s)==0)  exit(0);
	if (strlen(s)==1)  return s[0];
	const unsigned int length=strlen(s);
	vector<int> num(256,0);
	vector<int>order(256,0);
	char res='#';
	int j=0;
	for (int i=length-1;i>=0;i--)
	{
		if (s[i]!='/0')
		{
			num[s[i]]++;
			if (num[s[i]]==1)
			{
				order[j]=s[i];
				j++;
			}
		}
	}
	if (num[order[j-1]]==1)
	{
		res=order[j-1];
	}
	return res;

}

以上代码输出为 

f

f



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值