ЗАДАНИЕ 4-6 Выходной файл представляет собой HTML-документ требуемым п

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
ЗАДАНИЕ 4-6
Выходной файл представляет собой HTML-документ, с требуемым по заданию табличным представлением данных,
либо наличием ссылок на выделяемые фрагменты. Входной файл представляет собой гипертекстовый документ (html-файл).
При выполнении работы произвести измерение зависимости «грязного» времени работы программы и ее трудоемкости
(количества базовых операций). Оценить вид полученной зависимости (линейно-логарифмическая, квадратичная).
Программа читает текст в html-файле, слова считаются одинаковыми при совпадении первых 70% букв
(% совпадения можно менять, синтаксис слов не учитывается). При форматировании текста и обнаружении слова
формируется ссылка на предыдущий абзац, где это слово встречается, либо на само слово.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct modif //Одно слово клон
{
char word[40]; //слово
int source; //Номер слова оригинала
long num; //Позиция в тексте
};
struct source
{
char word[40]; //Слово
long num; //Позиция в тексте
};
modif m[40000]; //список слов-клонов, а слов ооооч много
source s[40000]; //Список слов-оригиналов или просто уникальных (тоже не меньше)
double per=0.75; //Процент, необходимый для записи слова в клон
int slot=0,mlot=0; //Кол-во добавленных слов в список m и s
void read_tag(FILE *fin,char name[40]) //считывает весь тегдо символа > из fin и записывает его в name
{int i;
char c=0;
name[0]='\0';
for(i=0;c!='>'&&c!=' ';i++) //считываем первое слово в теге
{
fscanf(fin,"%c",&c);
if (c!='>'&&c!=' ') name[i]=c;
}
name[i-1]='\0';
while (c!='>') fscanf(fin,"%c",&c); //дочитываем до конца тега
}
void write_tag(FILE *fin,FILE *fout,char name[40]) //аналогич. read_tag но параллелльно записывает тег в out.htm
{int i;
char c=0;
name[0]='\0';
for(i=0;c!='>'&&c!=' ';i++)
{
fscanf(fin,"%c",&c);
fprintf(fout,"%c",c);
if (c!='>'&&c!=' ') name[i]=c;
}
name[i-1]='\0';
while (c!='>')
{
fscanf(fin,"%c",&c);
fprintf(fout,"%c",c);
}
}
void find_begin(FILE *fin,FILE *fout,int is_w) //ищем тег <body>, от которого начнем отчет и поиск слов, параметр is_w определяет - считывание или параллельн. запись в out
{int t=0;
char c,name[40];
while (t==0)
{
fscanf(fin,"%c",&c);
if (is_w) fprintf(fout,"%c",c);
if (c=='<') { if (is_w) write_tag(fin,fout,name);
else read_tag(fin,name);
if (strcmp("body",name)==0 || strcmp("BODY",name)==0) t=1;
}
}
}
int is_dull(char c) //смотрим, является ли символ подходящим под слово
{
return !((c>='а' && c<='я') || (c>='А' && c<='Я') || (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'));
}
int compare(source s,char word[40]) //сравниваем исходное слово и возможный клон, результат - 1 если клон, 0 если нет
{int i,sl=strlen(s.word),ml=strlen(word);
int min=(sl>ml ? sl : ml);
for (i=0;s.word[i]==word[i];i++);
if (((double) i)/((double) min) >=per ) return 1;
return 0;
}
void find_words(FILE *fin) //считывание всех слов в теге body
{long cur=0; //отвечает за номер найденного слова, нужно будет при записи
int i,t=0,need=0;
char c=' ',word[40],name[40];
word[0]='\0';
while (t==0)
{
while (is_dull(c) && c!='<' && c!='&') //считываем пока не попадется слово или тег или &*SOMETHING*, а точнее &nbsp (пробел);
{ fscanf(fin,"%c",&c);
cur++;
}
if (c=='<') { read_tag(fin,name); //если тег, то проверяем, тег ссылок или нет. Если тег ссылок, то не смотрим внутри ничего, до окончания тега
if (strcmp("a",name)==0 || strcmp("A",name)==0)
while (need==0) //если тег ссылки то считываем, пока он не закроется
{ c=0;
while (c!='<')
fscanf(fin,"%c",&c);
read_tag(fin,name);
if (strcmp("/a",name)==0 || strcmp("/A",name)==0) need=1;
} else
if (strcmp("/body",name)==0 || strcmp("/BODY",name)==0) t=1; //если body кончилось то все! считывание останавливается
need=0;
cur++;
c=0;
}
else
if (c=='&') //Если & (&nbsp), до читаем пока не кончится
while (c!=';')
{ fscanf(fin,"%c",&c);
}
else //это - если слово
{
word[0]=c;
for (i=1;!is_dull(c) || c=='_' || c=='-';i++)
{
fscanf(fin,"%c",&c);
if (!is_dull(c) ||c=='_' || c=='-') word[i]=c;
}
word[i-1]='\0'; //считали слово
for (i=0;i<slot && need==0;i++) //сравниваем слово со всеми словами
{ need=compare(s[i],word);
if (need==1) {
strcpy(m[mlot].word,word);
m[mlot].num=cur;
m[mlot].source=i;
mlot++;
}
}
if (need==0) //если оно уникально, то добавляем в этот список
{
strcpy(s[slot].word,word);
s[slot].num=cur;
slot++;
}
need=0;
}
cur++;
}
}
long find_next_min(long min,int *pos,int *type) //поиск сдледующего слова, которому надо приписать тег, pos - его номер в массиве, type - типа слова и , соо-но, типа тега
{int i,t=0;
long new_min=10000000;
for (i=0;i<slot;i++)
if (s[i].num>min && s[i].num<new_min)
{
new_min=s[i].num;
*pos=i;
*type=0;
}
for (i=0;i<mlot;i++)
if (m[i].num>min && m[i].num<new_min)
{
new_min=m[i].num;
*pos=i;
*type=1;
}
if (*type==0)//если слово не клон, но для него нету клонов, то не имеет смысла ставить тега,поэтому проверяем
for (i=0;i<mlot && t==0;i++)
if (m[i].source==*pos) t=1;
if (t==0 && *type==0) *type=2;
return new_min;
}
void write_links(FILE *fin,FILE *fout) //запись всего с ссылками
{long cur=0,min=0;
int i,t=0,need=0,pos,type;
char c=' ',word[40],name[40];
word[0]='\0';
while (t==0) // запускаем бесконечный цикл
{ if (cur>=min) min=find_next_min(min,&pos,&type); //ищем следующее слова для тега (если старое не обтежили)
while (is_dull(c) && c!='<' && c!='&') //поиск слова или тега или & (&) (пробел)
{ fscanf(fin,"%c",&c);
if (is_dull(c) && c!='<' && c!='&') fprintf(fout,"%c",c);
cur++;
}
if (cur==min && type!=2) // если дошли до слова то вставляем нужный тег
{
if (type==0) fprintf(fout,"<a name=\"__%d\">",pos);
else fprintf(fout,"<a href=\"#__%d\">",m[pos].source);
}
fprintf(fout,"%c",c); //пишем начало того слова, к которому начали пихать тег (или тупо пишем начало тега)
if (c=='<') { write_tag(fin,fout,name); //записываем тег, действия аналогичны той части, кроме параллельной записи в out
if (strcmp("a",name)==0 || strcmp("A",name)==0)
while (need==0)
{ c=0;
while (c!='<')
{
fscanf(fin,"%c",&c);
fprintf(fout,"%c",c);
}
write_tag(fin,fout,name);
if (strcmp("/a",name)==0 || strcmp("/A",name)==0) need=1;
} else
if (strcmp("/body",name)==0 || strcmp("/BODY",name)==0) t=1;
need=0;
cur++;
c=0;
}
else
if (c=='&')// считываем &
while (c!=';')
{ fscanf(fin,"%c",&c);
fprintf(fout,"%c",c);
}
else //считываем слово
{
word[0]=c;
for (i=1;!is_dull(c) || c=='_' || c=='-';i++)
{
fscanf(fin,"%c",&c);
if (!is_dull(c) || c=='_' || c=='-') fprintf(fout,"%c",c);
}
if (cur==min && type!=2) fprintf(fout,"</a>"); //пишем закрывающий тег к слову (если надо)
if (c!='<' && c!='&') fprintf(fout,"%c",c);
}
cur++;
}
}
void main()
{FILE *fin,*fout;
char c;
memset(s,0,sizeof(s));
memset(m,0,sizeof(m));
fin=fopen("input.htm","r");
fout=fopen("out.htm","w");
find_begin(fin,fout,0); //поиск body
find_words(fin);// считывание слов
fseek(fin,0,SEEK_SET);//возврат в начало
find_begin(fin,fout,1); //поиск body и копирование текста
write_links(fin,fout); //запись вместе с тегами
while (!feof(fin)) // запись всего что после body
{fscanf(fin,"%c",&c);
fprintf(fout,"%c",c);
}
}