-
Notifications
You must be signed in to change notification settings - Fork 0
/
str.c
303 lines (243 loc) · 8.97 KB
/
str.c
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
/*******************************************************************************
*
* Implementace prekladace imperativniho jazyka IFJ 09
*
* xkubis03 - Radim Kubis
* xbrene02 - Brenek Roman
* xblaho01 - Blaho Vojtech
* xlukas07 - Lukas Radek
*
*******************************************************************************/
// Knihovna pro práci s nekonečně dlouhými řetězci
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include "str.h"
#define STR_LEN_INC 8
// Konstanta STR_LEN_INC udává, na kolik bytů provedeme počateční alokaci paměti
// Pokud načítáme řetězec znak po znaku, paměť se postupně bude alokovat na
// násobky tohoto čísla
int strInit(string *s)
// Funkce vytvoří nový řetězec
{
if((s->str = (char*)malloc(STR_LEN_INC)) == NULL) // Alokace a její kontrola
return STR_ERROR; // Při neúspěšné alokaci vracím chybu
s->str[0] = '\0'; // Nastavím první znak na nulový -> prázdný řetězec
s->length = 0; // Nastavím délku řetězce na 0
s->allocSize = STR_LEN_INC; // Nastavím alokovanou velikost na STR_LEN_INC
return STR_SUCCESS; // Úspěšné vytvoření nového řetězce
}
void strFree(string *s)
// Funkce uvolní řetězec z paměti
{
free(s->str); // Uvolnění řetězce z paměti
}
void strClear(string *s)
// Funkce vymaže obsah řetězce
{
s->str[0] = '\0'; // Nastavím první znak na nulový
s->length = 0; // Nastavím délku řetězce na 0
}
int strAddChar(string *s1, char c)
// Přidá na konec řetězce jeden znak
{
if(s1->length + 1 >= s1->allocSize) // Pokud alokovaná paměť nebude stačit
{
// Realokuji paměť řetězce
if((s1->str = (char*)realloc(s1->str, s1->length + STR_LEN_INC)) == NULL)
return STR_ERROR; // Při neúspěšné realokaci vracím chybu
s1->allocSize = s1->length + STR_LEN_INC; // Přenastavím alokovanou paměť
}
s1->str[s1->length] = c; // Přidám znak c na konec řetězce
s1->length++; // Zvětším délku řetězce
s1->str[s1->length] = '\0'; // Posunu nulový znak o 1 pozici
return STR_SUCCESS; // Úspěšné přidání znaku do řetězce
}
int strCopyString(string *s1, string *s2)
// Funkce překopíruje řetězec s2 do s1
{
int newLength = s2->length; // Zjistím délku kopírovaného řetězce
if(newLength >= s1->allocSize) // Pokud alokovaná paměť nebude stačit
{
// Realokuji paměť řetězce
if((s1->str = (char*)realloc(s1->str, newLength + 1)) == NULL)
return STR_ERROR; // Při neúspěšné realokaci vracím chybu
s1->allocSize = newLength; // Přenastavím alokovanou paměť
}
strcpy(s1->str, s2->str); // Zkopíruji řetězec s2 do řetězce s1
s1->length = newLength; // Nastavím délku řetězce
return STR_SUCCESS; // Úspěšné zkopírování řetězce s2 do s1
}
int strCmpString(string *s1, string *s2)
// Funkce porovná oba řetězce a vrátí výsledek
{
return strcmp(s1->str, s2->str); // Vrací výsledek porovnání
}
int strCmpConstStr(string *s1, char* s2)
// Funkce porovná náš řetězec s konstantním řetězcem
{
return strcmp(s1->str, s2); // Vrací výsledek porovnání
}
char *strGetStr(string *s)
// Funkce vrátí textovou část řetězce
{
return s->str; // Vrací obsah řetězce
}
int strGetLength(string *s)
// Funkce vrátí délku daného řetězce
{
return s->length; // Vrací délku řetězce
}
int strConcate(string *s1, string *s2)
// Funkce přidá řetězec s2 do řetězce s1
{
int delka1, delka2, newLength, index; // Proměnné pro přidání
delka1 = s1->length; // Zjistím délku prvního
delka2 = s2->length; // Zjistím délku druhého
newLength = delka1 + delka2; // Nová délka
if(newLength >= s1->allocSize) // Pokud alokovaná paměť nebude stačit
{
// Realokuji paměť řetězce
if((s1->str = (char*)realloc(s1->str, newLength + 1)) == NULL)
return STR_ERROR; // Při neúspěšné realokaci vracím chybu
s1->allocSize = newLength; // Přenastavím alokovanou paměť
}
// Zkopíruji po znacích druhý řetězec do prvního řetězce
for(index = 0; index < delka2; index++)
{
if(strAddChar(s1, s2->str[index]) == STR_ERROR)
// Přidám znak na konec řetězce s1 a kontrola
return STR_ERROR; // Vracím chybu přidání znaku
}
s1->length = newLength; // Změním délku v prvním řetězci
return STR_SUCCESS; // Úspěšné přidání řetězce s2 do s1
}
int concateStrings(string *s1, string *s2, string *s3)
// Funkce zkopíruje řetězec s1 do s3 a přidá za něj řetězec s2
{
int delka, index; // Proměnné pro přidávání
if(strCopyString(s3,s1) == STR_ERROR) // Zkopíruji s1 do s3 a kontrola
return STR_ERROR;
delka = strGetLength(s2); // Uložím si délku druhého
for(index = 0; index < delka; index++) // Kopíruji do s3 znaky z s2
{
if(strAddChar(s3, s2->str[index]) == STR_ERROR)
// Přidám znak na konec řetězce a kontrola
return STR_ERROR;
}
return STR_SUCCESS; // Úspěšné sloučení řetězců s1 a s2 do řetězce s3
}
int strCopyChar(string *s1, char retezec[])
// Funkce zkopíruje řetězec do řetězce s1
{
int delka, x; // Proměnné pro kopírování
strClear(s1); // Vyprázdnění prvního řetězce
delka = strlen(retezec); // Zjistím délku řetězce
for(x = 0; x < delka; x++) // Procházím řetězec po znacích
{
if(strAddChar(s1, retezec[x]) == STR_ERROR)
// Přidávám znak na konec řetězce s1
return STR_ERROR;
}
return STR_SUCCESS; // Úspěšné zkopírování řetězce do řetězce s1
}
/**************************************************************************************************/
/* TODO */
/**************************************************************************************************/
int find(string *s1, string *s2) {
int i = -1, j, citac=0;
int delka_vzorku = s1->length; //delka vzorku
char *vektor = (char*)malloc((delka_vzorku+1)*sizeof(char)); //vektor, ktery bude udrzovat cisla o kolik se ma text pri vyhledavani posunout
vektor[0] = -1;
//VYTVOŘENÍ VEKTORU
//vyvoreni vektoru, pomoci ktereho se nebudeme vracet pri vyhledavani v textu zpet
for (j = 0; j < delka_vzorku; j++) {
while ((i > -1) && (s1->str[j] != s1->str[i]))
i = vektor[i];
i++;
if (s1->str[j+1] == s1->str[i])
vektor[j+1] = vektor[i];
else
vektor[j+1] = i;
}
//zvetseni cisel ve vektoru o 1
for(i =0; i < delka_vzorku; i++) {
vektor[i] = vektor[i]+1;
}
//VLASTNI HLEDANI PODRETEZCE
i=0;
j=0;
//cyklus prochazejici hlavni retezec dokud nenarazi na konec
while (s2->str[i] != '\0') {
//pokud se hledany znak retezce shoduje s 1.znakem podretezce
if(s2->str[i] == s1->str[0]) {
//prochazej podretezec dokud nedojdes na konec
while(s1->str[j] != '\0') {
//pokud se dalsi znaky podretezce a retezce rovnaji
if(s2->str[i+j] == s1->str[j]) {
citac++;
}
else {
//vzorek se nenasel - vymazou se pomocne promenne a skoci se o predem vypocitany vektor
if(citac != delka_vzorku) {
s2->str[i]=s2->str[i]+vektor[j];
j=0;
citac=0;
break;
}
}
j++;
//v pripade ze se citac rovna velikosti pole - retezce se rovnaji a vraci se pozice hledaneho podretezce v retezci
if(citac == delka_vzorku) {
free(vektor);
return (i + 1);
}
}
}
i++;
}
free(vektor);
return 0;
}
void mergessort(string *s1, int levy, int pravy){
int pivot;
if(levy<pravy){ //dokud nemame jedno cislo
pivot=(levy+pravy)/2;
mergessort(s1, levy, pivot); //rozdelime na levou
mergessort(s1, pivot+1, pravy); //a pravou cast
merge(s1, levy, pivot, pravy); //zatridime je do sebe
}
}
void merge(string *s1, int lev, int piv, int prav){
char *pomocne_pole; //pomuzeme si pomocnym polem
int i, j, k; //pomocne promenna cyklu
int levy=lev;
int pravy=prav;
int pivot=piv;
pomocne_pole=(char *) malloc((pravy+1)*sizeof(char)); //naalokujeme ono pole
for(i=levy; i<=pravy; i++){ //do pomocneho pole si prekopirujeme cele pole
pomocne_pole[i]=s1->str[i];
}
i=levy;
j=pivot+1;
k=levy;
while(i<=pivot && j<=pravy){ //nejvetsi prvek vzdycky nakopiruju do pole cisel
if(pomocne_pole[i]<=pomocne_pole[j]){ //pokud je prvek z leve poloviny mensi, ulozim ho do vyslednyho pole
s1->str[k]=pomocne_pole[i];
i++;
k++;
}
else{ //jinak tam ulozim prvek z prave poloviny
s1->str[k]=pomocne_pole[j];
j++;
k++;
}
}
while (i<=pivot){ //pokud existuje nejaky zbytek prvni pulky, dokopiruj ho do pole_cisel
s1->str[k]=pomocne_pole[i];
i++;
k++;
}
free(pomocne_pole);
}