Проблема со вторником (индексация строк на иностранном языке) - PullRequest
0 голосов
/ 05 ноября 2018

Вот, вероятно, слово с ошибкой во вторник на турецком диалекте: "Çkinci gÜn". Правописание не имеет значения для проблемы. Вот моя проблема:

s =  "Çkinci"
srev = reverse(s)
for i in 1:length(srev)
    println(srev[i])
end

работает, но

for i in 1:length(s)
    println(s[i])
end

ошибок по второй букве. Фактически, Çkinci, но не его перевернутая строка, не может быть проиндексирован буквой k в позиции 2.

Кто-нибудь знает почему? "Çk" - это escape-последовательность Unicode или что-то в этом роде?

1 Ответ

0 голосов
/ 05 ноября 2018

Джулия использует UTF-8 кодирование строк. На самом деле символ 'Ç' занимает 2 байта. Поэтому лучше написать:

julia> for v in s
           println(v)
       end
Ç
k
i
n
c
i

Подробнее об индексации строк можно прочитать здесь: https://docs.julialang.org/en/latest/manual/strings/#Unicode-and-UTF-8-1.

Причина, по которой работала версия reverse, заключается в том, что символы k, i, n, c, i все являются ASCII и занимают всего 1 байт, поэтому вы не ударили по многоборью символ байта до того, как вы закончили, и случайно length (который возвращает число символов в строке) равен 6, что соответствует позиции Ç в reverse(s). Однако на самом деле ваша строка занимает 7 байтов, что вы можете проверить, вызвав:

julia> ncodeunits(s)
7

julia> sizeof(s)
7

julia> length(s)
6

EDIT: В строках Julia при вызове getindex используется байтовая индексация, а не символьная. Это из соображений производительности, поскольку в UTF-8 стоимость штрафа за индекс n-го символа равна O (n).

Если вы хотите получить байтовый индекс из i -ого символа в вашей строке s, напишите nextind(s, 0, i). Например. s[nextind(s, 0, i)] вернет вам i -й символ в строке s. Обратите внимание, что вы должны использовать его, только если вы хотите получить один символ из строки. Если вам нужно много, более эффективно использовать итерацию по строке.

...