在字符串中删除特定的字符
Q:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。
例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。
A:对于这个题目,办法就是遍历第一个字符串,每次遍历时查找该字符是否在第二个字符串中,如果在,则要删除该字符。所以该问题就分为两步,查找和删除。
按照最笨的做法,查找使用线性查找,即对于每一个字符,遍历第二个字符串,看是否出现。这样时间复杂度太高,如果第一个字符串长度为m,第二个字符串长度为n,则时间复杂度为O(mn)。
再看删除,最笨的方法是,对于每一个要删除的字符,将其后的每一个字符都向前挪一位,这样时间复杂度也太高,为O(m^2),所以也不宜采用。
再想想该用什么方法尽量减少时间复杂度。
对于查找,快速的方法就是使用哈希,这里也不例外。对于第二个字符串中的每一个字符,我们用字符的ASCII码值作为哈希函数,将其映射到长度为256的布尔数组中,这样对于第一个字符串的每一个字符,查找该字符在数组特定位置是否存在即可。
对于删除我们可以使用快慢指针。dest和source指针初始化为第一个字符串的开始。然后,每个循环中,如果指向的字符不在第二个字符串中,则将该字符复制给dest指向的位置,并且dest和source同时向前走一步,如果指向的字符在第二个字符串,则仅仅将source向前走一步。循环的终止条件是source指向'\0',最后不要忘记dest指向的位置填上一个终止符。
1 #include <iostream> 2 using namespace std; 3 4 void Func(char* first,char* second) 5 { 6 bool hash_table[256]; 7 for(int i=0;i<256;++i) 8 hash_table[i]=false; 9 10 while(*second) 11 { 12 hash_table[*second]=true; 13 ++second; 14 } 15 16 char *dest,*source; 17 dest=first; 18 source=first; 19 while(*source) 20 { 21 if(!hash_table[*source]) 22 { 23 *dest=*source; 24 ++dest; 25 ++source; 26 } 27 else 28 ++source; 29 } 30 *dest='\0'; 31 cout <<first<<endl; 32 } 33 34 int main() 35 { 36 char first[50],second[50]; 37 cin.getline(first,50); 38 cin.getline(second,50); 39 Func(first,second); 40 return 0; 41 }