【发布时间】:2012-01-12 22:06:23
【问题描述】:
问题是:从给定的字符串中删除指定的字符。
Input: The string is "Hello World!" and characters to be deleted are "lor"
Output: "He Wd!"
解决这个问题涉及两个子部分:
- 确定是否要删除给定字符
- 如果是,则删除该字符
为了解决第一部分,我将要删除的字符读入std::unordered_map,即我解析字符串“lor”并将每个字符插入哈希图中。稍后,当我解析主字符串时,我会查看这个以每个字符为键的 hashmap,如果返回值非零,则从字符串中删除该字符。
问题 1:这是最好的方法吗?
问题 2:哪个更适合这个问题? std::map 还是 std::unordered_map?由于我对订购不感兴趣,因此我使用了unordered_map。但是创建哈希表是否有更高的开销?在这种情况下该怎么办?使用map(平衡树)还是unordered_map(哈希表)?
现在进入下一部分,即从字符串中删除字符。一种方法是删除字符并将数据从该点向后移动一个位置。在最坏的情况下,我们必须删除所有字符,这需要 O(n^2)。
第二种方法是只将所需的字符复制到另一个缓冲区。这将涉及分配足够的内存来保存原始字符串并逐个字符地复制而忽略要删除的那些。虽然这需要额外的内存,但这将是一个 O(n) 操作。
第三种方法,从第 0 个位置开始读写,每次读取时递增源指针,仅在写入时递增目标指针。由于源指针将始终相同或领先于目标指针,因此我可以在同一个缓冲区上进行写入。这节省了内存,也是一个 O(n) 操作。我也在做同样的事情,最后调用resize 来删除额外的不必要的字符?
这是我写的函数:
// str contains the string (Hello World!)
// chars contains the characters to be deleted (lor)
void remove_chars(string& str, const string& chars)
{
unordered_map<char, int> chars_map;
for(string::size_type i = 0; i < chars.size(); ++i)
chars_map[chars[i]] = 1;
string::size_type i = 0; // source
string::size_type j = 0; // destination
while(i < str.size())
{
if(chars_map[str[i]] != 0)
++i;
else
{
str[j] = str[i];
++i;
++j;
}
}
str.resize(j);
}
问题 3: 我可以通过哪些不同的方式来改进此功能。还是我们能做到的最好?
谢谢!
【问题讨论】:
-
每个问题只问一个问题。
-
¤ Q1 和 Q2:请注意,
CHAR_BIT在大多数实现中 = 8,实际上最差是 16 位。因此,为了提高效率并且每个字符只有一个char,只需使用数组进行查找。您可以考虑使用std::bitset或std::vector<bool>。 Q3:为了可用性,制作一个类似函数的包装器。为了编码清晰,忘记烦恼string::size_type。只需使用int或ptrdiff_t。干杯, -
这个q。最好在代码审查网站上询问。
-
据我所知,您映射到的唯一值是 1。因此,为什么要使用
unordered_map,而不是unordered_set?