<email@andreas-eberle.com>
<http://www.gnu.org/licenses/>
#ifndef EBERLE_INSSORT_H_
#define EBERLE_INSSORT_H_
#include <iostream>
#include "../tools/stringtools.h"
namespace eberle_inssort_lcp
{
using namespace stringtools;
typedef unsigned char* string;
static inline
void inssort_lcp(string* strings, const LcpStringPtr& out, size_t length)
{
string* output = out.strings;
lcp_t* lcps = out.lcps;
for (size_t n = 0; n < length; n++)
{
const string candidateText = strings[n];
lcp_t candidateLcp = 0;
size_t insIdx = 0;
for (; insIdx < n; insIdx++)
{
lcp_t currLcp = lcps[insIdx];
if (candidateLcp == currLcp)
{
string s1 = candidateText + candidateLcp;
string s2 = output[insIdx] + candidateLcp;
while (*s1 != '\0' && *s1 == *s2)
s1++, s2++;
const lcp_t lcp = s1 - candidateText;
if (*s1 <= *s2)
{
lcps[insIdx] = lcp;
break;
}
else
{
candidateLcp = lcp;
}
}
else if (candidateLcp > currLcp)
{
break;
}
}
for (size_t i = n; i > insIdx; i--)
{
output[i] = output[i - 1];
lcps[i] = lcps[i - 1];
}
lcps[insIdx] = candidateLcp;
output[insIdx] = candidateText;
}
}
static inline
void inssort_lcp(string* strings, const LcpCacheStringPtr& out, size_t length)
{
inssort_lcp(strings, (const LcpStringPtr&) out, length);
out.calculateCache();
}
static inline
void eberle_lcp_inssort(string *strings, size_t n)
{
lcp_t* lcps = new lcp_t[n];
LcpStringPtr output(strings, lcps, n);
inssort_lcp(strings, output, n);
#ifdef EBERLE_INSSORT_CHECK_LCPS
std::cout << "Checking LCPs" << std::endl;
stringtools::verify_lcp(output.strings, output.lcps, n, 0);
#endif
delete[] lcps;
}
static inline
void eberle_lcp_inssort_cache(string *strings, size_t n)
{
lcp_t* lcps = new lcp_t[n];
char_type* cache = new char_type[n];
LcpCacheStringPtr output(strings, lcps, cache, n);
inssort_lcp(strings, output, n);
#ifdef EBERLE_INSSORT_CHECK_LCPS
std::cout << "Checking LCPs" << std::endl;
stringtools::verify_lcp_cache(output.strings, output.lcps, output.cachedChars, n, 0);
#endif
delete[] lcps;
delete[] cache;
}
CONTESTANT_REGISTER(eberle_lcp_inssort, "eberle/lcp_insertion_sort", "LCP aware inssertion sort by Andreas Eberle")
CONTESTANT_REGISTER(eberle_lcp_inssort_cache, "eberle/lcp_insertion_sort_cache", "LCP aware insertion sort with cached characters calculation by Andreas Eberle")
}
#endif