C++ - Как считать символы Unicode (Сценарий хинди для, например) использующий C++ или является там лучшим Путем через некоторый другой язык программирования?

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

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

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

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

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

3.  India has a long and rich history.

Если Вы наблюдаете '।' (который является точкой на хинди, эквивалентном a'.' на английском языке), также перебрасывается парой слов положение, и так же другие специальные символы также имели бы, поскольку я пытаюсь пойти о Выравнивании слов английского хинди (часть Обработки естественного языка (NLP)), таким образом, точка на английском языке '.' должна отобразиться на '।' на хинди. Последовательные номера остаются, поскольку это является нетронутым. Я думал, читая символ символом, могло быть решение. Вы могли помочь мне с тем, как пойти о в C++, если его легкое или, если легче могло Вы предполагать, что некоторому другому пути через некоторый другой язык программирования может понравиться Python/Perl..?

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

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

Спасибо за Ваше время... :)

7
задан Ether 18 February 2010 в 17:39
поделиться

7 ответов

Я бы серьезно посоветовал вам использовать 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 )

{ {1}}
3
ответ дан 6 December 2019 в 07:06
поделиться

Вау, уже 6 ответов, и ни один не делает то, что хотел mgj . jkp подходит близко, но затем бросает мяч, удаляя дана.

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)

редактировать: изменено на чтение из STDIN в соответствии с комментарием, добавлены прагмы передового опыта

7
ответ дан 6 December 2019 в 07:06
поделиться

При создании всего вывода можно использовать sprintf () , например,

> sprintf("%.10f",0.25)
[1] "0.2500000000"

указывает, что требуется отформатировать число с плавающей запятой с десятью десятичными точками (в % .10f f для float и .10 указывает десять десятичных точек).

Я не знаю о каких-либо способах принуждения функций более высокого уровня R печатать точное количество цифр.

Отображение 100 цифр не имеет смысла, если вы печатаете обычные цифры R, так как наилучшая точность, которую вы можете получить с помощью 64-разрядных двойников, составляет около 16 десятичных цифр (посмотрите на .Machine $ double.eps в вашей системе). Остальные цифры будут просто нежелательными.

-121--746846-

Многие старые инструменты неправильно работают, если последняя строка данных в текстовом файле не заканчивается комбинацией «новая строка» или «возврат каретки/новая строка». Они игнорируют эту строку, так как вместо этого она оканчивается на ^ Z (eof).

-121--626899-

Посмотрите на http://site.icu-project.org/ , библиотеку C++ для обработки последовательностей Юникода.

3
ответ дан 6 December 2019 в 07:06
поделиться

При создании всего вывода можно использовать sprintf () , например,

> sprintf("%.10f",0.25)
[1] "0.2500000000"

указывает, что требуется отформатировать число с плавающей запятой с десятью десятичными точками (в % .10f f для float и .10 указывает десять десятичных точек).

Я не знаю о каких-либо способах принуждения функций более высокого уровня R печатать точное количество цифр.

Отображение 100 цифр не имеет смысла, если вы печатаете обычные цифры R, так как наилучшая точность, которую вы можете получить с помощью 64-разрядных двойников, составляет около 16 десятичных цифр (посмотрите на .Machine $ double.eps в вашей системе). Остальные цифры будут просто нежелательными.

-121--746846-

Многие старые инструменты неправильно работают, если последняя строка данных в текстовом файле не заканчивается комбинацией «новая строка» или «возврат каретки/новая строка». Они игнорируют эту строку, так как вместо этого она оканчивается на ^ Z (eof).

-121--626899-

Если вы работаете в 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, которая имеет множество инструментов для этого вида работы.

6
ответ дан 6 December 2019 в 07:06
поделиться

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

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

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

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

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

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

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

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

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

4
ответ дан 6 December 2019 в 07:06
поделиться

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

1
ответ дан 6 December 2019 в 07:06
поделиться

Первое, что нужно сделать, это определить, используется ли ваш ввод в 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
ответ дан 6 December 2019 в 07:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: