mgr inż. Wacław Libront * Bobowa 2019
ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu
Duża część algorytmów działa na dowolnych danych i nie jesteśmy w stanie przewidzieć, ile razy powinna wykonać się pętla (jak w przypadku pętli FOR). Może to być zależne na przykład od wpisywanego z klawiatury tekstu, podawania poprawnych lub błędnych danych, itp. W ogólnym przypadku możemy stwierdzić, że czas działania pętli logicznej będzie zależał od spełnienia (lub nie) określonego warunku logicznego.
warunek logiczny jest sprawdzany przed wykonaniem instrukcji w pętli
while (warunek) instrukcja;
while (warunek) { instrukcje;…; }
najpierw wykonywana jest instrukcja, a potem sprawdzany jest warunek logiczny
do instrukcja; while (warunek);
do { instrukcje;…; } while (warunek);
Przykłady
Wypisz na ekranie liczby naturalne od 1 do 10
// pętla FOR for (int i=1; i<=10; i++) cout << i << endl; |
// pętla WHILE int i=1; while (i <= 10){ cout << i << endl; i=i+1; } |
// pętla DO WHILE int j=1; do { cout << j << endl; j=j+1; } while (j <= 10); |
Zadanie - SUMA i ŚREDNIA
Podsumuj i wylicz średnią arytmetyczną oceny wpisywane z klawiatury. Kończymy obliczenia, gdy użytkownik wpisze z klawiatury 0. Sprawdź czy oceny mieszczą się w zakresie od 1 do 6.
#include <stdlib.h> //system() #include <iostream> //cout i cin #include <iomanip> //fixed i setprecision() using namespace std; int main() { setlocale(LC_ALL, ""); cout << "SUMA i ŚREDNIA OCEN" << endl << endl; // zerujemy zmienne aby program nie liczył glupot int ile=0; float suma=0; float srednia=0; // zmiennej ocena nie musimy inicjowac // bo za pierwszym razem wpisana wartosc z klawiatury float ocena; do { cout << "Wpisz ocenę (0-koniec): "; cin >> ocena; // ocena musi miescic sie w zakresie 1..6 if (ocena >= 1 && ocena <= 6){ ile=ile+1; // zmienna SUMA powiekszana o nowa ocena suma=suma+ocena; //za kazdym razem liczymy srednia srednia=suma/ile; } } while (ocena != 0); // koniec petli gdy z klawiatury wpisano zero cout << "Ilość ocen: " << ile << endl; cout << "Suma ocen: " << suma << endl; cout << fixed << setprecision(2); cout << "Średnia ocen: " << srednia << endl; system("pause"); } |
Uwagi do programu
Kolejne algorytmy zostaną opisane zgodnie ze specyfikacją wymaganą na maturze.
Zadanie - Wyszukiwanie minimum (maksimum)
Wpisujemy z klawiatury liczby i wyszukujemy minimalną (maksymalną).
Jeden z najbardziej elementarnych algorytmów, stosowany przede wszystkim podczas operacji sortowania.
Specyfikacja
Zadanie: wybierz minimalną z liczb <1..n> wpisywanych z klawiatury. Zero kończy proces.
Dane: liczba naturalna N <1..maxint>
Wyniki: liczba minimalna
Lista kroków:
wprowadź liczbę N
zmiennej MIN przypisz N
wprowadź liczbę N
jeżeli N > 0 i N < MIN przypisz MIN=N
jeżeli N>0 wróć do kroku 3
Wypisz liczbę minimalną MIN
int N; cout << "wpisz liczbę: "; cin >> N; int MIN=N; do { cout << "wpisz liczbę: "; cin >> N; if (N > 0 && N < MIN) MIN=N; } while (N>0); cout << "minimalna: " << MIN << endl; |
Zadanie - Euklides
Napisz program (funkcję), który policzy największy wspólny dzielnik dwóch liczb wpisanych z klawiatury.
Największy wspólny dzielnik liczb wykorzystywany jest do skracania ułamków (licznik i mianownik dzieli się przez NWD) oraz do obliczania najmniejszej wspólnej wielokrotności NWW (sprowadzanie ułamków do wspólnego mianownika)
Specyfikacja
Dane: Dwie liczby naturalne A i B
Wynik: wartość NWD
Lista kroków:
Wprowadź A i B
Czy A jest różne od B
Dopóki A nie jest równe B powtarzaj punkty 4 i 5
Od liczby większej odejmij mniejszą
Do liczby większej przypisz różnicę
Wyprowadź NWD równe pierwszej liczbie (lub drugiej bo i tak są równe)
cout << "EUKLIDES NWD" << endl; cout << "NWD Wpisz dwie liczby: "; int A,B; cin >> A >> B; while (A != B) if (A > B) A=A-B; else B=B-A; cout << "NWD(" << A << "," << B << ")=" << NWD(A,B) << endl; |
Zadanie - Fibonacci
Początkowo mamy jedną parę królików. Po miesiącu osiągają dojrzałość płciową i po kolejnym rodzi się nowa para królików. W kolejnym miesiącu znów urodzi się nowa para królików od rodziców, a młode króliki osiągną dojrzałość płciową, by za miesiąc wydać nowe pokolenie. I tak w nieskończoność. Zadaniem programu (funkcji) będzie policzenie, ile par królików będzie w stadzie po N miesiącach?
W kolejnych miesiącach będzie następująca ilość par: 1,1,2,3,5,8,13,21,34,55,89,144 i jest to suma dwóch poprzednich ciągów.
Specyfikacja
Dane: Liczba naturalna N – liczba kroków
Wynik: Ilość par królików po N krokach
Lista kroków:
F1=0 F2=1 - pierwsze dwa wyrazy
pętla od 0 do N-1
wylicz F2=F2+F1
wylicz F1=F2-F1
F2 zawiera wynik
int FIB(int N){ int F1=0, F2=1, i=0; while (i < N){ F2=F2+F1; F1=F2-F1; i++; }; return F2; } ... cout << "FIBONACCI Ile kroków: " << endl; int krok; cin >> krok; cout << "FIBONACCI(" << krok << ")=" << FIB(krok) << endl; |
Zadanie – SINUS
Wartość funkcji trygonometrycznej sin(x) można wyznaczyć za pomocą szeregu Taylora:
Wykorzystując tą definicję napisz funkcję, który policzy wartość sinusa dla argumentu x z dokładnością n, gdzie n oznacza ilość wyrazów w szeregu Taylora.
W programie głównym wylicz wartość funkcji dla kolejnych kątów od 0° do 360°, co 30°
Specyfikacja
Dane:
K - kąt w stopniach
D - liczba wyrazów szeregu
(dokładność obliczeń)
Wynik: Wartość funkcji sin(x), gdzie x - kąt w stopniach
Lista kroków:
Wczytaj kąt - K i dokładność - D
wyzeruj sumę początkową - S
zamień kąt K na miarę łukową radiany - R
pętla od 1 do D wykonuje punkt 5
powiększ sumę S o kolejny wyraz szeregu Taylora
S zawiera wynik - wartość funkcji sin(x)
#include <cmath> ... long long SILNIA(int N){ long long s=1, i=1; while (i <= N) { s=s*i; i++; } return s; } double RADIANY(double sto){ return sto*M_PI/180; } double SIN(double x, int n){ double s=0; double R=RADIANY(x); int i=0; while (i <= n){ s=s+pow(-1,i)*pow(R,2*i+1)/SILNIA(2*i+1); i++; } return s; } ... cout << "SINUS - Szereg Taylora" << endl; cout << "Wpisz kąt (stopnie): "; double K,D; cin >> K; cout << "Wpisz dokładność (0-N): "; cin >> D; cout << "SIN(" << K << ")=" << SIN(K,D) << endl; ... //kąty w pętli int k=0; while (k <= 360){ cout.width(5); cout << k; cout.width(10); cout << fixed << setprecision(5); cout << SIN(k,8) << endl; k=k+30; } |
funkcja Taylora liczy kąty dla x podawanych w tzw. mierze łukowej, w radianach. Aby funkcja przyjmowała kąty w stopniach, dopiszemy dodatkową funkcję RADIANY, która będzie zamieniać radiany na stopnie, Dodatkowo w funkcji SIN wykorzystano funkcję SILNIA oraz funkcję POW i M_PI z biblioteki CMATH.
zwróć uwagę na pojawiające się niedokładności, coraz większe dla większych kątów.
typ long long -263÷ 263 - 1, zawiera liczby z przedziału [-9223372036854775808, 9223372036854775807]
wszystkie pętle za pomocą WHILE, choć można za pomocą FOR, bo zawsze znamy koniec
1) Wczytuj z klawiatury oceny, aż do wpisania znaku zera. Na ekranie wyświetlamy za każdym razem sumę i średnią ocen.
2) Na wykonanie szkieletu prostopadłościanu zużyto 56 cm drutu. Sprawdź, jakie mogą być poszczególne długości krawędzi.
- napisz funkcję, która liczy długość drutu potrzebnego na wykonanie prostopadłościanu
- w trzech pętlach WHILE zmieniaj krawędzie 1.. 56 cm
3) Napisz funkcję, która wyliczy sumę cyfr podanej jako parametr liczby całkowitej. Wykorzystaj dzielenie całkowite i modulo oraz pętlę while.
- zmodyfikuj funkcję tak, aby potrafiła obliczać sumę dla liczb rzeczywistych
4) Napisz funkcję PIERWSZA, która sprawdza, czy podana jako parametr liczba jest pierwsza. Jako wynik otrzymujemy zero-gdy pierwsza lub dzielnik. Z jej pomocą wypisz na ekranie liczby pierwsze w zakresie 1..100
5) Co zostanie wydrukowane po wykonaniu pętli:
a) a = 1; b = 3; while (a < b) { a = 3 * a – 1; b = 2 * b + 1; } cout << a << endl << b;
b) a = 21; b = 3; while (a != b) { a = a – 1; b = b + 1; } cout << a << endl << b;
c) a = 1000; b = 1; while (a > b) { a /= 2; b *= 2; } cout << a << endl << b;
d) a = 81; b = 9; while (a != b) { if (a > b) a -= b; else b -= a; } cout << a << endl << b;
Przykładowe rozwiązania zadań
Jedynie ciężka umysłowa praca i zrozumienie działania
programu może nauczyć programowania!
//zadanie 1 cout << "SUMA i ŚREDNIA OCEN" << endl << endl; //zerujemy aby program nie liczył glupot int ile=0; float suma=0; float srednia=0; //nie musimy inicjowac, //bo za pierwszym razem wpisana wartosc z klawiatury float ocena; do { cout << "Wpisz ocenę (0-koniec): "; cin >> ocena; if (ocena >= 1 && ocena <= 6){ ile=ile+1; suma=suma+ocena; srednia=suma/ile; } } while (ocena != 0); cout << "Ilość ocen: " << ile << endl; cout << "Suma ocen: " << suma << endl; cout << fixed << setprecision(2); cout << "Średnia ocen: " << srednia << endl; |
//zadanie 2 int DRUT(int a, int b, int c){ return 4*(a+b+c); } ... //zadanie 2 cout << "SZKIELET PROSTOPADŁOŚCIANU" << endl; cout << "długość krawędzi = 56" << endl; int a=1; while (a <= 56){ int b=1; while (b <= 56){ int c=1; while (c <= 56){ if (DRUT(a,b,c) == 56){ //cout.width(6); cout << "a=" << a << " b=" << b << " c=" << c << endl; } c++; } b++; } a++; } cout << endl; |
//zadanie 3 int SumaCyfr(int liczba){ int suma=0,wynik=0; while (liczba != 0){ wynik=liczba % 10; liczba=liczba / 10; suma=suma+wynik; } return suma; } ... int liczba,wynik; do{ cout << "wpisz liczbę: "; cin >> liczba; cout << SumaCyfr(liczba) << endl; } while(liczba != 0); |
//zadanie 4 //zero - pierwsza //dzielnik - nie pierwsza int PIERWSZA(int liczba){ if (liczba<2) return 0; else{ int i=2; while (liczba%i != 0) i++; if (liczba == i) return 0; else return i; } } ... for (int i=1; i <= 100; i++) { cout.width(5); cout << i; cout.width(5); cout << PIERWSZA(i) << endl; } for (int i=1 ; i<= 100; i++) { int p=PIERWSZA(i); if (p == 0) cout << i << " "; } |
//zadanie 5 |
//SZABLON #include <stdlib.h> //system #include <iostream> //cout #include <iomanip> //fixed #include <cmath> //pow using namespace std; int main(){ setlocale(LC_ALL, ""); system("pause"); } |