从第一字符串中删除第二个字符串中所有的字符,例如第一个字符串“We are students.”,第二个字符串“aeiou”,则删除后的结果为“W r stdnts.”。通过文章知道,我们可以通过hash表来统计第二个字符串中的字符,然后再逐一遍历第一个字符,如果在hash表里面存在该字符,就进行删除操作。代码如下:
#include "stdafx.h"
#include "iostream"
using namespace std;
//在第一个字符串中删除在第二个字符串中出现的所有字符
void deleteFirstInSecond(char* first,const char* second)
{
if(first==NULL)
return;
const int tableSize = 256;
unsigned int hashTable[tableSize];
for(unsigned int i = 0; i < tableSize;i++)
hashTable[i] = 0;
while(*(second) != '\0')
hashTable[*(second++)]++;
while(*(first) != '\0')
{
if (hashTable[*(first)] > 0)
deleteOneChar(first,*(first));
first++;
}
}
//从str中删除一个指定的字符
void deleteOneChar(char* str,char toBeDelete)
{
if (str == NULL)
return;
int length = strlen(str);
char* p = str;
for (int i=0;str[i]!='\0'&&i<length;i++)
{
if (str[i] == toBeDelete)
{
int j = i;
for (;str[j]!='\0'&&j < length - 1;j++)
{
str[j] = str[j+1];
}
str[j] = '\0';
}
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
char* first = "We are students";
const char* second ="aeiou";
char* p = (char*)malloc((strlen(first)+1)*sizeof(char));
strcpy(p,first);
deleteFirstInSecond(p,second);
//deleteChars(p,second);
cout<<p<<endl;
getchar();
return 0;
}
当然字符串的删除,char* 分配的内存是连续的,当从字符串中删除一个字符,需要将字符串后面的所有字符统一进行前移移位,对于一个长度为n的字符串,删除一个字符的时间复杂度为O(n),再加上有可能删除n个字符,所以本题的时间复杂度就变为O(n^2)了。
其实,在每次删除一个字符的时候都将后面的所有的字符进行前移浪费了时间。我们可以设想,当一个字符被删除的时,我们用后面的字符进行填补,相当于这个字符被删除了。我们可以定义两个指针(pFast和pSlow),初始的时候都指向第一字符的起始位置,当pFast指向的字符是需要删除的字符,则pFast直接跳过,指向下一个字符。如果pFast指向的字符是不需要删除的字符,那么把pFast指向的字符赋值给pSlow指向的字符,并且pFast和pStart同时向后移动指向下一个字符。这样,前面被pFast跳过的字符相当于被删除了。这样,完成该问题的时间复杂度就变为了O(n)。代码如下:
// 时间复杂度O(n)
void deleteChars(char* first, const char* second)
{
if(NULL == first || NULL == second)
return;
const unsigned int nTableSize = 256;
int hashTable[nTableSize];
memset(hashTable, 0, sizeof(hashTable));
const char* pTemp = second;
while ('\0' != *pTemp)
{
hashTable[*pTemp] = 1;
++ pTemp;
}
char* pSlow = first;
char* pFast = first;
while ('\0' != *pFast)
{
if(1 != hashTable[*pFast])
{
*pSlow = *pFast;
++ pSlow;
}
++pFast;
}
*pSlow = '\0';
}
int _tmain(int argc, _TCHAR* argv[])
{
char* first = "We are students";
const char* second ="aeiou";
char* p = (char*)malloc((strlen(first)+1)*sizeof(char));
strcpy(p,first);
//deleteFirstInSecond(p,second);
deleteChars(p,second);
cout<<p<<endl;
getchar();
return 0;
}