这个算是比较经典的题目之一,之前在华为的笔试题目中也遇到过。具体题目忘记了,从网上找来了一个基本一致的题目进行学习,也针对网上现有的代码做一下简单的讨论。话不多说,我们便进入正题。
题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”。
首先,一种简明的低效方法:
通过遍历,我们依次判定第一个字符串中是否存在第二个字符串中的第i个字符,如果存在,则删除该字符,因此该方法就删除而言的时间复杂度为O(n^2)。
显然,整个算法的时间复杂度还是较大的。
空间兑换时间的方法:
对于字符串,由于ASCII码的所有符号为256个(包括了拓展表,参见http://wenku.baidu.com/linkurl=RH03r9polKdSfErbTthsNKglrjkMW4ISjHo1unYB1XQva03p7C1_eSuzsLZX6fd1AhlYzRlq_ciHGG8I2g7lDUuZ_kOngUHxoMIV7KFyae3),那么,我们可以申请一个数组用来代表这256个字符是否存在于第二个字符串中,如果有,则标记为1,如果没有则标记为0.同理,我们通过查询,对应ASCII值号下,数组是否为1,来判定是否删除。汉字描述确实费劲,我们便看看实例:
第一步,
第二个字符串为“aeiou”,对应的ascii为97,101,105,111,117,也就是说,需要将数组hashTable[97],hashTable[101],hashTable[105],hashTable[111],hashTable[117]的值赋值为1,其他为0;
第二步,
依次查找第一个字符串”They are students.”,如,第一个字符为‘T’,对应ASCII码为84,因此查看hashTable[84]的值,发现为0,因此不删除,同理,以此类推即可。最后时间复杂度为o(n).
字符串删除元素的一个好思路:
代码里,关于删除字符串的方式个人觉得是很不错的。之前,遇到类似的问题,我的思路一般为,通过创建一个字符串,将不需要删除的字符填入这个字符串中,然后再进行字符串的拷贝。而代码中通过指针实现了类似的方案,并且不需要进行赋值字符串且减少了空间的浪费,具体操作便看代码吧。
完整的代码如下:
// 从str中,删除一个指定的字符 void deleteOneChar(char* str, char toBeDelete) { if(str == NULL) return; int length = strlen(str); char* p = str; // 遍历str,删除和toBeDelete相等的字符 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; } // 使用第一种方法实现 复杂度O(n^2) void deleteChars1(char* str,const char* chars) { if(str==NULL) return; if(chars == NULL) return; // 依次删除chars中的每一个元素 for(int i=0; i<strlen(chars); i++) deleteOneChar(str,chars[i]); return; } // 使用第二种方法实现复杂度O(n) void deleteChars2(char* pStrSource, const char* pStrDelete) { if(NULL == pStrSource || NULL == pStrDelete) return; const unsigned int nTableSize = 256; int hashTable[nTableSize]; memset(hashTable, 0, sizeof(hashTable)); const char* pTemp = pStrDelete; while ('\0' != *pTemp) { hashTable[*pTemp] = 1; ++ pTemp; } char* pSlow = pStrSource; char* pFast = pStrSource; while ('\0' != *pFast) { if(1 != hashTable[*pFast]) { *pSlow = *pFast; ++ pSlow; } ++pFast; } *pSlow = '\0'; } int main() { char* str = "they are students"; char* p = (char*)malloc((strlen(str)+1)*sizeof(char)); strcpy(p,str); const char*q = "aeiou"; deleteChars2(p,q); cout<<p<<endl; free(p); p = NULL; }