sairate c9f8710d03 sairate<sairate@sina.cn>
Signed-off-by: sairate <sairate@sina.cn>
2025-07-12 16:05:52 +08:00

221 lines
3.9 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_ST_ITEM 10000
#define MAX_CODE 100
#define MAX_LNGT 1000
#define MAX_CONC 1000
#define FC_NAME "words.inp"
#define FI_NAME "text.inp"
typedef struct st_struct
{
unsigned short code;
long max, end, start;
struct st_struct *prev, *link;
} st_item;
typedef struct ps_struct
{
unsigned short code, index;
long start;
struct ps_struct *next;
} ps_item;
st_item *head_PQ, *tail_PQ;
ps_item *head_PS[256], *tail_PS[256];
char buf[1024], *code[MAX_CODE];
int curr_char;
long pos;
unsigned short CN, length[MAX_CODE], TableSize, *first[256], n_first[256];
unsigned long FileSize, n_ps_item, m_ps_item, n_st_item, NumberOfCodes;
#ifndef __TURBOC__
unsigned long min(unsigned long a, unsigned long b)
{
if (a < b) return a; else return b;
}
#endif
void read_codes()
{
int i; unsigned char c;
FILE *fc = fopen(FC_NAME, "r"); int dummy;
fscanf(fc, " %d", &dummy);
for (i = 0; i < dummy; i++)
{
fscanf(fc, "%s", buf);
length[CN] = strlen(buf); code[CN] = strdup(buf);
c = buf[0];
first[c] = realloc(first[c], sizeof(unsigned short) * (n_first[c] + 1));
first[c][n_first[c]++] = CN++;
}
fclose(fc);
}
void insert(unsigned short curr_char, unsigned short code, unsigned short index, long start)
{
ps_item *p = (ps_item *)malloc(sizeof(ps_item));
p->code = code, p->index = index, p->start = start;
p->next = NULL;
if (tail_PS[curr_char]) tail_PS[curr_char]->next = p; else head_PS[curr_char] = p;
tail_PS[curr_char] = p;
if (++n_ps_item > m_ps_item) m_ps_item = n_ps_item;
}
void insert_all(long i)
{
int j; unsigned short *p = first[curr_char];
for (j = 0; j < n_first[curr_char]; j++) insert(curr_char, p[j], 0, i);
}
void delete_item(ps_item *prev, ps_item *curr)
{
if (prev == NULL) head_PS[curr_char] = curr->next; else prev->next = curr->next;
if (curr == tail_PS[curr_char]) tail_PS[curr_char] = prev;
free(curr);
--n_ps_item;
}
void create_link(st_item *s)
{
st_item *q = tail_PQ;
while (q)
{
if (q->end < s->start)
{
s->link = q, s->max = q->max + length[s->code];
return;
}
q = q->prev;
}
s->link = NULL, s->max = length[s->code];
}
void insert_priq(st_item *s)
{
st_item *q = tail_PQ, *prev = NULL;
while (q)
{
if (q->max > s->max)
{
prev = q; q = q->prev;
} else
{
_found:
s->prev = q;
if (prev) prev->prev = s; else tail_PQ = s;
return;
}
}
goto _found;
}
void _found_item(ps_item *p, long end)
{
st_item *s = (st_item *)malloc(sizeof(st_item));
s->code = p->code, s->start = p->start, s->end = end;
create_link(s);
insert_priq(s);
++n_st_item;
}
void search_all(long i)
{
unsigned char c;
ps_item *p = head_PS[curr_char], *prev = NULL, *curr;
while (p)
{
if ((i - p->start) > MAX_LNGT)
{
curr = p;
goto remove;
}
c = code[p->code][++p->index]; curr = p;
if (c == 0)
{
_found_item(p, i);
} else if (c != curr_char)
{
insert(c, p->code, p->index, p->start);
} else goto do_not_remove;
remove:
p = p->next;
delete_item(prev, curr);
goto _next;
do_not_remove:
prev = p;
p = p->next;
_next: ;
}
}
void delete_all()
{
int i; ps_item *curr, *head;
for (i = 0; i < 256; i++)
if (head = head_PS[i])
{
while (head)
{
curr = head;
head = head->next;
free(curr);
}
tail_PS[i] = NULL;
}
}
int search()
{
int retval = 0;
FILE *fi = fopen(FI_NAME, "r");
pos = 0; n_st_item = n_ps_item = m_ps_item = 0;
while ((curr_char = fgetc(fi)) != EOF)
{
insert_all(pos);
search_all(pos++);
if (n_st_item >= NumberOfCodes)
{
retval = 1; break;
}
}
fclose(fi), delete_all();
return retval;
}
void output()
{
FILE *fo = fopen("codes.out", "w");
fprintf(fo, "%ld\n", tail_PQ->max);
while (tail_PQ)
{
fprintf(fo, "%d %ld %ld\n", tail_PQ->code + 1, tail_PQ->start + 1, tail_PQ->end + 1);
tail_PQ = tail_PQ->link;
}
fclose(fo);
}
void main(int argc, char *argv[])
{
NumberOfCodes = MAX_ST_ITEM;
read_codes();
search();
output();
}