Сторнирование и удаление дубликатов в предложении

Я готовлюсь к собеседованию. Один вопрос заключается в том, чтобы отменить предложение. Например, "это потрясающий день", чтобы "день был потрясающим". После этого они спросили, есть ли дублирование, можете ли вы удалить дублирование, такое как "Я хорошо, хорошо ли он", "хорошо, что он есть, я",.

для отмены предложения я написал следующий метод

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

}

Но я не получаю идеи по удалению дублирования. Могу ли я помочь здесь.

Ответ 1

Это работает:

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 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

Ответ 2

Для простого разворота:

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" и группирует с ним ",". Это кажется мне неправильным.

Ответ 3

Другой ответ указывает на использование абстракций, но интервьюеры обычно хотят видеть реализацию.

Для разворота обычный трюк состоит в том, чтобы сначала отменить предложение, а затем отменить каждое слово при движении слева направо. В каком пространстве вы скажете, что вы дошли до конца слова. (См. "Программирование интервью", выставленных для решения этого или просто Google. Это был вопрос ОЧЕНЬ популярного интервью). Ваш подход работает, но на него нахмурился, потому что вы используете дополнительное пространство (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 и пропустите добавление, если оно уже существует.

Ответ 4

попробуйте это

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