翻译和删除一个句子中的重复项

时间:2015-07-15 03:05:11

标签: c#

我正准备面试一个问题。其中一个问题是还原一个句子。比如“它是一个令人敬畏的日子”到“令人敬畏的日子”。在此之后,他们问是否有重复,你能否删除重复,如“我很好,他是好人”,“好他是,我是我” 。

用于反转我按照方法编写的句子

public static string reversesentence(string one)
{
    StringBuilder builder = new StringBuilder();

    string[] split = one.Split(' ');
    for (int i = split.Length-1; i >= 0; i--)
    {

        builder.Append(split[i]);
        builder.Append(" ");
    }
    return builder.ToString();

}

但我没有得到删除重复的想法。我可以在这里得到一些帮助。

4 个答案:

答案 0 :(得分:10)

这有效:

public static string reversesentence(string one)
{
    Regex reg = new Regex("\\w+");
    bool isFirst = true;
    var usedWords = new HashSet<String>(StringComparer.InvariantCultureIgnoreCase);
    return String.Join("", one.Split(' ').Reverse().Select((w => {
        var trimmedWord = reg.Match(w).Value;
        if (trimmedWord != null) {
            var wasFirst = isFirst;
            isFirst = false;

            if (usedWords.Contains(trimmedWord)) //Is it duplicate?
                return w.Replace(trimmedWord, ""); //Remove the duplicate phrase but keep punctuation

            usedWords.Add(trimmedWord);

            if (!wasFirst) //If it's the first word, don't add a leading space
                return " " + w;
            return w;
        }
        return null;
    })));
}

基本上,我们根据没有标点符号的单词来判断它是否与众不同。如果它已经存在,只需返回标点符号。如果它不存在,请打印出包括标点符号在内的整个单词。

标点符号也会移除示例中的空格,这就是我们不能String.Join(" ", ...)的原因(否则结果将是good he Is , am I而不是good he Is, am I

测试:

reversesentence("I am good, Is he good").Dump();

结果:

good he Is, am I

答案 1 :(得分:9)

对于普通逆转:

String.Join(" ", text.Split(' ').Reverse())

对于重复删除的逆转:

String.Join(" ", text.Split(' ').Reverse().Distinct())

对于仅包含空格的字符串作为分隔符,两者都可以正常工作。当您引入,时,问题变得更加困难。这么多,你需要指定它应该如何处理。例如,"I am good, Is he good"应该"good he Is am I"还是"good he Is , am I"?问题中的示例更改了"Is"的大小写,并将","与其分组。这对我来说似乎不对。

答案 2 :(得分:3)

另一个答案指出使用抽象,但访调员通常希望看到实施。

对于逆转,通常的技巧是首先反转句子,然后在从左到右行进时反转每个单词。你会告诉你一个空间已经到了一个单词的末尾。 (请参阅编程访谈为此解决方案或仅谷歌它。这曾经是一个非常受欢迎的访谈问题)。你的方法有效,但因为你正在使用额外的空间(O(n))而感到不满。

要删除重复项,如果您只使用ASCII,则可以执行以下操作:

    bool[] seenChars = new bool[128];
    var sb = new StringBuilder();

    foreach(char c in stringOne)
    {
        if(!seenChars[c]){
            seenChars[c] = true;
            sb.Append(c);
        }
    }

    return sb.ToString();

这个想法是使用char的值作为数组中的索引,告诉你之前是否看过这个字符。使用这种方法,您将使用O(1)空间!

编辑:如果你想要删除单词,你可能想要使用HashSet并跳过添加它(如果它已经存在)。

答案 3 :(得分:3)

试试这个

string sentence = "I am good, Is he good";


        var words = sentence.Split(new char[]{' ',','}).Distinct(StringComparer.CurrentCultureIgnoreCase);

        var stringBuilder = new StringBuilder();

        foreach(var item in words)
        {
            stringBuilder.Append(item);
            stringBuilder.Append(" ");
        }
        Console.Write(stringBuilder);
        Console.ReadLine();