1哈希表处理字符
字符的哈希表虽然占用了一定的额外空间,但可以大大地减少时间复杂度,是典型的空间换取时间的栗子。下面的栗子都属于这一类。
1.1 第一个只出现k次的字符
【题目】
在字符串中找出第一个只出现k次的字符,如字符串abeccdaff第一个只出现1次的字符时e
【代码】
char firstNRepeatingChar(const char *str, int n = 1){
if(!str) return '\0';
const int tableSize = 1<<8;
unsigned table[tableSize] = {0};
const char *sp = str;
while(*sp) ++table[*(sp++)];
for(sp = str;*sp;++sp) if(table[*sp]==n) return *sp;
return '0';
}
1.2 从字符串中删除字符
【题目】
求从第一个字符串中删除在第二个字符串中出现过的所有字符后的字符串,并返回删除字符的个数。例如:从We are students. 中删除aoeiu 后的字符串为W r stdnts. 返回5。
【代码】
int removeCharsFromString(char *str, const char *s){
int res(0);
if(!(str && s)) return res;
const int tableSize = 1<<8;
unsigned table[tableSize] = {0};
while(*s) table[*(s++)] = 1;
char *sp = str;
while(*sp){
if(table[*sp]) ++res;
else *(str++) = *sp;
++sp;
}
*str = '\0';
return res;
}
1.3 限制字符串中字符最多重复出现的次数(删除字符串重复字符)
【题目】
限制一个字符串中字符重复出现的次数,特别的,当次数限制为1时就是删除字符串中重复出现的字符。返回值要求返回删除的字符数。例如:aaaabbbccd 次数限制为1时为abcd,返回6。
【代码】
int removeDuplication(char *str, unsigned n = 1){
int res(0);
if(!str) return res;
const int tableSize = 1<<8;
unsigned table[tableSize] = {0};
char *sp = str;
while(*sp) table[*(sp++)] = n;
for(sp = str;*sp;++sp){
if(table[*sp]) {
--table[*sp];
*(str++) = *sp;
}
else ++res;
}
*str = '\0';
return res;
}
1.4 判断两个字符串是否为变位词
【题目】
在英语中,如果两个单词中出现的字母相同,并且每个字母出现的次数也相同,那么这两个单词互为变位词。要求判断给定的两个字符串是否互为变位词。
【代码】
bool isAnagtam(const char *s1, const char *s2){
if(!s1) return !(s2 && *s2);
if(!s2) return !(s1 && *s1);
const int tableSize = 1<<8;
int table[tableSize] = {0};
while(*s1) ++table[*(s1++)];
while(*s2) --table[*(s2--)];
for(int k1(0);k1<tableSize;++k1)
if(table[k1]) return false;
return true;
}