Пример класса для Boost boyer_moore поиска типа corpusIter?

Я успешно использовал:

boost::algorithm::boyer_moore_search<const char *,const char *>( haystack, haystack_end, needle, needle_end )

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

class casechar {
public:
char ch;
// other stuff...it's not right, but I don't think the compiler is even getting this far
} ;

class caseiter : public std::iterator<random_access_iterator_tag,casechar> {
const casechar *ptr;
public:
// various iterator functions, but not enough of them, apparently!
} ;

boost::algorithm::boyer_moore_search<const caseiter,const char *>( HaYsTaCk, HaYsTaCk_EnD, needle, needle_end );

Компилятор (g ++ на OSX) жалуется на попытку создания хеша<casechar>Я думаю, для некоторой внутренней вещи BM. Я потерялся в лабиринте шаблона<twisty_passages, all_different>, Могу ли я навязать кому-то немного направления? Я подозреваю, что мне просто нужно предоставить определенные реализации в casechar и / или caseiter, но я не знаю, какие именно.

Спасибо!

1

Решение

Первая проблема, с которой вы столкнетесь это:

BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));

Это требует, чтобы типы значений итератора для шаблона и итератора для корпуса были одного типа. Другими словами, вам нужно будет использовать casechar для шаблона, а также.

Вот что я бы сделал:

  • Напиши casecharс заказным operator == и т. д. для сравнения без учета регистра.
  • Не нужно писать пользовательский итератор. const casechar * является вполне приемлемым итератором произвольного доступа.
  • Напиши std::hash<casechar> специализация. Эта специализация, вероятно, должна просто возвращать что-то вроде std::hash<char>()(std::tolower(ch)),

Тем не менее, я несколько сомневаюсь, что это на самом деле принесет вам выигрыш в производительности по сравнению с простым преобразованием всего в нижний регистр. Пропустить стол для chars использует оптимизацию, которая использует массивы вместо unordered_maps для более быстрой индексации и меньшего количества выделенной памяти. Эта оптимизация не используется для пользовательского типа, такого как casechar,

0

Другие решения