Создайте короткую удобочитаемую строку из более длинной строки

У меня есть требование заключить строку, например ...

Вы бы подумали о том, чтобы стать роботом? Вам будет предоставлена ​​бесплатная ежегодная замена масла ».

... к чему-то гораздо более короткому, но все же идентифицируемому человеком (его нужно будет найти из списка выбора - в моем текущем решении пользователи вводят произвольный заголовок для единственного цель выбора)

Я хотел бы извлечь только ту часть строки, которая формирует вопрос (если возможно), а затем как-то уменьшить ее до чего-то вроде

БудетСчитатьСтановлениеРобота

Есть ли какие-нибудь грамматические алгоритмы, которые могут мне в этом помочь? Я думаю, что может быть что-то, что позволяет выбирать только глаголы и существительные.

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


person David Neale    schedule 05.11.2010    source источник
comment
Это ВЕЛИКИЙ вопрос, который раскрывает многие проблемы при использовании эвристики по сравнению с тяжелым ИИ. Отличный вопрос.   -  person Fattie    schedule 06.11.2010


Ответы (5)


Наверное, слишком упрощенно, но я могу начать со списка «слов-заполнителей»:

var fillers = new[]{"you","I","am","the","a","are"};

Затем извлеките все, что находится перед вопросительным знаком (используя регулярное выражение, смешивание строк, что угодно), что даст вам «Не могли бы вы стать роботом?».

Затем пройдите по строке, извлекая каждое слово, считающееся заполнителем.

var sentence = "Would you consider becoming a robot";
var newSentence = String.Join("",sentence.Split(" ").Where(w => !fillers.Contains(w)).ToArray());
// newSentence is "Wouldconsiderbecomingrobot".

Паскаль, заключая каждое слово в регистр, даст желаемую строку - я оставлю это в качестве упражнения для читателя.

person Jamiec    schedule 05.11.2010
comment
@Joe Blow - спасибо за комплимент - я никогда раньше не думал о таком. Но я занимаюсь программированием уже слишком много лет. - person Jamiec; 08.11.2010
comment
В качестве дополнения к списку слов-заполнителей (правильнее было бы называть их союзами) вот сайт со списком общих слов: - esldesk.com/vocabulary/conjunctions - person David Neale; 08.11.2010

Создайте популярный веб-сайт в социальной сети. Когда пользователи хотят присоединиться к комментариям или оставить их, предложите им ввести кодировку. Капча будет состоять из сопоставления ваших сокращенных версий длинных строк с их полными версиями. Ваш алгоритм сокращения будет основан на нейронной сети или генетическом алгоритме, который обучается на основе результатов капчи.

Вы также можете продавать рекламу на сайте.

person Ben Jackson    schedule 05.11.2010

В итоге я создал следующий метод расширения, который работает на удивление хорошо. Спасибо Джо Блоу за его отличные и эффективные предложения:

    public static string Contract(this string e, int maxLength)
    {
        if(e == null) return e;

        int questionMarkIndex = e.IndexOf('?');
        if (questionMarkIndex == -1)
            questionMarkIndex = e.Length - 1;

        int lastPeriodIndex = e.LastIndexOf('.', questionMarkIndex, 0);

        string question = e.Substring(lastPeriodIndex != -1 ? lastPeriodIndex : 0, questionMarkIndex + 1).Trim();

        var punctuation =
            new [] {",", ".", "!", ";", ":", "/", "...", "...,", "-,", "(", ")", "{", "}", "[", "]","'","\""};

        question = punctuation.Aggregate(question, (current, t) => current.Replace(t, ""));

        IDictionary<string, bool> words = question.Split(' ').ToDictionary(x => x, x => false);

        string mash = string.Empty;
        while (words.Any(x => !x.Value) && mash.Length < maxLength)
        {
            int maxWordLength = words.Where(x => !x.Value).Max(x => x.Key.Length);
            var pair = words.Where(x => !x.Value).Last(x => x.Key.Length == maxWordLength);
            words.Remove(pair);
            words.Add(new KeyValuePair<string, bool>(pair.Key, true));
            mash = string.Join("", words.Where(x => x.Value)
                                       .Select(x => x.Key.Capitalize())
                                       .ToArray()
                );
        }

        return mash;
    }

Это сокращает до 15 символов:

  • Для этого нет предварительных требований - напишите эссе ...: PrereqsWriteEssay
  • Вы выбрали автомобиль: YouveSelectedCar
person David Neale    schedule 15.12.2010

Я не думаю, что существует какой-либо алгоритм, который мог бы определить, является ли каждое слово строки существительным, прилагательным или чем-то еще. Единственное решение - использовать собственный словарь: просто создайте список слов, которые нельзя идентифицировать как глаголы или существительные (I, you, they, them, his, hers, of, a, и т. Д.).

Тогда вам просто нужно оставить все слова перед вопросительным знаком, которых нет в списке.

Это просто обходной путь, и, как вы сказали, он не идеален.

Надеюсь это поможет !

person Hal    schedule 05.11.2010

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

person Craig Gidney    schedule 05.11.2010