给定两个字符串,从A中删除存在于B中的字符

本文介绍了一种利用位图优化的字符删除算法,通过构建位图并遍历字符串A来高效移除字符串B中存在的字符,实现了O(n)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题可以采用常规思路实现,对于A中的每一个字符,遍历B查询是否还有该字符,如果有的话则进行删除操作,这种做法时间复杂度为O(n^2)。


采用位图实现能够到达更好的时间效率,下面采用位图来解决这个问题。

由于ANSCII码总共只有256个字符,那么用8个unsigned int变量可完全表示,空间复杂度为常量复杂度O(1)。

首先遍历B字符串,若B中字符对应的ASCII值为n,就将位图的第n位置1。然后遍历字符串A,查询字符串A中字符在位图中对应的值,删除位图值为1的字符。


需要说明的是不要每删除一个元素都将后面的所有元素前移一遍,这样实际的算法时间复杂度是O(n^2)。
其实可以这样做,设置两个下标,i、j,如果不删除字符A[i]的话,把A[i]赋给A[j],如果要删除,直接使i加1跳过要删除字符,不对A[j]进行赋值,这样就以时间复杂度O(n)的代价完成了删除操作。

实现代码:

#include "stdafx.h"
#include <iostream>
using namespace std;
namespace DeleteSameChar
{
	void deleteSameChar(char* strA, const char* strB)
	{
		unsigned int bitMap[8];
		memset(bitMap, 0, sizeof(bitMap));
		for (int i=0; strB[i]; i++)						//创建位图
			bitMap[strB[i] / 32] |= 1 << (strB[i] % 32);
		int j = 0;
		int k = 0;
		while (strA[k])
		{						
			if (bitMap[strA[k] / 32] & (1 << strA[k] % 32))
				k++;
			else
				strA[j++] = strA[k++];
		}
		strA[j] = '\0';
	}
	void test()
	{
		char strA[] = { "woaibeijingtiananmen" };
		const char*strB = "ian";
		cout << strA << endl;
		deleteSameChar(strA, strB);
		cout << strA << endl;
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	DeleteSameChar::test();
	return 0;
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值