/**
*
* Binarni vyhledavani
*
* @file binarySearch.c
*
* @author A. Zlamal
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define DELKA_POLE 26 // muzeme kdykoli delku pole menit jen na tomto miste
#define I_F_P "%d" // FORMATOVACI_PARAMETR pro scanf - musime menit jen na tomto miste podle myType
#define O_F_P "%2d " // FORMATOVACI_PARAMETR pro printf - musime menit jen na tomto miste podle myType
typedef int myType; // muzeme potom typ menit jen na tomto miste
typedef myType pole[DELKA_POLE]; // analogicky: lze typ pole pohodlne pouzivat
/**
* Binarne vyhledava zadanou ciselnou hodnotu - vrati jeji index v poli; nenajde-li ji vrati -1
*
* @param aa usporadane pole, v nemz se hleda
* @param ch hledana ciselna hodnota
* @param d dolni mez podpole, v nemz se hleda
* @param h horni mez podpole, v nemz se hleda
* @return index v poli, najde-li zadanou hodnotu; nenajde-li -1
*/
nt binarySearch(pole aa, myType ch, int d, int h);
int main()
{
pole a;
int i;
myType v;
srand(time(NULL));
a[0] = rand() % (4 + (rand() & 1));
for (i = 1; i < DELKA_POLE; ++i) {
a[i] = a[i-1] + 1 + rand() % (4 + (rand() % 4));
}
for (i = 0; i < DELKA_POLE; ++i) {
printf("%2d ", i);
}
printf("\n");
for (i = 0; i < DELKA_POLE; ++i) {
printf(O_F_P, a[i]);
}
printf("\n");
printf("Zadejte hodnotu, jez se ma nalezt: ");
scanf(I_F_P, &v);
if ((i = binarySearch(a, v, 0, DELKA_POLE)) != -1) {
printf(O_F_P"je v poli na posici %d.\n", v, i);
} else {
printf(O_F_P"v poli neni.\n", v);
}
return EXIT_SUCCESS;
}
int binarySearch(pole aa, myType ch, int d, int h)
{
int s;
myType c;
if (d > h) return -1;
if ((c = aa[(s = (d + h) / 2)]) == ch) return s;
if (c > ch) return binarySearch(aa, ch, d, s - 1);
return binarySearch(aa, ch, s + 1, h);
}
Obsah kruhové úseče je a má být . Úhly jsou v radiánech.
(Kruh je jednotkový.)
/**
* Jednoucelova rekursivni funkce pro vypocet usece s tretinovym obsahem
*
* @param a levy konec intervalu, v nemz se pohybuje vysledek
* @param b pravy konec intervalu, v nemz se pohybuje vysledek
* @return vysledek
*/
double tretinaKruhu(double a, double b);
⋮
x = tretinaKruhu(0.0, 1.0);
printf(" %lf %lf %lf\n", x, acos(x) - x * sqrt(1.0 - x*x), TRETINA_KRUHU);
⋮
double tretinaKruhu(double a, double b)
{
double xx, m;
m = (a + b) * 0.5;
xx = acos(m) - m * sqrt(1.0 - m*m);
if (xx - 0.0000005 < TRETINA_KRUHU && TRETINA_KRUHU < xx + 0.0000005) return m;
if (xx > TRETINA_KRUHU) return tretinaKruhu(m, b);
return tretinaKruhu(a, m);
}
V terminálovém oknu:
0.264932 1.047197 1.0471
/**
* Mene jednoucelova rekursivni funkce pro vypocet usece se zadanym podilem obsahu
*
* @param a levy konec intervalu, v nemz se pohybuje vysledek
* @param b pravy konec intervalu, v nemz se pohybuje vysledek
* @param y pozadovany podil z kruhu, pro nejz se hleda vzdalenost stredu kruhu od tetivy
* @param eps zadana tolerance
* @return vysledek ≡ vzdalenost stredu kruhu od tetivy vymezujici kruhovou usec
*/
double kolikatinaKruhu(double a, double b, double y, double eps);
⋮
x = x = kolikatinaKruhu(0.0, 1.0, 1.0 / 3.0, 0.0000005);
printf(" %lf %lf %lf\n", x, acos(x) - x * sqrt(1.0 - x*x), TRETINA_KRUHU);
⋮
double kolikatinaKruhu(double a, double b, double yy, double eps)
{
double xx, m, y;
y = yy * M_PI;
m = (a + b) * 0.5;
xx = acos(m) - m * sqrt(1.0 - m*m);
if (xx - eps < y && y < xx + eps) return m;
if (xx > y) return kolikatinaKruhu(m, b, yy, eps);
return kolikatinaKruhu(a, m, yy, eps);
}
V terminálovém oknu:
0.264932 1.047197 1.0471
double f(double x);
double g(double x); // druha mocnina ≡ ctverec
/**
* Universalni rekursivni funkce pro vypocet zadane hodnoty ve funkci inversni k zadane
* Inversni funkci k zadane nelze spocitat a zadana funkce musi mit v zadanem intervalu monotonni prubeh
*
* @param f double f(double x), ve fukci k ni inversni se pocita hodnota funkce v zadanem bode
* @param a levy konec intervalu, v nemz se pohybuje vysledek
* @param b pravy konec intervalu, v nemz se pohybuje vysledek
* @param r kladna hodnota - nejlepe 1.0 - pro vzestupnou funkci a pro sestupnou zaporna - nejlepe -1.0
* @param y pozadovana hodnota argumentu inversni funkce
* @param eps zadana tolerance
* @return vysledna hodnota
*/
double interpolace(double (*h)(double), double a, double b, double r, double y, double eps);
⋮
x = interpolace(f, 0.0, 1.0, f(1.0) - f(0.0), M_PI * 1.0 / 3.0, 0.0000005);
printf(" %lf %lf %lf\n", x, f(x), TRETINA_KRUHU);
x = interpolace(g, 1.0, 2.0, 1.0, 2, 0.0000005);
printf(" \\|%lf = %lf\n", g(x), x);
⋮
double f(double x)
{
return acos(x) - x * sqrt(1.0 - x*x);
}
double g(double x)
{
return x*x;
}
double interpolace(double (*h)(double), double a, double b, double r, double y, double eps)
{
double xx, m;
m = (a + b) * 0.5;
xx = h(m);
if (xx - eps < y && y < xx + eps) return m;
if (r*xx < r*y) return interpolace(h, m, b, r, y, eps);
return interpolace(h, a, m, r, y, eps);
}
V terminálovém oknu:
0.264932 1.047197 1.0471
\|2.000000 = 1.414214