/
Article assistant
515 lines (514 loc) · 12.3 KB
/
Article assistant
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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
#define MAXSIZE 1000 //字符空间的最大容量
#define MAXLEN 20 //单词的最大长度
#define MAXNUM 16 //一行中单词最多个数
#define FALSE 0
#define TRUE 1
#include<stdio.h>
#include<stdlib.h>
#include<bits/stdc++.h>
/*堆结构的定义 */
typedef struct{
char stores[MAXSIZE]; int freep; /*当前可用空间开始位置 */
}HeapSpace;
HeapSpace sp;
/*单词数据类型定义*/
typedef struct{ //单词在堆中的位置描述
int stadr; /*单词在对空间中的开始位置 */
int len; /*单词长度 */
}WordType;
typedef struct{ //单词描述
char ch[MAXLEN]; /*单词字符串 */
int size; /*单词长度 */
}Sequence;
/*有序表类型定义*/
typedef WordType ElemType;
typedef struct NodeType
{ //单词有序表结点定义
ElemType data;
struct NodeType *next;
}NodeType,*LinkType;
typedef struct
{ //单词有序表定义
LinkType head; /*有序表头指针 */
LinkType tail; /*有序表尾指针 */
int size; /*有序表结点个数 */
}OrderList;
/* 记录一行中匹配成功单词在目标词汇表中的位置*/
typedef struct
{
int eqelem[MAXNUM]; /*单词在目标词汇表中的位置 */
int last; /*匹配成功单词的个数 */
}EqelemList;
/* 文件测试相关的数据类型定义*/
typedef struct Node
{ //单词在文件中的位置
int elem; /*被测单词在文件中的行号 */
struct Node *next;/* 指向下一个行号结点的指针 */
}Node,*Link;
typedef struct
{ //单词统计分析记录结构定义
WordType data; /*被测试的单词 */
int count; /*在文件中出现的次数 */
Link Next; /*记录出现的所有行号的脸表头指针 */
}HeadNode;
/* 文本文件测试结果记录定义*/
typedef HeadNode ResultType[MAXNUM];
typedef int status;
/* 定义新单词函数 */
status NewWord(WordType *nw,Sequence cha)
{
int i,k;
if(sp.freep+cha.size>=MAXSIZE)
{
printf("Heap Full!\n");
getchar();
return 0;
}
else
{
i=sp.freep;
sp.freep=sp.freep+cha.size;
for(k=0;k<cha.size;k++)
sp.stores[i+k]=cha.ch[k];
nw->stadr=i;
nw->len=cha.size;
return 1;
}
}
/*回到最初空间*/
void NewLength(OrderList rs)
{
int m=0;
LinkType p,q;
p=rs.head->next;
while(p)
{
if(m<=p->data.stadr)
{
m=p->data.stadr;
q=p;
}
p=p->next;
}
sp.freep=m+q->data.len;
}
/* 复制单词信息函数 */
void CopyWord(WordType *nw,WordType oldw)
{
nw->stadr=oldw.stadr;
nw->len=oldw.len;
}
/* 单词比较函数 */
int WordCmp(WordType wd1,WordType wd2)
{
int k,si,sj,m;
si=wd1.stadr;sj=wd2.stadr;
for(k=0;k<=wd1.len&&k<=wd2.len;k++)
{
m=fabs((float)(sp.stores[si+k]-sp.stores[sj+k]));
if(m!=0&&m!=32)
break;
if(k==wd1.len||k==wd2.len)
break;
}
if(wd1.len==wd2.len)
{
if(k==wd1.len)
return 0;
else if(sp.stores[si+k]>sp.stores[sj+k])
return 1;
else return -1;
}
else if(wd1.len<wd2.len)
{
if(k==wd1.len)
return -1;
else if(sp.stores[si+k]>sp.stores[sj+k])
return 1;
else return -1;
}
else
{
if(k==wd2.len)
return 1;
else if(sp.stores[si+k]>sp.stores[sj+k])
return 1;
else return -1;
}
}
/* 打印单词函数 */
void PrintWord(WordType wd)
{
int i;
for(i=0;i<wd.len;i++)
putchar(sp.stores[wd.stadr+i]);
}
/* 结点生成函数 */
status MakeNode(LinkType *p,ElemType e)
{
*p=(LinkType)malloc(sizeof(NodeType));
if(!(*p))
return FALSE;
(*p)->data.stadr=e.stadr;
(*p)->data.len=e.len;
(*p)->next=NULL;
return TRUE;
}
/* 有序表初始化函数 */
status InitList(OrderList *L)
{
ElemType wd;
wd.len=0;
if(MakeNode(&(L->head),wd))
{
L->tail=L->head;
L->head->next=NULL;
L->size=0;
return TRUE;
}
else
{
L->head=NULL;
return FALSE;
}
}
/* 撤销有序表函数 */
void DestroyList(OrderList *L)
{
LinkType p,q;
p=L->head;
while(p)
{
q=p;
p=p->next;
free(q);
}
L->head=L->tail=NULL;
}
/* 有序表查找函数 */
status LocateElem(OrderList L,ElemType e,LinkType *q)
{
LinkType pre,p;
p=L.head->next;
while(p)
{
if(WordCmp(p->data,e)==0)
{
*q=p;
return TRUE;
}
if(WordCmp(p->data,e)==-1)
*q=p;
p=p->next;
}
return FALSE;
}
/* 有序表插入函数 */
void InsertAfter(OrderList *L,LinkType q,LinkType s)
{
if(L->head&&q&&s)
{
s->next=q->next;
q->next=s;
if(L->tail==q)
L->tail=s;
L->size++;
}
}
/* 表匹配函数 */
void ListCompare(OrderList La,OrderList Lb,EqelemList *s)
{
int pos,n;
LinkType pa,pb;
if(La.head&&Lb.head)
{
pa=La.head->next;
pb=Lb.head->next;
s->last=pos=0;
while(pa&&pb)
{
n=WordCmp(pa->data,pb->data);
if(n==0)
{
s->eqelem[s->last++]=pos++;
pa=pa->next;
pb=pb->next;
}
else if(n==-1)
{
pa=pa->next;
pos++;
}
else pb=pb->next;
}
}
}
/* 判表空函数 */
status ListEmpty(OrderList * L)
{
if(L->size==0)
return TRUE;
return FALSE;
}
int ListLength(OrderList* L)
{ /*返回判表长度 */
if(L->head ==L->tail)
return 0;
else return L->size ;
}
/* 字符判断函数 */
int feoln(FILE *f)
{
char cha;
cha=fgetc(f);
if(cha=='\n')
return(TRUE);
ungetc(cha,f);
return FALSE;
}
/* 读取单词函数 */
void GetAWord(FILE *f,Sequence *st)
{
char ch;
int k=0;
ch=fgetc(f);
while(ch==' ')
{
ch=fgetc(f);
if(ch=='\n')
break;
}/* 去掉空格和回车 */
if(ch=='\n')
{
ungetc(ch,f);
ch=' ';
}/* 最后一个为回车键,文件指针回指 */
while(((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))&&!feof(f))
{
st->ch[k]=ch;
ch=fgetc(f);
k++;
}
if(ch=='\n')
ungetc(ch,f);
st->size=k;
}
/* 读取文件当前行单词函数 */
status ExtractWord(FILE *f,OrderList *ta)
{
int i;
char lendc;
Sequence str;
WordType nwd;
LinkType p,q;
LinkType s;
InitList(ta);
p=ta->head;
q=ta->head;
for(i=0;!feof(f);i++)
{
if(feoln(f))
return(TRUE);
GetAWord(f,&str);/* 从文件中读出一个单词 */
NewWord(&nwd,str);/* 将单词放入堆存储空间 */
MakeNode(&s,nwd);/* 生成一个单词节点 */
if(ta->head->next)
{
while(p!=NULL&&WordCmp(p->data,s->data)==-1)
{
q=p;
p=p->next;
}
p=q;
}
InsertAfter(ta,p,s);
p=ta->head->next;
q=ta->head;
}
}
/* 文件单词匹配函数 */
status match(FILE *f,OrderList pat,ResultType rs)
{
int i,k,linenum,failed,fsp;
OrderList sa;
EqelemList eqlist;
Link p,q;
if(!pat.head)
return FALSE;
linenum=1;
while(!feof(f))
{
ExtractWord(f,&sa);
ListCompare(pat,sa,&eqlist);
i=0;
if(eqlist.last)
while(i<eqlist.last)/* 计算出单词出现行号以及一行出现次数 */
{
p=(Link)malloc(sizeof(Node));
p->next=rs[eqlist.eqelem[i]].Next;
rs[eqlist.eqelem[i]].Next=p;
p->elem=linenum;
rs[eqlist.eqelem[i]].count++;
i++;
}/* 内层while*/
linenum++;/* 行数加 1*/
DestroyList(&sa);
NewLength(pat); }/* 外层 while*/
fclose(f);
return TRUE;
}
/* 初始化文件函数 */
status Initialization(FILE **fr)
{
char FileName[30];
printf("Input file name:");
do
{
scanf("%s",FileName);
}
while(strlen(FileName)==0);
*fr=fopen(FileName,"r");
if(*fr)
{
printf("file open!\n");
return TRUE;
}
else
{
printf("file not open!\n");
return FALSE;
}
}
/* 输入统计的词集函数 */
void InputWord(OrderList *pt)
{
char cc;
int i=0;
Sequence ws;
LinkType p,q,s;
WordType nwd;
InitList(pt);
p=pt->head;
q=pt->head;
while((cc=getchar()))
{
if(cc!=' '&&cc!='\n')
{
ws.ch[i]=cc;
i++;
}
else
{
ws.size=i;
NewWord(&nwd,ws);
MakeNode(&s,nwd);
if(pt->head->next)
{
while(p!=NULL&&WordCmp(p->data,s->data)==-1)
{
q=p;
p=p->next;
}
p=q;
}
InsertAfter(pt,p,s);
p=pt->head->next;
q=pt->head;
i=0;
}
if(cc=='\n')
return;
}
}
/* 初始化统计结果表函数 */
void InitRList(ResultType rs,OrderList pat)
{
int k;
LinkType p;
p=pat.head->next;
for(k=0;k<pat.size;k++)
{
CopyWord(&rs[k].data,p->data);
rs[k].Next=NULL;
rs[k].count=0;
p=p->next;
}
}
/* 输出统计结果函数 */
void OutResult(ResultType rslist,int n)
{
int i,j;
Link p;
for(i=0;i<n;i++)
{
printf("The word ");
PrintWord(rslist[i].data);
printf(" appeared in the file %d times",rslist[i].count);
if(rslist[i].count!=0)
{
printf(" and on ");
p=rslist[i].Next;
for(j=0;j<rslist[i].count;j++)
if(j<rslist[i].count-1)
{
printf("%d,",p->elem);
p=p->next;
}
else
printf("%d\n",p->elem);
}
else printf("\n");
}
}
/* 撤销统计结果数据空间函数 */
void FreeResult(ResultType rs,int n)
{
int i;
Link p,q;
for(i=0;i<n;i++)
if(rs[i].Next!=NULL)
break;
if(rs[i].Next!=NULL)
for(i=0;i<n;i++)
{
p=rs[i].Next;
while(p)
{
q=p;
p=p->next;
free(q);
}
rs[i].Next=NULL;
rs[i].count=0;
}
else
return;
}
int main()
{
int flag=0;
sp.freep=0; /*sp 为全局变量 */
FILE *fp=NULL;
OrderList *pt;
pt=(OrderList *)malloc(sizeof(OrderList));
pt->head=NULL;
ResultType rs;
do{
Initialization(&fp); /*输入文件名并打开文件 */
printf("input search words\n");
getchar();
InputWord(pt); /*输入查询的单词 */
if(fp&&!ListEmpty(pt))
{
InitRList(rs,*pt);
if(match(fp,*pt,rs))
OutResult(rs,ListLength(pt));
else
DestroyList(pt);
}
printf("Do you want to have a seach again?(YES--1/NO--0)\n");
scanf("%d",&flag);
fflush(stdin);
}while(flag);
return 0;
}