treeh.c
3.45 KB
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
#include "treeh.h"
//initializers & destroyer
tree make_empty_tree(){
return NULL;
}
node* make_empty_node(){
node*n=malloc(sizeof(node));
n->letter='\0';
n->isEnd=0;
for(int i=0;i<NBCHAR;i++)
n->next[i]=make_empty_tree();
return n;
}
node* make_node(char l,byte end){
node*n=malloc(sizeof(node));
n->letter=l;
n->isEnd=end;
for(int i=0;i<NBCHAR;i++)
n->next[i]=make_empty_tree();
return n;
}
void delete_tree(tree t){
if(is_empty(t))return;
for(int i=0;i<NBCHAR;i++)
delete_tree(t->next[i]);
free(t);
}
//Casual functions
bool is_empty(const tree t){
return t==NULL;
}
bool is_followed(const tree t){
int i;
for(i=0;i<NBCHAR;i++){
if(t->next[i]!=NULL)
return true;
}
return false;
}
//functions is_end
bool is_end(const tree t){return t->isEnd;}
bool is_straight_end(const tree t){return t->isEnd & STRAIGHT_END;}
bool ends_with_apostrophe(const tree t){return t->isEnd & APOSTROPHE_END;}
bool is_common_end(const tree t){return t->isEnd & COMMON_END ;}
bool is_proper_end(const tree t){return t->isEnd & PROPER_END;}
bool is_acronyme_end(const tree t){return t->isEnd & ACRONYME_END;}
//needs to check c wether isalpha
int hash(char c){return c%32-1;}
bool ischar_of_word(char c){return isalpha(c) || c=='\'';}
byte end_kind(const string s){
byte endKind;
int i=1;
//1st, let's consider all letters
if(!isalpha(s[0]))
return NOT_AN_END;
if(islower(s[0])){
endKind=COMMON_END;
while(islower(s[i]));
}
else {//if isupper(s[0])
if(isalpha(s[1])){
i++;
if(islower(s[1])){
endKind=PROPER_END;
while(islower(s[i]));
}
else{//if isupper(s[1])
endKind=ACRONYME_END;
while(isupper(s[i]));
endKind=16;
}
}
}
//then let's consider the end
if(s[i]=='\0')
return endKind & STRAIGHT_END;
if(s[i]=='\''&&s[i+1]=='s'&&s[i+2]=='\0')
return endKind & APOSTROPHE_END;
return NOT_AN_END;
}
bool is_word(const byte endKind){
return endKind!=0;
}
//loading functions
bool addto_tree(tree t,const string s,char endKind){
//recursive, need to check all letter in s are alpha or "\'s"
//return wether s is already in t or not
bool ret;
if(s[0]=='\0' || s[0]=='\''){
ret=t->isEnd & endKind;
t->isEnd=t->isEnd|endKind;
return ret;
}
if(is_empty(t->next[hash(s[0])])){
t->next[hash(s[0])]=make_node(s[0],0);
addto_tree2(t->next[hash(s[0])],s+1,endKind);
return false;
}
else
return addto_tree(t->next[hash(s[0])],s+1,endKind);
}
void addto_tree2(tree t,const string s,char endKind){
//faster than addto_tree
//used when it is known the word is not yet in dictionnary
if(s[0]=='\0' || s[0]=='\''){
t->isEnd=endKind;
return;
}
t->next[hash(s[0])]=make_node(s[0],0);
addto_tree2(t->next[hash(s[0])],s+1,endKind);
}
bool addto_treeIT(tree*t,const string word ,byte endKind){
bool isIn;
int i;
//1st, let's go through the tree, until the word is not in tree
for(i=1; word[i]!='\0' && word[i]!='\'' && !is_empty(*t) ;i++){
t=&((*t)->next[hash(word[i])]);
}
printf("hi\n");
//if word is not ended at the end of the tree
if(is_empty(*t)){
isIn=false;
for(; word[i]!='\0' && word[i]!='\'';i++){
*t=make_node(tolower(word[i]),NOT_AN_END);
t=&((*t)->next[hash(word[i])]);
}
(*t)->isEnd=endKind;
printf("actions ended\n");
}
//if word is ended
else{
isIn=endKind & is_end(*t);
(*t)->isEnd=endKind | is_end(*t);
printf("action ended\n");
}
return isIn;
}