
Čer
9
9
Základy programování (IZP) – Projekt č. 1 a 2
První projekt se věnuje kompresi a dekompresi řetězců, druhý projekt je zaměřen na matematické operace.
Hodnocení:
1. projekt – 4.5/5
2. projekt – 9/10
Je zakázáno kopírovat tyto zdrojové kódy! Veškeré projekty procházejí kontrolou na plagiátorství, takže se nepokoušejte použít mé kódy a to ani tak, že přepíšete názvy proměnných, nepomůže to. Výsledkem opisování je předvolání před komisi a většinou také odebrání zápočtu, takže vzhledem k tomu, že jsem nezpochybnitelným autorem následujících kódů, uškodíte pouze sami sobě.
Projekt č. 1
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 | /* Projekt c.1 - komprese a dekomprese textu * Autor: Milan Seitler, xseitl01@fit.vutbr.cz * Skupina: 36 (1BIB) * Datum: 2010/10/25 * Nazev souboru: proj1.c * Popis programu: Program komprimuje vstupni text tim, ze opakujici se bloky o delce N zapisuje ve tvaru "pocet_opakovani""retezec". Takto vytvoreny text lze opet pomoci programu dekomprimovat zpet do puvodni podoby. V programu jsou vyuzita dve pole o delce N + 1 (k indexaci neni pouzita 0), ktera nejprve naplnime znaky. Pote je porovname, pokud jsou stejna, zvetsime pocet opakovani, pokud pocet dosahne 9, vypiseme pocet opakovani, vypiseme opakujici se znaky a opet nacteme dalsi znaky. Pokud se pole nerovnaji zjistime, kolik znaku bylo shodnych a pote vsechny neshodne znaky v prvnim poli posuneme na zacatek a doplnime je shodnymi znaky z druheho pole, to same provedeme s druhym polem, jen nove znaky donacteme ze vstupu. Takto postupne prochazime dokud na vstupu neni EOF, pripadny chybny znak. Pri dekomprimaci nacitame znaky, pokud je na vstupu cislo, pak vypiseme nasledujicich N znaku, pokud je mezi nimi cislo nebo nepovoleny znak, vypiseme chybovou hlasku a program se ukonci. */ #include <stdio.h> /* vstup a vystup */ #include <stdlib.h> /* obecne funkce */ #include <ctype.h> /* funkce pro testovani znaku - isdigit, isprint atd. */ #include <string.h> /* funkce strcmp */ #include <errno.h> /* chybove kody errno */ /* definice chybovych kodu */ #define K_OK 0 /* bez chyb */ #define K_CHYBNY_PARAMETR 1 /* chybny parametr prikazove radky */ #define K_CHYBNY_VSTUP 2 /* chybny vstup */ #define K_NEDOSTATEK_PAMETI 3 /* nedostatek pameti */ /*definice minima a maxima opakovani */ #define OPAK_MIN 1 #define OPAK_MAX 9 /* vytvorime funkcni prototypy */ void dekomprimuj(int c); void komprimuj(int c); void napoveda(void); int dopln_pole(char *pole, char *pole2, int delka, int stejne, int *kon); /* posune druheho pole a donacte znaku ze vstupu */ int nacti_pole(char *pole, char *pole2, int delka, int *kon); /* nacte N znaku ze vstupu */ int porovnej_pole(char *pole, char *pole2, int delka); /* porovna obe pole */ void posun_pole(char *pole, char *pole2, int delka, int stejne); /* posune prvni pole a donacte do nej znaky z druheho pole */ void vycisti_pole(char *pole, int delka); /* vsem prvkum v poli nastavi hodnotu 0 */ void vypis_chybu(int kod); /* podle zadaneho parametru vypise chybovou hlasku a ukonci program */ void vypis_obe(char *pole, char *pole2, int delka, int *kon); /* vypise obe pole najednou, u prvniho testuje, zda je cele naplnene */ void vypis_opakovani(char *pole, int delka, int pocet_op); /* vypise pocet opakovani a opakujici se znaky */ void vypis_pole(char *pole, int delka, int *kon); /* vypise pouze jedno pole */ void zkopiruj_pole(char *pole, char *pole2, int delka); /* zkopiruje pole2 do pole */ int main(int argc, char *argv[]) { unsigned int n = 0; char *stop = NULL; /* pokud je pocet parametru 2 (argc == 3) a prvnim parametrem je -c, -h, nebo -d a N je vetsi nez nula a mensi nebo rovno UINT_MAX + 1 tak spusti prislusnou funkci, jinak vypise chybovou hlasku */ if(argc == 3) { if(argv[2][0] > '0' && argv[2][0] <= '9') { n = strtoul(argv[2], &stop, 10); /* osetruje parametry typu "3ab" */ if(errno == ERANGE || isalpha(*stop) || ispunct(*stop)) vypis_chybu(K_CHYBNY_PARAMETR); } else { vypis_chybu(K_CHYBNY_PARAMETR); } if(strcmp("-d", argv[1]) == 0) { dekomprimuj(n); } else if(strcmp("-c", argv[1]) == 0) { komprimuj(n); } else { vypis_chybu(K_CHYBNY_PARAMETR); } } else if(argc == 2) { if(strcmp("-h", argv[1]) == 0) { napoveda(); } else { vypis_chybu(K_CHYBNY_PARAMETR); } } else { vypis_chybu(K_CHYBNY_PARAMETR); } return 0; } void dekomprimuj(int n) { char *znaky; int c, i, j, pocet; /* dynamicky vytvorime pole, testujeme, zda byla pridelena pamet */ znaky = (char*) malloc(n * sizeof (char)); if(znaky == NULL) { vypis_chybu(K_NEDOSTATEK_PAMETI); } vycisti_pole(znaky, n); do { c = getchar(); /* kontrolujeme, zda je na vstupu cislo a zda jej nasleduje povoleny znak, jinak vypiseme chybovou hlasku */ if(isdigit(c)) { pocet = c - '0'; for(i = 0; i < n; i++) { c = getchar(); if((isprint(c) || isspace(c)) && !isdigit(c)) { znaky[i] = c; } else { free(znaky); vypis_chybu(K_CHYBNY_VSTUP); } } /* vypis N znaku */ for(i = 0; i < pocet; i++) { for(j = 0; j < n; j++) { c = znaky[j]; putchar(znaky[j]); } } } else { /* jinak tiskneme posloupnost znaku */ if(isprint(c) || isspace(c)) putchar(c); } } while(c != EOF); free(znaky); } void komprimuj(int n) { int c = 0, stejne = 0, pocet_op = 1, konec = 0; char *znaky1, *znaky2; /* dynamicky vytvorime pole, testujeme, zda byla pridelena pamet */ znaky1 = (char*) malloc((n + 1) * sizeof (char)); if(znaky1 == NULL) { vypis_chybu(K_NEDOSTATEK_PAMETI); } znaky2 = (char*) malloc((n + 1) * sizeof (char)); if(znaky2 == NULL) { vypis_chybu(K_NEDOSTATEK_PAMETI); } vycisti_pole(znaky1, n); vycisti_pole(znaky2, n); /* nacteme N prvku do obou poli, pokud je v prvnim EOF, do druheho jiz nenacitame */ c = nacti_pole(znaky1, znaky1, n, &konec); if(c != EOF) c = nacti_pole(znaky2, znaky1, n, &konec); /* porovname pole, pokud jsou stejna, zvetsime pocet opakovani, jinak pole posuneme, napr. pri vstupu labloslen udelame z |lab|los| |blo|sle|"*/ while(c != EOF) { stejne = porovnej_pole(znaky1, znaky2, n); if(stejne == n) { if(pocet_op < OPAK_MAX) { pocet_op++; } else { /* pokud se pocet opakovani rovna 9, vypiseme opakovani */ vypis_opakovani(znaky1, n, pocet_op); pocet_op = 1; } c = nacti_pole(znaky2, znaky1, n, &konec); } else { /* pokud se pole nerovnaji, ale pocet opakovani je vetsi nez 1, vypiseme opakovani, druhe pole zkopirujeme do prvniho, do druheho nacteme N znaku */ if(pocet_op > OPAK_MIN) { vypis_opakovani(znaky1, n, pocet_op); pocet_op = 1; zkopiruj_pole(znaky1, znaky2, n); c = nacti_pole(znaky2, znaky1, n, &konec); } else { /* pokud je pocet opakovani roven 1, posuneme pole, viz radek 158 */ posun_pole(znaky1, znaky2, n, stejne); c = dopln_pole(znaky1, znaky2, n, stejne, &konec); } } } /* vypis znaku pri dosazeni EOF - bud vypiseme opakovani a zbytek druheho pole nebo obe pole, az po EOF pripadne posledni nevypsany znak */ if(pocet_op > OPAK_MIN) { vypis_opakovani(znaky1, n, pocet_op); vypis_pole(znaky2, n, &konec); } else { vypis_obe(znaky1, znaky2, n, &konec); } free(znaky1); free(znaky2); } void napoveda(void) { printf("------------------------------------------------\n" "Program na kompresi a dekompresi vstupniho textu \n" "\n" "Autor: Milan Seitler, 1BIB, sk. 36\n" "\n" "Spusteni programu: ./proj -c N / -d N / -h\n" "-c - komprese\n" "-d - dekomprese\n" "-h - napoveda\n" "N - parametr, ktery urcuje delku opakujicich se bloku, musi byt vetsi nez nula a" " mensi nez UINT_MAX (4,294,967,295)\n" "\n" "Vstupni text lze zadavat bud primo z klavesnice nebo jej presmerovat z prikazove" " radky pomoci <<< \"blabla\", pripadne ze souboru: < vstup.txt\n" "Podobne lze smerovat take vystup do souboru > vystup.txt\n" "\n" "Program zpracovava vstupni text a hleda opakujici se bloky o delce N, ktere pri " "kompresi zapisuje ve tvaru 3abc. Takto vytvoreny text lze zpetne dekomprimovat, " "tedy z 3hop bude pri N = 3 hophophop.\n" "------------------------------------------------\n"); } int dopln_pole(char *pole, char *pole2, int delka, int stejne, int *kon) { /* v druhem poli se posouvaji znaky, doplnuji se dalsimi ze vstupu, parametr delka urcuje delku obou poli, parametr stejne urcuje, kolik znaku bylo pri porovnani stejnych, do promenne kon se ulozi pozice pripadneho EOF */ int i, j, x = 0; stejne++; /* znaky, ktere se nerovnaly, posuneme na zacatek pole */ for(i = 1; i <= (delka - stejne); i++) { pole2[i] = pole2[i + stejne]; } /* donacteme zbytek znaku ze vstupu, pri nepovolenem znaku vypiseme chybu */ j = delka - stejne + 1; for(i = 1; i <= stejne; i++) { if((x = getchar()) != EOF) { if(isprint(x) || isspace(x)) { pole2[j] = x; j++; } else { free(pole); free(pole2); vypis_chybu(K_CHYBNY_VSTUP); } } else { /* do promenne kon ulozime pozici posledniho znaku, v pripade za nacteme nepovoleny znak */ *kon = j; break; } } return x; } int nacti_pole(char *pole, char *pole2, int delka, int *kon) { /* do pole a pole2 (o velikosti delka) se nacitaji nove znaky, pozice pripadneho EOF se ulozi do kon */ int x, i; /* nacteme N znaku ze vstupu, pokud je na vstupu nepovoleny znak, vypiseme chybu */ for(i = 1; i <= delka; i++) { if((x = getchar()) != EOF) { if(isprint(x) || isspace(x)) { pole[i] = x; } else { free(pole); free(pole2); vypis_chybu(K_CHYBNY_VSTUP); } } else { /* do promenne kon ulozime pozici posledniho znaku, v pripade za nacteme nepovoleny znak */ *kon = i; break; } } return x; } int porovnej_pole(char *pole, char *pole2, int delka) { /* porovnava pole a pole2 (velikost "delka") */ int i, stejne = 0; /* porovname znaky na i-te pozici v obou polich, vracime pocet stejnych znaku */ for(i = 1; i <= delka; i++) { if(pole[i] == pole2[i]) { stejne++; } else { break; } } return stejne; } void posun_pole(char *pole, char *pole2, int delka, int stejne) { /* v bufferu pole se posouvaji znaky, ktere se doplni znaky z bufferu pole2 parametr delka urcuje velikost poli, parametr stejne urcuje, kolik bylo pri porovnani stejnych znaku */ int i, j; stejne++; /* nejprve vypiseme shodne znaky */ for(i = 1; i <= stejne; i++) putchar(pole[i]); /* pote zbytek posuneme na zacatek pole */ for(i = 1; i <= (delka - stejne); i++) { pole[i] = pole[i + stejne]; } /* a donacteme znaky z druheho pole */ j = delka - stejne + 1; for(i = 1; i <= stejne; i++) { pole[j] = pole2[i]; j++; } } void vycisti_pole(char *pole, int delka) { int i; for(i = 0; i < delka; i++) pole[i] = 0; } void vypis_chybu(int kod) { switch(kod) { case 1: fprintf(stderr, "\n\nChybny parametr prikazove radky! Program bude ukoncen. \n\n"); exit(1); break; case 2: fprintf(stderr, "\n\nChybny znak na vstupu! Program bude ukoncen. \n\n"); exit(2); break; case 3: fprintf(stderr, "\n\nNedostatek volne pameti! Program bude ukoncen. \n\n"); exit(3); break; default: break; } } void vypis_obe(char *pole, char *pole2, int delka, int *kon) { int i; /* vypise obe pole (o velikosti "delka"), bud cele nebo po pozici EOF ci nepovoleneho znaku */ for(i = 1; i <= delka; i++) { if(pole[i] != 0) putchar(pole[i]); } for(i = 1; i < *kon; i++) { putchar(pole2[i]); } } void vypis_opakovani(char *pole, int delka, int pocet_op) { int i = 0; /* vypiseme pocet opakovani a blok textu o delce N (delka) */ putchar(pocet_op + '0'); for(i = 1; i <= delka; i++) { putchar(pole[i]); } } void vypis_pole(char *pole, int delka, int *kon) { int i; for(i = 1; i < *kon; i++) { putchar(pole[i]); } } void zkopiruj_pole(char *pole, char *pole2, int delka) { int i = 0; for(i = 1; i <= delka; i++) { pole[i] = pole2[i]; } } |
Projekt č. 2
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 | /* Projekt c.2 - iteracni vypocty * Autor: Milan Seitler, xseitl01@fit.vutbr.cz * Skupina: 36 (1BIB) * Datum: 2010/11/19 * Nazev souboru: proj2.c * Popis programu: program provadi celkem 4 pocetni operace: obecny logaritmus, hyperbolicky tangens, vazeny aritmeticky a vazeny kvadraticky prumer. Program spoustime s temito parametry -h - napoveda --logax sigdig a - obecny logaritmus o zakladu a, pocet platnych cislic vysledku urcuje sigdig --tanh sigdig - hyperbolicky tangens, pocet platnych cislic vysledku urcuje sigdig --wam - vazeny aritmeticky prumer --wqm - vazeny kvadraticky prumer Podrobny popis viz. dokumentace k projektu */ #include <errno.h> #include <ctype.h> #include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define K_OK 0 /* bez chyb */ #define K_CHYBNY_PARAMETR 1 /* chybny parametr prikazove radky */ #define K_CHYBNY_VSTUP 2 /* chybny vstup */ /* urcime si kody jednotlivych funkci, podle kterych budeme volat */ #define LOGAX 0 #define TANH 1 #define WAM 2 #define WQM 3 double wam(double cislo, double vaha); // vypocet vazeneho aritmetickeho prumeru double wqm(double cislo, double vaha); // vypocet vazeneho kvadratickeho prumeru double muj_sinh(double cislo, double eps); // vypocet sinh (pouzito ve vypoctu tanh) double muj_cosh(double cislo, double eps); // vypocet cosh (pouzito ve vypoctu tanh) double muj_tanh(double cislo, double eps); // vypocet tanh podle vzorce sinh/cosh double muj_ln(double cislo, double eps); // vypocet prirozeneho logaritmu double muj_logax(double cislo, double eps, double a); // vypocet logaritmu podle vzorce loga x = ln x / ln a double preved_eps(int sigdig); // prevede sigdig na epsilon void vypis_chybu(int kod); // vypise chybove hlaseni podle zadaneho kodu chyby void napoveda(void); void nacti_parametry(int argc, char *argv[]); const double IZP_E = 2.7182818284590452354; // e const double log_horni_hranice = 2; // horni hranice pro konvergenci funkce muj_ln const double log_dolni_hranice = 0.1; // dolni hranice pro konvergenci funkce muj_ln // slouzi pro ukladani mezisouctu statistickych funkci struct stat_hodnoty { double citatel; double jmenovatel; } stat_h; // struktura slouzi k nacteni a osetreni parametru ve funkci nacti_parametry struct parametry { double eps, zaklad_log; int sigdig, spust; // do promenne spust ukladame kod funkce, kterou chceme spustit, ten nacteme z prikazove radky char *stop; // tento pointer pouzijeme pri kontrole, zda parametry sigdig a "a" byly cislo } param; int main(int argc, char *argv[]) { int temp1 = 0, temp2 = 0; // promenne pro uchovani vysledku funkce scanf a promenna chyba pro pripadny vypis nan double cislo1 = 0, cislo2 = 0, vysledek = 0; nacti_parametry(argc, argv); // zpracujeme parametry ve specialni funkci, ulozi se do struktury param while((temp1 = scanf("%le", &cislo1)) != EOF) { // nacita hodnoty dokud na vstup neprijde EOF ci neplatny znak if(temp1 == 0) { // pokud nacte neplatny znak, "preskoci" jej, aby se program nezacyklil scanf("%*s"); vysledek = NAN; printf("%.10e\n", vysledek); vypis_chybu(K_CHYBNY_VSTUP); } switch(param.spust) { // podle kodu spusti prislusny program case 0: vysledek = muj_logax(cislo1, param.eps, param.zaklad_log); break; case 1: vysledek = muj_tanh(cislo1, param.eps); break; case 2: temp2 = scanf("%le", &cislo2); // pokud jde o statistickou funkci, nacteme druhe cislo if(temp2 == 0) { // pokud neni nacteno cislo, nahlasime chybu (dale vypiseme nan, ukoncime program) vysledek = NAN; printf("%.10e\n", vysledek); vypis_chybu(K_CHYBNY_VSTUP); break; } vysledek = wam(cislo1, cislo2); break; case 3: temp2 = scanf("%le", &cislo2); if(temp2 == 0) { vysledek = NAN; printf("%.10e\n", vysledek); vypis_chybu(K_CHYBNY_VSTUP); break; } vysledek = wqm(cislo1, cislo2); break; default: break; } printf("%.10e\n", vysledek); } return EXIT_SUCCESS; } double wam(double cislo, double vaha) // pocita vazeny aritmeticky prumer { if(vaha < 0) { // zapornou vahu oznacime jako naplatny vstup cislo = NAN; } stat_h.citatel += cislo * vaha; // predchozi vypocty mame ulozeny ve strukture stat_h.jmenovatel += vaha; return stat_h.citatel / stat_h.jmenovatel; } double wqm(double cislo, double vaha) // pocita vazeny kvadraticky prumer { if(vaha < 0) { cislo = NAN; // zapornou vahu oznacime jako naplatny vstup } stat_h.citatel += (cislo * cislo) * vaha; // predchozi vypocty mame ulozeny ve strukture stat_h.jmenovatel += vaha; return sqrt(stat_h.citatel / stat_h.jmenovatel); } double muj_sinh(double cislo, double eps) { double soucet = cislo; double soucet_p = 0; double clen = cislo; // prvni clen je x double citatel = 0, jmenovatel = 0; int i = 3; double mocnina = cislo * cislo; // pro urychleni vypoctu spocitame mocninu "predem" citatel = cislo * cislo * cislo; jmenovatel = 3 * 2; clen = citatel / jmenovatel; // rucne spocitame druhy clen soucet_p = soucet; soucet = soucet + clen; // a soucet prvnich dvou clenu // pocitame pomoci tayorova rozvoje: x + (x ^ 3) / 3! + (x ^ 5) / 5! + ... while(fabs(soucet - soucet_p) > eps) { i += 2; citatel *= mocnina; // predchozi citatel nasobime hodnotou cislo^2, ziskame tak cislo^i // v jmenovateli pridavame postupne cleny faktorialu o dva vyssi, tj. napr. 5! = 5 * 4 * 3! jmenovatel *= (i * (i - 1)); clen = citatel / jmenovatel; soucet_p = soucet; // ulozime predchozi soucet, abychom mohli testovat, zda se provede dalsi opakovani cyklu soucet += clen; } return soucet; } double muj_cosh(double cislo, double eps) { double soucet = 1; double soucet_p = -1; double clen = 1; // prvni clen je 1 int i = 0; double citatel = 1, jmenovatel = 1; double mocnina = cislo * cislo; // pro urychleni vypoctu spocitame mocninu "predem" // pocitame pomoci tayorova rozvoje: 1 + (x ^ 2) / 2! + (x ^ 4) / 4! + ... while(fabs(soucet - soucet_p) > eps) { i += 2; citatel *= mocnina; // predchozi citatel nasobime hodnotou cislo^2, ziskame tak cislo^i // v jmenovateli pridavame postupne cleny faktorialu o dva vyssi, tj. napr. 6! = 6 * 5 * 4! jmenovatel *= (i * (i - 1)); clen = citatel / jmenovatel; soucet_p = soucet; // ulozime predchozi soucet, abychom mohli testovat, zda se provede dalsi opakovani cyklu soucet += clen; } return soucet; } double muj_tanh(double cislo, double eps) { double vysl, sinh_v, cosh_v; sinh_v = muj_sinh(cislo, eps); cosh_v = muj_cosh(cislo, eps); if(sinh_v == INFINITY) { // pokud je vysledek sinh (staci testovat pouze jednu fci) inf, vracime 1 vysl = 1; } else if(sinh_v == -INFINITY) { // pokud je -inf, vracime -1 vysl = -1; } else { // jinak spocitame vysledek jako podil sinh / cosh vysl = sinh_v / cosh_v; } return vysl; } double muj_ln(double cislo, double eps) // pocitame prirozeny logaritmus pomoci rozvoje 2 * (((x - 1) / (x + 1)) + (1 / 3 * (x - 1 / x + 1)^3) + ...) // tento vypocet je nejefektivnejsi pro hodnoty v rozsahu <0.1, 2>, proto hodnoty mimo tento interval do nej musime prevest { double soucet = 0; double clen = 0; double mocnina = 0; int i = 1, pocet_v = 0, pocet_m = 0; if(cislo == INFINITY) return cislo; if(fabs(cislo) > log_horni_hranice) { // prevod cisel vyssich nez 2 while(fabs(cislo) > log_horni_hranice) { cislo = cislo / IZP_E; pocet_v += 1; } } else if(fabs(cislo) < log_dolni_hranice ) { // prevod cisel mensich nez 0.1 while(fabs(cislo) < log_dolni_hranice) { cislo = cislo * IZP_E; pocet_m += 1; } } double citatel = cislo - 1, jmenovatel = cislo + 1; double citatel2 = 0, mocnina2 = 0; mocnina = jmenovatel; clen = 2 * (citatel / jmenovatel); // vypocet prvniho clenu soucet = clen; citatel2 = (cislo - 1) * (cislo - 1); // pro urychleni vypoctu si dopredu spocitame hodnotu (x - 1)^2 mocnina2 = (cislo + 1) * (cislo + 1); // pro urychleni vypoctu si dopredu spocitame hodnotu (x + 1)^2 while(fabs(clen) > eps) { i += 2; citatel *= citatel2; // predchozi citatel nasobime (x - 1)^2 mocnina *= mocnina2; // odobne ve jmenovateli jmenovatel = i * mocnina; // a jeste vynasobime hodnotou i clen = 2 * (citatel / jmenovatel); // cely clen musime dle matematicke definic nasobit 2 soucet += clen; } // pro prevod cisla do intervalu <0.1, 2> jsme pouzili vztah ln(x) = ln(r) + m * ln(z) // kde r je cislo z intervalu <0.1, 2>, m je pocet deleni, ktere jsme potrebovali, aby cislo bylo v intervalu // z je cislo, kterym jsme delili, z = e, tedy ln(e) = 1, z toho vyplyva, ze k vysledku ln(x) musime pricist jeste m // stejne postupujeme i pri cisle mensim nez 0.1, kde vsak nasobime cislem e a od vysledku m odcitame if(pocet_v > 0) { soucet += pocet_v; } else if(pocet_m > 0) { soucet -= pocet_m; } return soucet; } double muj_logax(double cislo, double eps, double a) { double vysledek = 0; // dle matematicke definice testujeme specialni vstupy if(cislo < 0) { vysledek = NAN; } else if (cislo == 0 && a > 1) { vysledek = -INFINITY; } else if (cislo == 0 && a < 1) { vysledek = INFINITY; } else if (cislo == INFINITY && a > 1) { vysledek = INFINITY; } else if (cislo == INFINITY && a < 1) { vysledek = -INFINITY; } else { vysledek = muj_ln(cislo, eps) / muj_ln(a, eps); } return vysledek; } void vypis_chybu(int kod) // podle obdrzeneho chyboveho kodu vypiseme chybove hlaseni na stderr a ukoncime program { switch(kod) { case 1: fprintf(stderr, "\n\nChybny parametr prikazove radky! Program bude ukoncen. \n\n"); exit(1); break; case 2: fprintf(stderr, "\n\nChybny znak na vstupu! Program bude ukoncen. \n\n"); exit(2); break; default: break; } } double preved_eps(int sigdig) // prevadi pocet platnych cislic na eps { double eps = 0.1; while(sigdig--) eps *= 0.1; return eps; } void napoveda(void) { printf("\n\n" "Iteracni vypocty\n" "Autor: Milan Seitler\n" "\n" "Spusteni programu: ./proj2 -h | --logax sigdig a | --tanh sigdig | --wam | --wqm" "-h - napoveda\n" "--logax - obecny logaritmus\n" "--tanh - hyperbolicky tangens\n" "--wam - vazeny aritmeticky prumer\n" "--wqm - vazeny kvadraticky prumer \n" "sigdig - pocet platnych cislic\n" "a - zaklad logaritmu\n\n" "Program pocita tyto funkce s pouzitim iteracnich vypoctu. U logax a tanh uzivatel zadava" " pocet platnych cislic, ktere urcuji pocet cislic od prvni nenulove cislice, ktere budou" " odpovidat \"spravnemu\" vysledku.\n\n"); exit(EXIT_SUCCESS); } void nacti_parametry(int argc, char *argv[]) { if(argc == 4) { // pokud uzivatel zada logax param.zaklad_log = strtod(argv[3], ¶m.stop); if(errno == ERANGE || isalpha(*param.stop) || ispunct(*param.stop) || param.zaklad_log == 1 || param.zaklad_log <= 0) // testujeme, zda je parametr a cislo typu double vypis_chybu(K_CHYBNY_PARAMETR); param.sigdig = strtoul(argv[2], ¶m.stop, 10); if(errno == ERANGE || isalpha(*param.stop) || ispunct(*param.stop) || param.sigdig <= 0) // testujeme, zda je parametr sigdig cislo typu int vypis_chybu(K_CHYBNY_PARAMETR); if(strcmp("--logax", argv[1]) == 0) { // testujeme, zda uzivatel spravne napsal parametr pro funkci param.eps = preved_eps(param.sigdig); // prevedeme sigdig na epsilon param.spust = LOGAX; } else { vypis_chybu(K_CHYBNY_PARAMETR); } } else if(argc == 3) { // pokud uzivatel zada tanh param.sigdig = strtoul(argv[2], ¶m.stop, 10); if(errno == ERANGE || isalpha(*param.stop) || ispunct(*param.stop) || param.sigdig <= 0) // testujeme, zda je parametr sigdig cislo typu int vypis_chybu(K_CHYBNY_PARAMETR); if(strcmp("--tanh", argv[1]) == 0) { // testujeme, zda uzivatel spravne napsal parametr pro funkci param.eps = preved_eps(param.sigdig); // prevedeme sigdig na epsilon param.spust = TANH; } else { vypis_chybu(K_CHYBNY_PARAMETR); } } else if(argc == 2) { // pokud uzivatel zada stat. fce if(strcmp("--wam", argv[1]) == 0){ // testujeme, zda uzivatel spravne napsal parametr pro funkci param.spust = WAM; } else if(strcmp("--wqm", argv[1]) == 0) { // testujeme, zda uzivatel spravne napsal parametr pro funkci param.spust = WQM; } else if(strcmp("-h", argv[1]) == 0) { napoveda(); } else { vypis_chybu(K_CHYBNY_PARAMETR); } } } |

Čti dál:
1 komentář k “Základy programování (IZP) – Projekt č. 1 a 2”
Vyjádři svůj názor
O mně
kategorie
SSME FI MUNI
FIT VUT
Odkazy
Inzerujte zde!
Kupte si odkaz! PR 3, SR 2
Inzerujte zde!
Kupte si odkaz! PR 3, SR 2
Inzerujte zde!
Kupte si odkaz! PR 3, SR 2
TAGS
2012
acta
akce
api
barcamp
bash
Bergamo
blog
brno
byznys
C
chytni svojdu
css
cufon
e-shop
facebook
filmy
FIT VUT
hobit
hokejový souboj
html
internet explorer
Iseo
IT
Itálie
komunikace
low-cost trip
mozilla firefox
objektově orientované programování
osobní rozvoj
parser
php
programování
python
pán prstenů
přednáška
regex
reinto
skript
spartacus
testování
url
volby 2013
vut
wordpress
Nejčtenější články
- 7 tipů Jak spát méně a efektivněji - 163 786 views
- První semestr na FIT VUT - 117 569 views
- Jak v PHP nahradit zastaralé funkce ereg a eregi - 64 358 views
- TEST: Kolik spánku je denně potřeba? - 51 994 views
- Třetí semestr na FIT VUT - 51 706 views
- 7 tipů jak si usnadnit a urychlit práci s HTML a CSS - 50 440 views
- Pátý semestr na FIT VUT - 42 110 views
- Čtvrtý semestr na FIT VUT - 38 874 views
- Druhý semestr na FIT VUT - 36 552 views
- 9 nečekaně jednoduchých technik, které z vás udělají mistra komunikace - 35 998 views
Nejnovější komentáře
- 5 nových tipů pro lepší spánek « Milan Seitler u 7 tipů Jak spát méně a efektivněji
- 5 nových tipů pro lepší spánek « Milan Seitler u TEST: Je možné spát 6 hodin denně? Tak určitě!
- David u 9 nečekaně jednoduchých technik, které z vás udělají mistra komunikace
- Petr u Bakalářské studium na FIT VUT
- Martin u Jak v PHP nahradit zastaralé funkce ereg a eregi
archiv
- Prosinec 2018
- Listopad 2015
- Září 2015
- Březen 2015
- Květen 2014
- Duben 2014
- Prosinec 2013
- Listopad 2013
- Červenec 2013
- Červen 2013
- Duben 2013
- Březen 2013
- Únor 2013
- Leden 2013
- Prosinec 2012
- Listopad 2012
- Říjen 2012
- Září 2012
- Srpen 2012
- Červenec 2012
- Červen 2012
- Květen 2012
- Březen 2012
- Únor 2012
- Leden 2012
- Listopad 2011
- Říjen 2011
- Srpen 2011
- Červen 2011
- Duben 2011
- Únor 2011
- Leden 2011
Dobre ty… Až na to, že máš zakázané použiť dynamickú alokáciu v projekte 1