2014-08-31 3 views
1

я успешно использовал:Пример класса для Boost boyer_moore search corpusIter type?

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); 

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

Спасибо!

ответ

0

The first problem you will run into заключается в следующем:

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)).

Сказанное: я несколько сомневаюсь, что это фактически обеспечит вам прирост производительности по сравнению с просто преобразованием всего в нижний регистр. В таблице пропуска для char s используется оптимизация, которая использует массивы вместо unordered_map с для более быстрой индексации и меньшего количества распределений кучи. Эта оптимизация не используется для настраиваемого типа, например casechar.

+0

Большое спасибо! Я не могу преобразовать стог сена в нижний регистр - он доступен только для чтения и ОГРОМНЫЙ (я сопоставляю файлы с несколькими гигабайтами в память и ищет строки в них). Если бы я мог понять, как предоставить таблицу пропуска, я думаю, что могу получить скорость BM (вы правы, если BM использует неупорядоченную карту, это, вероятно, будет слишком медленным). В качестве альтернативы, я предполагаю, что я мог бы просто реализовать BM сам - это не так сложно, и если бы я не начал использовать материал шаблона, я бы, наверное, уже сделал! –

+0

[ворчать, ворчать] Boost проверяет как размер шаблона/корпуса, так и целостный. Поэтому, хотя sizeof (casechar) равен 1 (и, следовательно, оптимизация будет работать), не представляется возможным сделать boost :: is_integral истинным. Ну что ж. –

 Смежные вопросы

  • Нет связанных вопросов^_^