这道题可以采用常规思路实现,对于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;
}
运行结果: