C ++ - Как читать символы Юникода (например, Hindi Script), используя C ++ или есть лучший способ через какой-нибудь другой язык программирования? - PullRequest
7 голосов
/ 18 февраля 2010

У меня есть файл скрипта хинди, как это:

3.  भारत का इतिहास काफी समृद्ध एवं विस्तृत है।

Я должен написать программу, которая добавляет позицию к каждому слову в каждом предложении. Таким образом, нумерация для каждой строки для конкретной позиции слова должна начинаться с 1 в скобках. Вывод должен быть примерно таким.

3.  भारत(1) का(2) इतिहास(3) काफी(4) समृद्ध(5) एवं(6) विस्तृत(7) है(8) ।(9)

Значение вышеприведенного предложения:

3.  India has a long and rich history.

Если вы наблюдаете, что у «।» (который в английском языке хинди эквивалентен «.») Также есть позиция слова, и аналогично другие специальные символы также будут, как я пытаюсь говорить об английском - хинди Выравнивание слов (часть Natural Language Processing (NLP)), так что остановка на английском языке '.' следует сопоставить с «।» на хинди. Серийные номера остаются без изменений. Я думал, что чтение за символом может быть решением. Не могли бы вы помочь мне с тем, как работать в C ++, если это легко или, если проще, можете ли вы предложить какой-то другой путь через какой-то другой язык программирования, например, Python / Perl ..?

Дело в том, что я могу получить положения слов для моего английского текста, используя C ++, так как я мог читать символ за символом, используя значения ASCII в C ++, но я не имею понятия, как сделать то же самое для текст на хинди.

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

Спасибо, что уделили время ...:)

Ответы [ 7 ]

7 голосов
/ 18 февраля 2010

Ух ты, уже 6 ответов, и ни один из них на самом деле не делает то, что хотел mgj . jkp подходит близко, но затем отбрасывает мяч, удаляя daṇḍa.

Perl на помощь. Меньше кода, меньше ошибок.

use utf8; use strict; use warnings;
use Encode qw(decode);
my $index;
join ' ', map { $index++; "$_($index)" } split /\s+|(?=।)/, decode 'UTF-8', <>;
# returns भारत(1) का(2) इतिहास(3) काफी(4) समदध(5) एव(6) विसतत(7) ह(8) ।(9)

edit: изменено на чтение с STDIN в соответствии с комментарием, добавлены лучшие практики pragmas

6 голосов
/ 18 февраля 2010

Если вы работаете в C ++ и решаете, что UTF-8 является жизнеспособной кодировкой для вашего приложения, вы можете взглянуть на utfcpp , которая является библиотекой, предоставляющей множество эквивалентов для типов, найденных в stdlib (таких как потоки и функции обработки строк), но избавляет от трудностей, связанных с кодированием переменной длины, таким как UTF8.

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

#!/usr/bin/env python
# encoding: utf-8

string = u"भारत का इतिहास काफी समृद्ध एवं विस्तृत है।"
parts = []
for part in string.split():
    parts.extend(part.split(u"।"))
print "No of Parts: %d" % len(parts)
print "Parts: %s" % parts

Выходы:

No of Parts: 9
Parts: [u'\u092d\u093e\u0930\u0924', u'\u0915\u093e', u'\u0907\u0924\u093f\u0939\u093e\u0938', u'\u0915\u093e\u092b\u0940', u'\u0938\u092e\u0943\u0926\u094d\u0927', u'\u090f\u0935\u0902', u'\u0935\u093f\u0938\u094d\u0924\u0943\u0924', u'\u0939\u0948', u'']

Кроме того, поскольку вы выполняете обработку на естественном языке, вы можете взглянуть на библиотеку NLTK для Python, в которой есть множество инструментов именно для такой работы.

4 голосов
/ 18 февраля 2010

ICU - Международные компоненты для Unicode - это поддерживаемая IBM библиотека C ++, которая начинает становиться стандартом для обработки символов всех языков. Я вижу все больше и больше проектов, использующих его. Это делает работу действительно хорошо. Вот функции (скопировать / вставить с сайта):

  • Преобразование кодовой страницы : преобразование текстовых данных в кодировку Unicode или из нее и почти в любой другой набор символов или кодировку. Таблицы преобразования ICU основаны на данных кодировки, собранных IBM в течение многих десятилетий, и являются наиболее полными из всех доступных.

  • Сопоставление : Сравните строки в соответствии с соглашениями и стандартами конкретного языка, региона или страны. Параметры сортировки ICU основаны на алгоритме сортировки Unicode плюс правила сравнения для конкретных локалей из общего хранилища данных локали, являющегося исчерпывающим источником данных этого типа.

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

  • Расчет времени : Несколько типов календарей предоставляются за пределами традиционного григорианского календаря. Предоставляется полный набор API для расчета часовых поясов.

  • Поддержка Unicode : ICU тщательно отслеживает стандарт Unicode, обеспечивая легкий доступ ко всем многим свойствам символов Unicode, нормализации Unicode, складыванию регистра и другим основным операциям, как указано в стандарте Unicode.

  • Регулярное выражение : регулярные выражения ICU полностью поддерживают Unicode, обеспечивая при этом очень конкурентоспособную производительность.

  • Bidi : поддержка обработки текста, содержащего смесь данных слева направо (английский) и справа налево (арабский или иврит).

  • Границы текста : определение местоположения слов, предложений, абзацев в пределах диапазона текста или определение мест, подходящих для переноса строк при отображении текста.

3 голосов
/ 18 февраля 2010

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

Например, если приведенное выше предложение содержится в файле utf-8 и вы используете python2.x.Если вы используете Python 3.x, он становится еще более читабельным, так как вам не нужно добавлять префиксы к юникоду в 'u' ', как в этом примере (но вам не хватает многих сторонних библиотек:

separators = [u"।", u",", u"."]
text = open("indiantext.txt").read()
#This converts the encoded text to an internal unicode object, where
# all characters are properly recognized as an entity:
text = text.decode("utf-8")

#this breaks the text on the white spaces, yielding a list of words:
words = text.split()

counter = 1

output = ""
for word in words:
    #if the last char is a separator, and is joined to the word:
    if word[-1] in separators and len(word) > 1:
        #word up to the second to last char:
        output += word[:-1] + u"(%d) " % counter
        counter += 1
        #last char
        output += word[-1] +  u"(%d) " % counter
    else:
        output += word + u"(%d) " % counter
    counter += 1

print output

Это «развернутый» пример. Поскольку вы все больше привыкаете к Python, есть более короткие способы выразить это. Вы можете изучить основы языка всего за пару часов, следуя руководству.Например, один на http://python.org сам)

3 голосов
/ 18 февраля 2010

Взгляните на http://site.icu -project.org / , библиотеку C ++ для обработки строк Unicode.

1 голос
/ 18 февраля 2010

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

FILE * fp = _wfopen( L"fname",L"r" );
wchar_t buf[1000];
while( fgetws(buf,999, fp ) )   {
    fwprintf(L"%s",buf);
}

Если с выводом все в порядке, у вас есть файл UNICODE, если он искажен, это UTF-8

Если у вас есть UTF-8, вам придется конвертировать в Unicode, чтобы упростить обработку.

// convert UTF-8 to UNICODE

    void String2WString( std::wstring& ws, const std::string& s )
    {
        ws.clear();
        int nLenOfWideCharStr = MultiByteToWideChar(CP_ACP, 0, 
            s.c_str(), s.length(), NULL, 0); 
        PWSTR pWideCharStr = (PWSTR)HeapAlloc(GetProcessHeap(), 0, 
            nLenOfWideCharStr * sizeof(wchar_t)+2); 
        if (pWideCharStr == NULL)         
            return; 
        MultiByteToWideChar(CP_ACP, 0, 
            s.c_str(), s.length(), 
            pWideCharStr, nLenOfWideCharStr);
        *(pWideCharStr+nLenOfWideCharStr ) = L'\0';
        ws = pWideCharStr ;
        HeapFree(GetProcessHeap(), 0, pWideCharStr); 

    }

    // read UTF-8
FILE * fp = fopen( "fname","r" );
char buf[1000];
std::string aline;
std::wstring wline;
std::vector< std::wstring> vline;
while( fgets(buf,999, fp ) )    {
    aline = buf;
    String2WString( wline, aline );
    vline.push_back( wline );
}

Выше предполагается, что вы находитесь в Windows. В Unix применяется та же идея, и код очень похож. Тем не менее, я не нахожу это настолько простым, поэтому я позволю эксперту UNIX предоставить подробности.

1 голос
/ 18 февраля 2010

Самый простой способ сделать обработку состоит в том, чтобы получить ваш ввод в std::wstring (который логически является массивом wchar_t). Теперь у вас все еще не будет «символов», потому что эта концепция немного сложнее на хинди. Однако у вас будут подстроки, разделенные L' ', а L '।' также будет отдельным. Например. Вы можете позвонить input.find_first_of(L" ।")

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