Реализация функции преобразования символов - PullRequest
0 голосов
/ 17 ноября 2009

Мне нужно реализовать функцию преобразования кодировки символов в C ++ или C (наиболее желательно) из пользовательской схемы кодирования (для поддержки нескольких языков в одной кодировке) в UTF-8.

Наше кодирование довольно случайное, оно выглядит так

Из-за случайности этого отображения я думаю использовать std :: map для отображения нашего кодирования в UTF и наоборот на двух разных картах и ​​использовать эти карты для преобразования. Является ли их какая-либо оптимизированная структура данных или способ сделать это.

Ответы [ 4 ]

2 голосов
/ 17 ноября 2009

Хеш-таблица, безусловно, будет самым быстрым решением.

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

Я пару раз использовал gperf , но я предлагаю вам проверить Боб Дженкинс отличную страницу о хешировании (и минимальное идеальное хеширование )

2 голосов
/ 17 ноября 2009

Если ваши кодовые точки смежны, просто создайте большой массив char * и выполните перевод, используя его. Я не очень понимаю, что вы имеете в виду под кодовой точкой UTF-8. UTF-8 имеет представления, а Unicode имеет кодовые точки. Если вам нужны кодовые точки, используйте массив целых чисел.

const int mycode_to_unicode [] = {
   0x00ff,
   0x0102,
   // etc.
 };

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

Чтобы пойти другим путем, нужно просто создать массив структур того же размера, что-то вроде

struct {
   int mycode;
   int unicode;
};

копирование ключей массива в mycode и значений в unicode и запуск его через qsort с функцией, которая сравнивает значения unicode, затем используя bsearch с той же функцией для перехода из кодовой точки в вашу кодировку.

Предполагается, что вы хотите использовать C.

1 голос
/ 17 ноября 2009

Не уверен, что я понимаю вопрос, но если оно не слишком велико для отображения 1: 1, возможно, стоит использовать предварительно инициализированную структуру (в зависимости от кода вы можете написать программу, которая однажды будет выдавать содержимоетаблица инициализации):

struct MAP { int from, to; };

MAP somemapping[MAXMAP]= {
    { 0x101,  0x01 },
    { 0x102,  0x02 },

};

Использование bsearch () было бы достаточно быстрым способом поиска;

Если код чрезвычайно чувствителен к производительности, вы можете создать таблицу поиска на основе индекса:

int lookup[65536];


/* init build lookup table once */
init() 
{
  for (int i= 0; i<MAXMAP; i++) {
     lookup[somemapping[i].from]= somemapping[i].to;
  }
}



foo() 
{
  ....
   /* quick lookup */
  to= lookup[from];
  ....
}
1 голос
/ 17 ноября 2009

Поскольку вы строите постоянные отображения заранее и используете их только для поиска, хеш-таблица может быть более идеальной, чем std :: map. В стандарте C ++ нет реализации хеш-таблиц, но доступно много бесплатных реализаций, как на C, так и на C ++.

Это реализации C:

http://www.cl.cam.ac.uk/~cwc22/hashtable/

http://wiki.portugal -a-programar.org / с: фрагмент кода: hash_table_c

Хеш-таблицы Glibc .

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