Подсчитайте количество слов в NSString - PullRequest
9 голосов
/ 03 марта 2011

Я пытаюсь реализовать функцию подсчета слов для моего приложения, которое использует UITextView.

Между двумя словами в английском языке есть пробел, поэтому подсчитать количество слов в предложении на английском языке очень просто.Проблема возникает при подсчете китайских и японских слов, потому что обычно во всем предложении нет места.

Я проверил три разных текстовых редактора в iPad, которые имеют функцию подсчета слов, и сравнил их с MS Words.

Например, вот серия японских иероглифов, означающих идею мира: 世界 (мир)) ('s) ア イ デ ア (идея)

世界 の ア イ デ ア

1)Страницы для iPad и MS Words считают каждый символ одним словом, поэтому он содержит 7 слов.

2) Текстовый редактор iPad P *** считает все как одно слово -> Они просто использовали пробел для разделения слов.

3) Текстовый редактор iPad i *** считает их тремя словами -> Я считаю, что они использовали CFStringTokenizer с kCFStringTokenizerUnitWord, потому что я мог получить тот же результат)

Я исследовалИнтернет и подсчет слов в Pages и MS Words кажутся правильными, потому что каждый китайский символ имеет значение.

Я не смог найти ни одного класса, которыйсчитает такие слова, как Pages или MS Words, и было бы очень трудно реализовать его с нуля, потому что, помимо японского и китайского, iPad поддерживает много разных иностранных языков.

Я думаю, что CFStringTokenizer с kCFStringTokenizerUnitWordхотя лучший вариант.

Есть ли способ подсчитать слова в NSString, такие как Pages и MSWords?

Спасибо

Ответы [ 7 ]

3 голосов
/ 09 марта 2011

Я рекомендую продолжать использовать CFStringTokenizer.Потому что это функция платформы, поэтому будет обновляться при обновлении платформы.И многие люди в Apple работают с трудом, чтобы отразить реальные культурные различия.Что трудно понять обычным разработчикам.

Это сложно, потому что это по сути не проблема программирования.Это культурно-языковая проблема человека.Вам нужен специалист по человеческому языку для каждой культуры.Для японцев вам нужен специалист по японской культуре.Однако я не думаю, что японцам нужно серьезно относиться к подсчету слов, потому что, как я слышал, сама концепция слова не так важна в японской культуре.Сначала вы должны определить понятие слова.

И я не могу понять, почему вы хотите принудительно ввести понятие количество слов в число символов .Слово кандзи, которое вы создали.Это равносильно подсчету universe как 2 слова путем деления на uni + verse по значению.Даже не логика.Разделять слово по значению иногда совершенно неправильно и бесполезно по определению слова.Потому что определение самого слова различно по культурам.В моем корейском языке слово - это просто формальная единица, а не смысловая единица .Идея о том, что каждое слово соответствует каждому значению, верна только в римских символьных культурах.

Просто предоставьте еще одну функцию, например подсчет символов для пользователей в Восточной Азии, если вы считаете, что это нужно.И подсчет символов в строке Unicode очень прост с помощью метода -[NSString length].

Я - говорящий на корейском языке (возможно, не в вашем случае :), и во многих случаях мы подсчитываем символы вместо слов.На самом деле, Я никогда не видел, чтобы люди считали слова за всю мою жизнь. Я смеялся над функцией подсчет слов в MS word, потому что я догадывался, что никто не будет ее использовать.(Однако теперь я знаю, что это важно в культуре римских персонажей.) Я использовал функцию подсчета слов только один раз, чтобы знать, что это действительно работает :) Я считаю, что это похоже на китайский или японский.Возможно, японские пользователи используют подсчет слов, потому что их основной алфавит похож на римские символы, которые не имеют понятия о композиции.Однако они интенсивно используют иероглифы Kanji, которые полностью сочетают в себе систему символов.

Если вы делаете так, чтобы функция подсчета слов работала очень хорошо на тех языках (которые используют люди, даже не чувствует необходимости разбивать предложения наменьшие формальные единицы!), трудно представить кого-то, кто его использует.И без лингвистического специалиста эта функция не должна корректироваться.

2 голосов
/ 03 марта 2011

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

В начале строки вы начинаете с одного символа. Это слово? Это может быть слово типа «А», но оно также может быть частью слова типа «AN» или «АНАЛОГ». Таким образом, решение о том, что это слово, должно быть принято с учетом всей строки. Вы должны рассмотреть следующие символы, чтобы узнать, можете ли вы сделать другое слово, начиная с первого символа, следующего за первым словом, которое, по вашему мнению, вы могли найти. Если вы решите, что слово «A», а у вас осталось «NALOG», то вскоре вы обнаружите, что больше нет слов, которые можно найти. Когда вы начинаете находить слова в словаре (см. Ниже), вы понимаете, что делаете правильный выбор, где разбивать слова. Когда вы перестаете находить слова, вы знаете, что сделали неправильный выбор, и вам нужно вернуться назад.

Большая часть этого - наличие словарей, достаточных для того, чтобы содержать любое слово, с которым вы можете столкнуться. Английским ресурсом будет TWL06 или SOWPODS или другие словари скрэббл, содержащие много непонятных слов. Для этого вам нужно много памяти, потому что если вы сравните слова с простым массивом, содержащим все возможные слова, ваша программа будет работать невероятно медленно. Если вы анализируете свой словарь, сохраняете его как список и воссоздаете словарь, ваша проверка будет достаточно быстрой, но для этого потребуется гораздо больше места на диске и больше места в памяти. Один из этих больших словарей скрэббл может расшириться до 10 МБ с фактическими словами в качестве ключей и простым NSNumber в качестве заполнителя для значения - вам все равно, какое значение, просто то, что ключ существует в словаре, который говорит вам, что слово признается действительным.

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

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

Другим способом будет использование правил естественного языка - например, «A» и «NALOG» могут выглядеть хорошо, потому что согласный следует за «A», но «A» и «ARDVARK» будут исключены, потому что это будет правильно для слова, начинающегося с гласного, чтобы следовать «AN», а не «A». Это может быть настолько сложным, насколько вам нравится, - я не знаю, упрощается ли это на японском языке или нет, но, безусловно, есть общие глагольные окончания, такие как "ma su".

(редактировать: началось вознаграждение, я хотел бы знать, как лучше всего это сделать, если не так.)

1 голос
/ 11 марта 2011

Если вы используете iOS 4, вы можете сделать что-то вроде

__block int count = 0;
[string enumerateSubstringsInRange:range
                           options:NSStringEnumerationByWords
                        usingBlock:^(NSString *word,
                                     NSRange wordRange,
                                     NSRange enclosingRange,
                                     BOOL *stop)
    {
        count++;
    }
];

Больше информации в Ссылка на класс NSString .

Также есть Сессия WWDC 2010 , номер 110, о продвинутой обработке текста, которая объясняет это, около 10 минут или около того.

0 голосов
/ 14 марта 2011

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

Обратите внимание, что на самом деле это не будет эффективно, так как вам нужно разобрать каждое предложение, прежде чем можно будет сосчитать слова.

Я бы порекомендовал использовать компилятор парсера, а не собирать его самостоятельно, чтобы начать, по крайней мере, вы можете сосредоточиться на выполнении грамматики, а не на создании парсера самостоятельно. Это не эффективно, но оно должно выполнить работу.

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

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

0 голосов
/ 11 марта 2011

Не носитель китайского / японского языка, но вот мои 2цента.

У каждого китайского иероглифа есть значение, но понятие слова - это комбинация букв / символов для представления идеи, не так ли?

В этом смысле, вероятно, 3 слова в"sekai no aidia" (или 2, если вы не учитываете такие частицы, как NO / GA / DE / WA и т. д.).То же, что и английский - «идея мира» - это два слова, а «идея мира» - 3, и давайте забудем о необходимом «хе-хе».

При этом подсчет слов не так полезен вРимский язык, на мой взгляд, похож на то, что упоминал Эонил.Вероятно, лучше посчитать количество символов для этих языков. Посмотрите на носителей китайского / японского языка и посмотрите, что они думают.

Если бы я это сделал, я бы разбил строку на строки с пробелами и частицами (по крайней мере, для японского, корейского и жетонов.Не уверен насчет китайского ..

0 голосов
/ 09 марта 2011

Я думаю, что CFStringTokenizer с kCFStringTokenizerUnitWord является лучшим вариантом.

0 голосов
/ 08 марта 2011

Просто используйте метод длины:

[@"世界のアイデア" length];  // is 7

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

...