|
f(x): | ||
x ∈ M ⇒ return d(x); | ||
return g(f(h1(x)), f(h2(x)), … f(hn(x))); | ||
nebo | ||
return g(x, f(h1(x)), f(h2(x)), … f(hn(x))); |
#include <stdlib.h> #include <stdio.h> #include <math.h> unsigned int isinM(unsigned int x); unsigned int d(unsigned int x); unsigned int h1(unsigned int x); unsigned int h2(unsigned int x); unsigned int h3(unsigned int x); unsigned int g(unsigned int x, unsigned int y, unsigned int z); unsigned int f(unsigned int x); int main() { unsigned int xx, i; printf("Zadejte do ktereho argumentu se ma spocitat: "); scanf(" %u", &xx); for (i = 1; i <= xx; ++i) { printf("f(%2u) = %u\n", i, f(i)); } } unsigned int isinM(unsigned int x) { return x == 1 || x == 2 || x == 3 || x == 6 || x == 7 || x == 11 || x == 13 || x == 16 || x == 19 || x == 26; } nsigned int d(unsigned int x) { return 97 - x; } unsigned int h1(unsigned int x) { return x < 7 ? x + 1 : x / 2; } unsigned int h2(unsigned int x) { return x > 49 ? (unsigned int)sqrt((double)x) : x / 3; } unsigned int h3(unsigned int x) { return x < 28 ? x + 2 : (2 * x) / 3; } unsigned int g(unsigned int x, unsigned int y, unsigned int z) { return (x + y + z) / 4; }
unsigned int f(unsigned int x) { if (isinM(x)) return d(x); return g(f(h1(x)), f(h2(x)), f(h3(x))); }
/** * @file combiNum.c * * @author Ales Zlamal */ #include <stdlib.h> #include <stdio.h> /** * Pocita kombinacni cislo „n nad k“ (c(n, k)) * * @param n * @param k * @return kombinacni cislo c(n, k) */ unsigned int c(unsigned int n, unsigned int k); int main() { unsigned int n, nn, k; printf("Zadejte kolik radku Pascalova trojuhelnika se ma vytisknout: "); scanf(" %u", &nn); for (n = 0; n <= nn; ++n) { printf("%*s", 58 - 3 * n, " "); for (k = 0; k <= n; ++k) { printf(" %3u", c(n, k)); } printf("\n"); } return EXIT_SUCCESS; }
je v math.h M_SQRT1_2 , ale ne vždy a všude to funguje. |
Tady jsem v pokušení parafrázovat bajku o dvou medvědech, kole sýra a lišce. (Oscar Wild napsal „Odolám všemu krom pokušení.” a „Nejlepší způsob jak odolat pokušení je podlehnout mu.” a řídil se tím a pobyl si ve vězení: The Ballad of Reading Gaol.) | |
Bez bajky napíši zadání:
napište rekursivní program na iterpolaci funkce (analogie binárního vyhledávání či „výpočtu” √ podle předpředešlého zadání)
pro rozdělení kruhu tětivou na dvě kruhové výseče s obsahy v poměru 2 : 1. Na obrázku vpravo úsečka q je vzdálenost středu S od tětivy. Na onom obrázku vpravo je v jednotkovém kruhu tětiva červeně a hledáme v něm poměr velikosti (v jednotkovém kruhu) zelené úsečky : 1, při výpočtu nám tedy vychází jakožto část jednotky. (Hledáme vlastně hodnotu inversní funkce k analytické funkci pro výpočet obsahu kruhové úseče při zadaném q.) Ona funkce, jejíž hodnotu hledáme, musí být ‑ stejně jako při binárním hledání ‑ monotonní. V našem případě je klesající: s rostoucí vzdáleností tětivy od středu kruhu se obsah úseče zmenšuje ‑ funkce klesá. Krajní body intervalu, v němž hledáme, jsou v jednotkovém kruhu (pochopitelně) 0 a 1. |
|
Počítejte použitím typu double a potřebovat budete funkce z math.h acos (arc cos)
a sqrt (), Pythágorovu větu
a z math.h M_PI (π) (tohle ale ne vždy a všude to funguje.
Pokud program sestavujete (a překládáte) z příkazového řádku, nezapomeňte na jeho konci přidat „-lm ”.Toto zadání je poněkud matematičtější. Nemáte zapomenout, že jste matematici, a že i při programování se mohou a mají používat matematické „buňky”. |
/** * @file isPrime.c * * @author Ales Zlamal */ #include <stdlib.h> #include <stdio.h> /** * Pocita prirozeneciselnou odmocninu === celky z odmocniny (|_\|x)_|) * * @param a cislo z nejz odmocnina pocita * @return nejvetsi prirozene cislo mensi nebo rovne odmocnine z a */ unsigned int isqrt(unsigned int a); /* m = isqrt(as) */ /** * Testuje prvociselnost (cisla x: isPrime(x, 0)) od odmocniny z x a jen prvocisly (Eratosthenes) * * @param x testovane cislo * @param d delitel * @return 1, jestlize je zadane cislo prvocislo; neni-li zadane cislo prvocislo, 0 */ unsigned int isPrime(unsigned int x, unsigned int d); int main() { unsigned int xx, ii; printf("Zadejte mez prvociselneho testu (0 program ukoncuje): "); scanf(" %u", &xx); if (xx == 0) return EXIT_SUCCESS; printf("Prvocisla:\n"); for (ii = 0; ii <= xx; ++ii) { if (isPrime(ii, 0)) { printf("%3u\n", ii); } } printf("\n\nNeprvocisla:\n"); for (ii = 0; ii <= xx; ++ii) { if (!isPrime(ii, 0)) { printf("%3u\n", ii); } } } unsigned int isqrt(unsigned int a) { unsigned int m, p, q, t, u; p = 1; q = 1; u = 3; p <<= sizeof(unsigned int)*8 - 2; q <<= sizeof(unsigned int)*4 - 1; u <<= sizeof(unsigned int)*8 - 2; while( (a & u) == 0 ){ u >>= 2; p >>= 2; q >>= 1; } a -= p; t = p; u = p; m = q; while( (a != 0) && (t > 0x00000002) ){ q >>= 1; p >>= 1; t >>= 2; if( a >= (u | t) ){ a -= t; a -= u; u |= p; m |= q; } p >>= 1; u >>= 1; } return m; } unsigned int isPrime(unsigned int x, unsigned int d) { if (x < 2) return 0; if (x < 4) return 1; if (d == 0) return isPrime(x, isqrt(x)); if (d == 1) return d; if (isPrime(d, 0) && x % d == 0) return 0; return isPrime(x, d - 1); }Kdyby dělení ‑ respective výpočet zbytku po dělení ‑ bylo (časově) „drahé“ (kdysi to byl tisícinásobek času sčítání) a zjišťování prvočíselnosti (do √ z testovaného čísla) (například nalezením v tabulce nebo v rychlé implementaci množiny) „levné“, pak by efektivita takového výpočtu dávala smysl. Je-li ale výpočet zbytku po dělení stejně dlouhý jako sčítání a prvočíselnosti (do √ z testovaného čísla) naopak podstatně delší, nemá smysl dělit jen prvočísly (u dělitelů zjišťovat prvočíselnost).
/** * @file bubbleSort.c * * @author Ales Zlamal */ #include <stdlib.h> #include <stdio.h> #include <time.h> /** * Generuje do pole od zadaneho indexu po zadany index hodnoty ze zadaneho (uzavreneho) intervalu * * @param d pole, do ktereho se nahodne ciselne hodnoty generuji * @param hodnotaOd levy kraj (uzavreneho) intervalu, z nejz se generuji nahodne ciselne hodnoty * @param hodnotaPo pravy kraj (uzavreneho) intervalu, z nejz se generuji nahodne ciselne hodnoty * @param odkud levy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty * @param pokud pravy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty */ void generujNahodne(int* d, int hodnotaOd, int hodnotaPo, int odkud, int pokud); /** * Generuje do pole od zadaneho indexu po zadany index hodnoty ze zadaneho (uzavreneho) intervalu * * @param e pole, do ktereho se nahodne ciselne hodnoty generuji * @param odkud levy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty * @param pokud pravy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty */ void printPole(int* e, int odkud, int pokud); /** * Prohod sousedni, je-li treba * * @param b pole, v kterem se ciselne hodnoty - posloupnost - tridi (vzestupne) * @param i index prvku, ktery se porovnava se svym bezprostrednim naslednikem, a prohazuji se, je-li treba * @return r priznak inverse, tj. ze se prohodilo */ int pjt(int* b, int i, int r); /** * Vzestupne setridi algoritmem Bubble sort s ukoncenim nebyla-li v bublani zadna inverse (a tedy vymena) * * Vola se bubbleSort(pole, index prvniho, index posledniho, 0); * * @param c pole, v kterem se ciselne hodnoty - posloupnost - tridi (vzestupne) * @param i index prvku, odkud se probublava * @param k index posledniho prvku v poli - podposloupnosti - po ktery se ma probublavat * @param r priznak inverse, tj. ze se prohodilo */ void bubbleSort(int* c, int j, int k, int r); #define N 26 int main() { int i, a[N]; srand(time(NULL)); generujNahodne(a, 0, 99, 0, N - 1); printPole(a, 0, N - 1); bubbleSort(a, 0, N - 1, 0); printPole(a, 0, N - 1); return 0; } void generujNahodne(int* d, int hodnotaOd, int hodnotaPo, int odkud, int pokud) { if (odkud == pokud) return; d[odkud] = hodnotaOd + rand() % (hodnotaPo - hodnotaOd + 1); generujNahodne(d, hodnotaOd, hodnotaPo, odkud + 1, pokud); } void printPole(int* e, int odkud, int pokud) { if (odkud == pokud) { printf("\n"); return; } printf("%2d ", e[odkud]); printPole(e, odkud + 1, pokud); } int pjt(int* b, int i, int rr) { int pom; if (b[i] > b[i+1]) { pom = b[i]; b[i] = b[i+1]; b[i+1] = pom; rr = 0; } return rr; } void bubbleSort(int* d, int j, int k, int r) { if ((j == k) && r) return; if (j < k) { bubbleSort(d, j + 1, k, pjt(d, j, r)); } else { bubbleSort(d, 0, k - 1, 1); } }Zkuste napsat jeho sice rekursivní versi, ale s použitím nerekursivní funkce bublání
/** * @file selectSort.c * * @author Ales Zlamal */ #include <stdlib.h> #include <stdio.h> #include <time.h> /** * Generuje do pole od zadaneho indexu po zadany index hodnoty ze zadaneho (uzavreneho) intervalu * * @param d pole, do ktereho se nahodne ciselne hodnoty generuji * @param hodnotaOd levy kraj (uzavreneho) intervalu, z nejz se generuji nahodne ciselne hodnoty * @param hodnotaPo pravy kraj (uzavreneho) intervalu, z nejz se generuji nahodne ciselne hodnoty * @param odkud levy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty * @param pokud pravy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty */ void generujNahodne(int* d, int hodnotaOd, int hodnotaPo, int odkud, int pokud); /** * Generuje do pole od zadaneho indexu po zadany index hodnoty ze zadaneho (uzavreneho) intervalu * * @param e pole, do ktereho se nahodne ciselne hodnoty generuji * @param odkud levy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty * @param pokud pravy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty */ void printPole(int* e, int odkud, int pokud); /** * Prohod zadane, je-li treba * * @param b pole, v kterem se ciselne hodnoty - posloupnost - tridi (vzestupne) * @param i index prvku, ktery se porovnava s druhym zadanym a prohazuji se, je-li treba * @param j index prvku, ktery se porovnava s prvnim zadanym a prohazuji se, je-li treba */ void pjt(int* b, int i, int j); /** * Vzestupne setridi algoritmem Select sort * * @param c pole, v kterem se ciselne hodnoty - posloupnost - tridi (vzestupne) * @param j index prvku, ktery se porovnava se prvkem na indexu dosud nalezeneho maxima v podposloupnosti * @param k index posledniho prvku nesetrideneho useku pole - podposloupnosti * @return index maximalniho prvku z nesetrideneho useku pole - podposloupnosti */ int selectSort(int* c, int j, int k); #define N 26 int main() { int i, a[N]; srand(time(NULL)); generujNahodne(a, 0, 99, 0, N - 1); printPole(a, 0, N - 1); selectSort(a, N-1, N-1); printPole(a, 0, N - 1); return 0; } void generujNahodne(int* d, int hodnotaOd, int hodnotaPo, int odkud, int pokud) { if (odkud == pokud) return; d[odkud] = hodnotaOd + rand() % (hodnotaPo - hodnotaOd + 1); generujNahodne(d, hodnotaOd, hodnotaPo, odkud + 1, pokud); } void printPole(int* e, int odkud, int pokud) { if (odkud == pokud) { printf("\n"); return; } printf("%2d ", e[odkud]); printPole(e, odkud + 1, pokud); } void pjt(int* b, int i, int j) { int pom; if (b[j] > b[i]) i = j; if (i != j) { pom = b[i]; b[i] = b[j]; b[j] = pom; } } int selectSort(int* c, int j, int k) { int m; if ((j == 0) || (k == 0)) return 0; if (j < k) { m = selectSort(c, j - 1, k); return c[j] > c[m] ? j : m; } pjt(c, selectSort(c, k-1, k), k); selectSort(c, k-1, k-1); return 0; }Zkuste napsat jeho sice rekursivní versi, ale s použitím nerekursivní funkce výběru buď minima anebo maxima ‑ podle vašeho výběru.
/** * @file insertSort.c * * @author Ales Zlamal */ #include <stdlib.h> #include <stdio.h> #include <time.h> /** * Generuje do pole od zadaneho indexu po zadany index hodnoty ze zadaneho (uzavreneho) intervalu * * @param d pole, do ktereho se nahodne ciselne hodnoty generuji * @param hodnotaOd levy kraj (uzavreneho) intervalu, z nejz se generuji nahodne ciselne hodnoty * @param hodnotaPo pravy kraj (uzavreneho) intervalu, z nejz se generuji nahodne ciselne hodnoty * @param odkud levy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty * @param pokud pravy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty */ void generujNahodne(int* d, int hodnotaOd, int hodnotaPo, int odkud, int pokud); /** * Generuje do pole od zadaneho indexu po zadany index hodnoty ze zadaneho (uzavreneho) intervalu * * @param e pole, do ktereho se nahodne ciselne hodnoty generuji * @param odkud levy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty * @param pokud pravy krajni index podpole, do nejz se generuji nahodne ciselne hodnoty */ void printPole(int* e, int odkud, int pokud); /** * Vzestupne setridi algoritmem Insert sort * * Vola se insertSort(pole, index prvniho, index posledniho, velikost pole); * * @param c pole, v kterem se ciselne hodnoty - posloupnost - tridi (vzestupne) * @param j index prvku, odkud se zacina tridit * @param t hodnota, ktera se zatrizuje * @param k index hodnoty, ktera se bude zatrizovat * @param n index konce trizene podposloupnosti + 1 */ void insertSort(int* c, int j, int t, int k, int n); #define N 26 int main() { int a[N]; srand(time(NULL)); generujNahodne(a, 0, 99, 0, N - 1); printPole(a, 0, N - 1); insertSort(a, 0, 0, 1, N); printPole(a, 0, N - 1); return 0; } void generujNahodne(int* d, int hodnotaOd, int hodnotaPo, int odkud, int pokud) { if (odkud == pokud) return; d[odkud] = hodnotaOd + rand() % (hodnotaPo - hodnotaOd + 1); generujNahodne(d, hodnotaOd, hodnotaPo, odkud + 1, pokud); } void printPole(int* e, int odkud, int pokud) { if (odkud == pokud) { printf("\n"); return; } printf("%2d ", e[odkud]); printPole(e, odkud + 1, pokud); } void insertSort(int* c, int j, int t, int k, int n) { if (k == n) return; if (j + 1 == k) { if (c[k] >= c[k-1]) { insertSort(c, k, t, k + 1, n); } else { t = c[k]; c[k] = c[j]; insertSort(c, j - 1, t, k, n); } } else { if ((j >= 0) && (c[j] > t)) { c[j+1] = c[j]; insertSort(c, j - 1, t, k, n); } else { c[++j] = t; insertSort(c, k, t, k + 1, n); } } }Zkuste napsat versi sice rekursivní, ale s použitím nerekursivní funkce zatřízení.