将整个字符串向左移动一个位置将使该算法的时间复杂度变为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
}
}
我在这里假设这些是以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;
}
string.translate(None, "aeiou")
。 (B):告诉面试官切换到Perl并使用$string =~ s/[^aeiou]//g
。 - kennytmTheta(n)
。您有m
个这样的模式要检查(特殊情况:模式长度== 1)。因此,基本上,您正在查看Theta(mn)运行时。 - dirkgently