/* * BorderArrayNaive.h * * Created on: 5. 11. 2014 * Author: Jan Travnicek */ #ifndef _ARBOLOGY_BORDER_ARRAY_NAIVE_H_ #define _ARBOLOGY_BORDER_ARRAY_NAIVE_H_ #include <alib/vector> #include <global/GlobalData.h> #include "SubtreeJumpTable.h" #include <tree/ranked/PrefixRankedBarNonlinearPattern.h> #include <tree/ranked/PrefixRankedBarPattern.h> #include <tree/ranked/PrefixRankedNonlinearPattern.h> #include <tree/ranked/PrefixRankedPattern.h> namespace tree { namespace properties { /** * Computation of BCS table for BMH from MI(E+\eps)-EVY course 2014 * To get rid of zeros in BCS table we ignore last haystack character */ class BorderArrayNaive { template < class SymbolType > static bool matches ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ); template < class SymbolType > static bool matches ( const tree::PrefixRankedBarPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ); template < class SymbolType > static bool matches ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ); template < class SymbolType > static bool matches ( const tree::PrefixRankedPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ); public: /** * Search for pattern in linear string. * @return set set of occurences */ template < class SymbolType > static ext::vector < size_t > construct ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ); /** * Search for pattern in linear string. * @return set set of occurences */ template < class SymbolType > static ext::vector < size_t > construct ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ); /** * Search for pattern in linear string. * @return set set of occurences */ template < class SymbolType > static ext::vector < size_t > construct ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern ); /** * Search for pattern in linear string. * @return set set of occurences */ template < class SymbolType > static ext::vector < size_t > construct ( const tree::PrefixRankedPattern < SymbolType > & pattern ); }; template < class SymbolType > bool BorderArrayNaive::matches ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ) { unsigned i = 0; while ( offset < stop && i < pattern.getContent ( ).size ( ) ) if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) { i++; offset++; } else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( ) [ i ] ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( ) [ offset ] ) ) ) { i = subtreeJumpTable[i]; offset = subtreeJumpTable[offset]; } else { return false; } return true; } template < class SymbolType > ext::vector < size_t > BorderArrayNaive::construct ( const tree::PrefixRankedBarNonlinearPattern < SymbolType > & pattern ) { ext::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern ); ext::vector < size_t > res; for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ ) res.push_back ( 0 ); res[0] = -1; for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) { int min = i; for ( unsigned j = 1; j < i; j++ ) if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) { min = j; break; } res[i] = i - min; } /* if ( common::GlobalData::verbose ) common::Streams::log << res << std::endl;*/ return res; } template < class SymbolType > bool BorderArrayNaive::matches ( const tree::PrefixRankedBarPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ) { unsigned i = 0; while ( offset < stop && i < pattern.getContent ( ).size ( ) ) if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) { i++; offset++; } else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) ) { i = subtreeJumpTable[i]; offset = subtreeJumpTable[offset]; } else { return false; } return true; } template < class SymbolType > ext::vector < size_t > BorderArrayNaive::construct ( const tree::PrefixRankedBarPattern < SymbolType > & pattern ) { ext::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern ); ext::vector < size_t > res; for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ ) res.push_back ( 0 ); res[0] = -1; for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) { int min = i; for ( unsigned j = 1; j < i; j++ ) if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) { min = j; break; } res[i] = i - min; } /* if ( common::GlobalData::verbose ) common::Streams::log << res << std::endl;*/ return res; } template < class SymbolType > bool BorderArrayNaive::matches ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ) { unsigned i = 0; while ( offset < stop && i < pattern.getContent ( ).size ( ) ) if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) { i++; offset++; } else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( ) [ i ] ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( ) [ offset ] ) ) ) { i = subtreeJumpTable[i]; offset = subtreeJumpTable[offset]; } else { return false; } return true; } template < class SymbolType > ext::vector < size_t > BorderArrayNaive::construct ( const tree::PrefixRankedNonlinearPattern < SymbolType > & pattern ) { ext::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern ); ext::vector < size_t > res; for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ ) res.push_back ( 0 ); res[0] = -1; for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) { int min = i; for ( unsigned j = 1; j < i; j++ ) if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) { min = j; break; } res[i] = i - min; } if ( common::GlobalData::verbose ) common::Streams::log << res << std::endl; return res; } template < class SymbolType > bool BorderArrayNaive::matches ( const tree::PrefixRankedPattern < SymbolType > & pattern, const ext::vector < int > & subtreeJumpTable, int stop, int offset ) { unsigned i = 0; while ( offset < stop && i < pattern.getContent ( ).size ( ) ) if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) { i++; offset++; } else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) ) { i = subtreeJumpTable[i]; offset = subtreeJumpTable[offset]; } else { return false; } return true; } template < class SymbolType > ext::vector < size_t > BorderArrayNaive::construct ( const tree::PrefixRankedPattern < SymbolType > & pattern ) { ext::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern ); ext::vector < size_t > res; for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ ) res.push_back ( 0 ); res[0] = -1; for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) { int min = i; for ( unsigned j = 1; j < i; j++ ) if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) { min = j; break; } res[i] = i - min; } if ( common::GlobalData::verbose ) common::Streams::log << res << std::endl; return res; } } /* namespace properties */ } /* namespace tree */ #endif /* _ARBOLOGY_BORDER_ARRAY_NAIVE_H_ */