例如,给定一个“Stackoverflow for every one”并删除“aeiou”, 该函数应该将str转换为“Stckvrflw s fr vry n”. 我有一个char数组的字符串:str []和一个要删除的字符char数组:remove [] 我的解决方案
该函数应该将str转换为“Stckvrflw s fr vry n”.
我有一个char数组的字符串:str []和一个要删除的字符char数组:remove []
我的解决方案:循环str []在remove []中查找每个字符.每次都移动str []一个地方.我相信更好的黑客是可能的.
将整个字符串移动一个位置将使其成为有效的O(n ^ 2)算法.您可以在线性时间内就地执行此操作:void Remove (char * src, const char * match) { char * dest = src; for (;;) { char ch = *src++; if (!strchr (match, ch)) *dest++ = ch; // Copy chars that don't match if (!ch) break; // Stop when we copy over a null } }
我假设这些是空终止的.如果不是这种情况,那么您也必须传入长度并适当地修改算法.特别是,您将无法使用strchr.为了完整起见,这里有一个与char数组一起使用的版本(不是以null结尾).
// Removes from str[] (of length strlen), all chars that are found // in match[] (of length matchlen). Modifies str in place, and returns // the updated (shortened) length of str. int Remove (char[] str, int srclen, char[] match, int matchlen) { int dst = 0, found; for (int src = 0; src < srclen; src++) { char ch = str[src]; found = 0; // Search if this char is found in match for (int i = 0; i < matchlen && !found; i++) if (match[i] == ch) found = 1; if (!found) str[dst++] = ch; } return dst; }
最后,我认为这与我们将要获得的O(n)接近.我在这里假设8位字符并构建一个查找表,因此这应该在O(n)O(m)中运行,其中m是匹配字符串的长度.
int Remove (char* str, int srclen, char* match, int matchlen) { bool found[256]; for (int i = 0; i < 256; i++) found[i] = 0; for (int i = 0; i < matchlen; i++) found[match[i]] = 1; int dst = 0; for (int src = 0; src < srclen; src++) { char ch = str[src]; if (!found[ch]) str[dst++] = ch; } return dst; }