Вам нужен базовый случай. Поскольку n может быть нулем, & epsilon; (пустая строка) на языке. Так что это должно сказать вам, с чего начать.
Вы, кажется, думаете, что есть больше b
с, чем a
с. Но число b
с ( n ) меньше или равно числу a
с ( м ). Не может быть больше b
с. Вместо добавления одного или двух b
для каждого a
, вам нужно добавить один или два a
для каждого b
. (Но см. Ниже.)
Вы обрабатываете только те случаи, когда дополнительный a
сопряжен с одним или двумя b
с, которые, как упоминалось выше, должны быть обращены так дополнительный b
в паре с некоторыми a
с. Но в описании языка говорится m & le; 3 * n *, а не m & le; 2 * n *; дополнительный b
может быть в паре с тремя a
с.
Этот ответ предполагает, что порядок байтов WCHARS не гарантируется ...
Поскольку вы работаете в Windows, вы можете попробовать WideCharToMultiByte
для преобразования WCHAR в UTF-8, а затем используйте существующий код JNI.
Будьте осторожны при использовании WideCharToMultiByte из-за возможности переполнения буфера в параметре lpMultiByteStr
. Чтобы обойти это, вы должны вызвать функцию дважды, сначала с lpMultiByteStr
, установленным на NULL
, и cbMultiByte
, установленным на ноль - это вернет длину требуемого буфер lpMultiByteStr
без попытки записи в него. Когда у вас есть длина, вы можете выделить буфер необходимого размера и снова вызвать функцию.
Пример кода:
int utf8_length;
wchar_t* utf16 = ...;
utf8_length = WideCharToMultiByte(
CP_UTF8, // Convert to UTF-8
0, // No special character conversions required
// (UTF-16 and UTF-8 support the same characters)
utf16, // UTF-16 string to convert
-1, // utf16 is NULL terminated (if not, use length)
NULL, // Determining correct output buffer size
0, // Determining correct output buffer size
NULL, // Must be NULL for CP_UTF8
NULL); // Must be NULL for CP_UTF8
if (utf8_length == 0) {
// Error - call GetLastError for details
}
char* utf8 = ...; // Allocate space for UTF-8 string
utf8_length = WideCharToMultiByte(
CP_UTF8, // Convert to UTF-8
0, // No special character conversions required
// (UTF-16 and UTF-8 support the same characters)
utf16, // UTF-16 string to convert
-1, // utf16 is NULL terminated (if not, use length)
utf8, // UTF-8 output buffer
utf8_length, // UTF-8 output buffer size
NULL, // Must be NULL for CP_UTF8
NULL); // Must be NULL for CP_UTF8
if (utf8_length == 0) {
// Error - call GetLastError for details
}
Я нашел небольшой вопрос о метка порядка байтов. Также из этого FAQ:
UTF-16 и UTF-32 используют кодовые блоки длиной два и четыре байта соответственно. Для этих UTF есть три разновидности: BE, LE и немаркированные. Форма BE использует сериализацию байтов с прямым порядком байтов (сначала наиболее значимый байт), форма LE использует сериализацию байтов с прямым порядком байтов (сначала наименее значимый байт), а в немаркированной форме по умолчанию используется сериализация байтов с прямым порядком байтов, но может включать порядок байтов отметьте в начале, чтобы указать фактическую используемую сериализацию байтов.
Я предполагаю, что на стороне Java UTF-16 попытается найти эту спецификацию и правильно обработать кодировку. Мы все знаем, насколько опасными могут быть предположения ...
Изменить на основании комментария:
Microsoft использует UTF16 с прямым порядком байтов. Java UTF-16 пытается интерпретировать спецификацию. При отсутствии спецификации по умолчанию используется UTF-16BE. Варианты BE и LE игнорируют спецификацию.