删除字符串S2中出现的字符串S1中的所有字符

时间:2013-03-10 10:39:47

标签: algorithm

给定两个字符串S1和S2,S = S1-S2被定义为在从S2获取S2中的所有字符之后的剩余字符串。如何尽快为任何给定字符串计算S1-S2?

例如:

输入:

他们是学生。

AEIOU

输出:

你的朋友。

我已经尝试过哈希映射了,但是,裁判认为它太慢了,但任何解决办法都能更快吗?

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool occur[300]={false};
int main()
{
    char str1[10002];
    gets(str1);
    char ch;
    while((ch=getchar())!='\n')
        occur[ch]=true;
    int i;
    for(i=0;i<strlen(str1);i++)
        if(occur[str1[i]])
            continue;
        else
            putchar(str1[i]);
    putchar('\n');
    return 0;
}

4 个答案:

答案 0 :(得分:2)

我认为你应该:

  1. 创建包含S2中所有字符的HashSet S
  2. 使用在您通过S1迭代不在S
  3. 中时附加字符的列表
  4. 从列表中构建字符串(Python中的“.join(list ..)”
  5. 我认为没有更快的方法..你可以将S1分成N个部分并处理这个并行 - 这是我看到的唯一优化...

    至于你的代码 - 不要在循环条件下使用strlen!见:strlen: how does it work?。只需迭代所有字符,直到你得到'\ 0'字符或计算strlen一次并加上你在循环条件中使用的变量...

答案 1 :(得分:1)

如果您可以将问题限制为一个小字母(例如英文字符),您可以创建一个字母大小的bool数组。

1个数组查找将比散列或遍历二叉树快得多。

答案 2 :(得分:0)

最快和最简单的方法之一可能是使用正则表达式替换。请参阅下面的示例python代码。

如果您不能使用正则表达式,则需要在输入字符串的每个字符上放置一个循环。由于您在考虑每个字符,因此任何算法都至少为O(n)。这意味着加速实现的唯一方法是减少检查是否需要将字符复制到输出以及将实际副本复制到输出所花费的时间。由于我不知道你使用的语言,我将在python中给出一个简短的实现。这使用python set类,如果值在集合中,则允许进行常量时间检查。示例代码如下所示。

import re

def remove1(string, chars):
    return re.sub("[%s]"%chars, "", string)

def remove2(string, chars):
    chars = set(chars)
    res = ""
    for c in string:
        if c not in chars:
            res += c

    return res

import unittest

class TestRemove(unittest.TestCase):
    def test_removeVowels1(self):
        self.assertEqual("Thy r stdnts.", remove1("They are students.","aeiou"))

    def test_removeVowels1(self):
        self.assertEqual("Thy r stdnts.", remove2("They are students.","aeiou"))

if __name__=="__main__":
    unittest.main()

注意:如果您使用的是C ++之类的语言,并且您知道输入仅限于8位值,则最快的方法是使用直接地址;即使用字符值作为数组索引。

答案 3 :(得分:0)

从技术上讲,Hashmap解决方案是O(n)+ O(m),n是句子的长度,m是禁止的字符数。

就我而言,当你拥有来判断是否保留或丢弃该字符时,这个速度就越快。此外,你至少运行一次所有禁止的字符以便了解它们。

但是,我可以想象存在更有效的解决方案,即更少的开销。但说实话,我想不出一个。

更新(这是最简单的,但它是O(n * m)。但是,它可能比其他短字符串方法更快):

foreach (c in sentence) 
  if (forbiddenChars.IndexOf(c) == -1) 
    Console.Write(c);