удалить предыдущий символ в байтовом массиве - PullRequest
2 голосов
/ 05 апреля 2011

Для данного байтового массива, в котором символы могут иметь длину 1 байт или 2 байта. Для 1-байтовых символов старший значащий бит должен быть 0. Для 2-байтового символа старший значащий бит старшего значащего байта долженбыть одним и самым значимым битом младшего значащего байта - не волнует (X).Вам дан индекс I символа в байтовом массиве.Обратите внимание, что I-1 или I + 1 могут привести вас либо к персонажу, либо к середине персонажа.Дайте логику (без кода), чтобы удалить предыдущий символ того, на который я указываю.

Ответы [ 3 ]

0 голосов
/ 05 апреля 2011

Для любого элемента array[i] вы можете определить, указывает ли i на один байтовый символ, начало 2-байтового символа или на середину 2-байтового символа, используя следующий тест:

Начиная с array[i-1] считать количество непрерывных MSB == 1.

Если array[i] предшествует число ODD, равное 1, то array[i] является серединой 2-байтового массива.

Если array[i] предшествует число ДАЖЕ, равное 1, то, если MSB(array[i]) равно 0, array[i] - однобайтовый символ, в противном случае array[i] - начало 2-байтового символа..

Поскольку мы пытаемся удалить символ непосредственно перед array[i], как только вы определите, является ли array[i] началом или серединой символа, вы должны выполнить тот же тест для * 1020.*, где x равно 1 или 2, в зависимости от того, указывает ли array[i] на начало или середину символа, соответственно.


Редактировать (Что происходит, когда arr [0] равен 1-byte, а arr [1] является 2-байтовым?):

Во-первых, подробнее о поиске смежных 1:При подсчете смежных единиц цикл останавливается, если мы достигаем массива [0] или MSB (array [j]) == 0.

odd=0
j = i
while( j && MSB(arr[j-1]) )
    j-=1
    odd^=1       <<(binary XOR)

Когда цикл завершается, нечетным будет 1, если естьнечетное количество смежных 1 и нечетное будет 0, если есть 0 или четное число смежных 1.


Если у нас есть массив с 1-байтовым символом в arr [0] и 2-байтный символ в arr [1], тогда, предположительно, у меня могут быть только значения 0, 1 или 2.

  • i = 0: цикл никогда не запускается, потому что i == 0.Мы считаем, что EVEN число предыдущих 1, потому что нечетное == 0.MSB для arr [i] равен 0, поэтому arr [i] является началом 1-байтового символа .
  • i = 1: цикл никогда не выполняется, поскольку MSB (arr [i-1]) равно 0. Мы считаем, что EVEN число смежных 1, потому что нечетное == 0.MSB для arr [i] равен 1, поэтому arr [i] является началом 2-байтового символа .
  • i = 2: цикл выполняется один раз.Мы находим ODD количество последовательных 1-х.Поскольку существует нечетное число предшествующих 1, arr [i] является серединой 2-байтового символа .
0 голосов
/ 05 апреля 2011

Похоже, вы все немного смущены?

Во-первых, что такое "середина двухбайтового символа"? Возможно, это последняя 1/3 первого персонажа и первая 1/3 второго? Нет, это чепуха. Двухбайтовый символ имеет первый и второй байт, но без «середины».

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

Но давайте предположим, что LSByte хранится по нижнему адресу, тогда задача проста. Просто проверьте самый значащий бит байта [i-1], если он установлен, тогда предыдущий символ является двухбайтовым символом, иначе это один байт. (Мы знаем, что я адресую символ, а не просто байт.)

0 голосов
/ 05 апреля 2011

Ну тогда давайте попробуем. Я предполагаю, что массив начинается с index = 0 и что мы знаем его размер. Если нет, измените цикл while в приведенном ниже коде для обратного отсчета и немного перемешайте логику.

Реальный вопрос не в том, как удалить предыдущий элемент. Выясняется, является ли данный индекс i началом символа (будь то 1- или 2-байтовый) или серединой 2-байтового. Как только мы узнаем, что удаление предыдущего элемента является тривиальным, поскольку выяснить, является ли предыдущий элемент 1- или 2-байтовым, просто.

Итак, я считаю, что это должно сработать, чтобы выяснить, какой у меня индекс. Псевдо-код:

if MSB_i == 0
{
  if MSB_(i+1) == 1
    -> Start of 2-byte char
  else
    -> Start of 1-byte char
} else
{
  if MSB_(i+1) == 0
    -> Middle of 2-byte char
  else
  {
    j = i + 1
    while (MSB_j == 1) AND (j != size)
      j++

    j = j - i
    if j modulo 2 == 1
      -> Start of 2-byte char
    else
      -> Middle of 2-byte char
}

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

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