输入一个字符串,求出该字符串包含的字符集合,例如:输入 abcqwerabc ,输出,acbwqer

45 篇文章 2 订阅

方法一:

设置一个bool数组,用来记录字符的置为,初始化为false、

bool vis[74] = { false };   

设置一个num字符数组记录需要输出的字符

char num[55]; 

设置一个字符数组, 并输入

char ch[101];
cin >> ch;

遍历字符串,利用ASCII码值给相应的字符置位

for (int i = 0; ch[i]; i++)    
{ 
	if (!vis[ch[i] - '0'])        
	{ 
		vis[ch[i] - '0'] = true;            
		num[cnt++] = ch[i]; 
	} 
}    

当一个字符首次出现时,将其对应位置置位true,并赋到num中,之后再出现时进行判断,如果已经置为true则跳过。

记得赋尾0

num[cnt] = '\0';   

完整代码如下:

#include <iostream>

using namespace std;

int main()
{
	char ch[100];    
	char num[55];     
	bool vis[74] = { false };    
	int cnt = 0;     
	cin >> ch;     
	for (int i = 0; ch[i]; i++)    
	{ 
		if (!vis[ch[i] - '0'])        
		{ 
			vis[ch[i] - '0'] = true;            
			num[cnt++] = ch[i]; 
		} 
	}    
	num[cnt] = '\0';     

	cout << num << endl;
		
	system("pause");
	return 0;
}

方法二:

该方法利用STL中的string,较为简单。

#include <iostream>
#include <string>

using namespace std;

int main()
{
	char tmp[101] = { 0 };

	cin >> tmp;
	string src(tmp);

	string dest;

	for (auto & ch : src)
	{
		if (dest.find(ch) == -1)
		{
			dest.push_back(ch);
		}
	}

	cout << dest;

	system("pause");
	return 0;
}

方法三:

首先设置两个全局变量

static int g_blbitmap = 0;
static int g_slbitmap = 0;

核心思想是利用二进制位记录字符的出现(只用到26位,因为只有26个字符)

void setbit(char ch)
{
	if (ch <= 'Z' && ch >= 'A')
	{
		g_blbitmap |= (1 << (ch - 'A'));
	}
	else
	{
		g_slbitmap |= (1 << (ch - 'a'));
	}
}

bool find(char ch)
{

if (ch <= 'Z' && ch >= 'A')
{
	return (g_blbitmap >> (ch - 'A')) & 1;
}
else
{
	return (g_slbitmap >> (ch - 'a')) & 1;
}

}

每个字符第一传入find函数必然返回0,此时对该字符进行push_back,同时调用setbit函数对相应字符进行置位,之后再传入相同的字符,对应的二进制位已经被置位1,使得find函数返回值为1,不会进入if判断,也就不会再次对该字符进行push_back。

举例来说明

假如给定字符串 “abcqwerac”

字符‘a’传给find
(0 >> (‘a’ - ‘a’)) & 1;

看二进制位
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0001
0 & 1为0
此时find函数 return 0;

执行

	dest.push_back(ch);
	setbit(ch);

调用setbit函数

g_slbitmap |= (1 << ('a' - 'a'));

同样看二进制位
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0001
g_slbitmap变为
0000 0000 0000 0000 0000 0000 0000 0001

假如再出现字符’a’,由于g_slbitmap已经被置位,所以会返回1,就不会再执行push_back操作。
同类,再传入其他字符
‘b’
字符’b’传给find
(0 >> (‘b’ - ‘a’)) & 1;
切记g_slbitmap已经不是0了
变为
0000 0000 0000 0000 0000 0000 0000 0001
将其右移1位再按位与1
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0001
变为
0000 0000 0000 0000 0000 0000 0000 0011

也就是说没传入一个新字符,都会有一个对应的二进制位被置为1,之后传入相同字符就不会再执行push_back操作。

#include <iostream>
#include <string>

using namespace std;

static int g_blbitmap = 0;
static int g_slbitmap = 0;

void setbit(char ch)
{
	if (ch <= 'Z' && ch >= 'A')
	{
		g_blbitmap |= (1 << (ch - 'A'));
	}
	else
	{
		g_slbitmap |= (1 << (ch - 'a'));
	}
}

bool find(char ch)
{

	if (ch <= 'Z' && ch >= 'A')
	{
		return (g_blbitmap >> (ch - 'A')) & 1;
	}
	else
	{
		return (g_slbitmap >> (ch - 'a')) & 1;
	}
}

int main()
{
	char tmp[101] = { 0 };

	cin >> tmp;
	string src(tmp);

	string dest;

	for (auto & ch : src)
	{
		if (!find(ch))
		{
			dest.push_back(ch);
			setbit(ch);
		}
	}

	cout << dest;

	system("pause");
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值