颠倒和去掉句子中的重复部分

本文关键字:复部 句子 | 更新日期: 2023-09-27 18:02:39

我正在准备一个面试问题。其中一个问题是还原一个句子。比如"今天真棒"到"今天真棒"。在这之后,他们问是否有重复,你可以删除重复如"我很好,他好吗"到"他好,我好吗"。

我用下面的方法写的句子的反转

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();
}

但是我没有得到关于删除重复的想法。能帮我一下吗

颠倒和去掉句子中的重复部分

这行得通:

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

简单反转:

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"的情况,并将","与之分组。

另一个答案指向使用抽象,但面试官通常希望看到实现。

对于反转,通常的技巧是先反转句子,然后从左到右翻转每个单词。空格会告诉你,你已经读到一个单词的末尾了。(参见Programming interview Exposed找到这个问题的解决方案,或者谷歌一下。这曾经是一个非常流行的面试问题)。您的方法有效,但由于使用了额外的空间(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();

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

编辑:如果你想删除重复的单词,你可能想使用HashSet,如果它已经存在,就跳过添加它。

try this

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();