Skip to content

Instantly share code, notes, and snippets.

@sgfsdfgsdfhgsfhdfhj
Last active June 18, 2016 15:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgfsdfgsdfhgsfhdfhj/c346201b591eeae7c3a5e399a6db5c16 to your computer and use it in GitHub Desktop.
Save sgfsdfgsdfhgsfhdfhj/c346201b591eeae7c3a5e399a6db5c16 to your computer and use it in GitHub Desktop.
my_sort_strstr
/* мой strstr стал ещё лучше
среднее быстрее чем в обычном strstr
Минимальное k+N/k
А максимальное кажется примерно такое:
k+N*M*... или вроде того, очень много, но оно редкое
когда str1 состояит из подстрок одинаковых символов почти равных str2
Подумаю, как от этого избавиться.
*/
char * my_strstr(const char * str1,
const char * str2,size_t slen)
{
//максимум max_len в этой реализации должен быть 254
//так как 0x00 используется что-бы отметить
//неиспользуемые
const unsigned char max_len = 140;
unsigned char *s1, *s2;
if ( !*str2 )
return((char *)str1);
//Первый
unsigned char index_header_first[256];
//Последний
unsigned char index_header_end[256];
//Индекс следующего на следующий
unsigned char next_char[max_len];
//Индекс в строке
unsigned char sorted_index[max_len];
memset(index_header_first,0x00,sizeof(unsigned char)*256);
memset(index_header_end,0x00,sizeof(unsigned char)*256);
memset(next_char,0x00,sizeof(unsigned char)*max_len);
memset(sorted_index,0x00,sizeof(unsigned char)*max_len);
char *cp2 = (char*)str2;
unsigned char v;
unsigned int len =0;
//можно убрать current_ind или len, но я не буду пока
unsigned char current_ind = 1;
while((v=*cp2) && (len<max_len)){
if(index_header_first[v] == 0)
{
index_header_first[v] = current_ind;
index_header_end[v] = current_ind;
sorted_index[current_ind] = len;
}
else
{
unsigned char last_ind = index_header_end[v];
next_char[last_ind] = current_ind;
index_header_end[v] = current_ind;
sorted_index[current_ind] = len;
}
current_ind++;
len++;
cp2++;
}
if(len > slen){
return NULL;
}
unsigned char *cp = (unsigned char *) str1;
unsigned char *cp_end= cp+slen;
while (cp<cp_end)
{
//v= *cp;
unsigned char ind = *cp;
if( ind = index_header_first[ind] )
{
do
{
//Позиция в строке
unsigned char pos_in_len = sorted_index[ind];
s1 = cp - pos_in_len;
s2 = (unsigned char*)str2;
if(s1>=str1)
{
while (*s2 && !(*s1^*s2) )
s1++, s2++;
if (!*s2)
return(cp-pos_in_len);
}
}
while(ind = next_char[ind]);
}
cp+=len;
}
return(NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment