Lab 3 Iteracje

background image

S t r o n a

| 1 WETI Politechnika Gdańska, POP v.1.5.2

Laboratorium 3. Iteracje

Przed zajęciami laboratoryjnymi zapoznaj się z następującymi pozycjami literatury:

1.

Wykład z przedmiotu „Podstawy programowania”

2.

J. Grębosz „Symfonia C++” tom 1. Oficyna Kallimach, Kraków, 1999

Rozdziały: 2.3, 2.4, 2.5 , 2.7, 2.9, 2.10, 4.1.

Przygotowując się do laboratorium przeanalizuj podane poniżej przykłady, odpowiedz na pytania, rozwiąż testy

i napisz odpowiednie programy. Po zajęciach zrób zadania podane w ostatnim punkcie tego opracowania.

Przykłady i pytania

1.

Instrukcje iteracyjne - trzy rodzaje pętli: while, do-while, for

Przykład L3_F0_P1 Przeanalizuj program i odpowiedz na pytania

// L3_F0_P1.cpp

// Program wypisuje liczby od 1 do 20 uzywajac petli while

#include

<iostream>

using namespace

std;

int

main()

{

int

i = 1;

// definicja i inicjalizacja zmiennej i

while

( i <= 20 )

// poczatek petli while

{
cout << i <<

" "

;

// wypisanie wartosci zmiennej i oraz spacji

i++;

// zwiekszenie i. Rownowazne z i = i + 1; albo i +=1;

}

// koniec petli while


cout << endl;

// przejscie do nowej linii

system(

"pause"

);

return

0;

}

Pytania

a)

Jak zastąpić blok ITERACJA przez równoważną instrukcję do-while?

b)

Jak zastąpić blok ITERACJA przez równoważną instrukcję for( pole1 ; pole2 ; pole3 ). Wypełnij pola.

c)

Jak zastąpić blok ITERACJA przez równoważną pętlę nieskończoną while(1) i instrukcję

break.

d)

Jak zastąpić blok ITERACJA instrukcją for

oraz instrukcją

continue, tak aby program wypisywał liczby od 20

do 1 z pominięciem liczby 13.

Skompiluj i uruchom programy i sprawdź poprawność odpowiedzi.

Odpowiedzi

a)

do

{cout << i <<

" "

; i++; }

while

( i <= 20 );

b)

for

( ; i<=20; cout << i <<

" "

, i++);

c)

while

(1){ cout << i <<

" "

;

if

(i==20)

break

; i++;}

d)

for

( i=20; i>= 1; i--) {

if

(i==13)

continue

; cout << i <<

" "

;}

background image

S t r o n a

| 2 WETI Politechnika Gdańska, POP v.1.5.2

2.

Błędy numeryczne w obliczeniach na liczbach zmiennoprzecinkowych

Przykład L3_F0_P2 Przeanalizuj program i odpowiedz na pytania

/*

* L3_F0_P2.cpp

*

* PROGRAM DWUKROTNIE OBLICZA SKONCZONA SUME CIAGU:

* S = 1./1 + 1./2 + 1./3 + 1./4 + ... + 1./n gdzie n=100000000

* Kropki po jedynkach we wzorze wskazuja, ze nie sa to obliczenia na liczbach

* calkowitych ( dla nich wynik bylby staly S=1 ).

* W pierwszej petli for sumowanie rozpoczyna si

ę

od najwiekszego skladnika sumy.

* W drugiej petli for sumowanie rozpoczyna si

ę

od najmniejszego skladnika sumy.

*/

#include

<iostream>

using namespace

std;

int

main()

{

float

fx = 0;

for

(

long int

i=1; i<=100000000; i++)

{
fx = fx + 1./i;
}

cout << fx << endl;

float

fy = 0;

for

(

long int

i=100000000; i>=1; i--)

{
fy = fy + 1./i;
}

cout << fy << endl;

system(

"pause"

);

return

0;

}


Pytania

a)

Sprawdź w Literaturze, jak są reprezentowane liczby zmiennoprzecinkowe. Czy wszystkie liczby

rzeczywiste są dokładnie reprezentowane w zapisie binarnym używanym w komputerze?

b)

Skompiluj, uruchom program i porównaj obliczone sumy. Czy obie sumy są równe? Jeżeli nie są równe, to

dlaczego?

c)

Zastąp typ float typem double, ponownie skompiluj i uruchom program. Porównaj wyniki. Który z użytych

typów liczb zmiennoprzecinkowych dokładniej reprezentuje liczby rzeczywiste?

Odpowiedzi

a)

Nie.

b)

Nie. Z powodu kumulujących się błędów numerycznych.

c)

Typ double.



background image

S t r o n a

| 3 WETI Politechnika Gdańska, POP v.1.5.2

3.

Pętle zagnieżdżone (pętle wewnątrz innych pętli)

Przykład L3_F0_P3 Program rysuje brzeg prostokąta znakami ’x’. Długości boków użytkownik podaje na

standardowym wejściu jako liczby całkowite z przedziału [2, 60].

Przeanalizuj program i odpowiedz na pytania

// L3_F0_P3.cpp

/* Program rysuje brzeg prostok

ą

ta znakami ’x’.

xxxxxxxxxxxxxxxxxxxxx

x x

x x b

x x

xxxxxxxxxxxxxxxxxxxxx

a

*/

#include

<iostream>

using namespace

std;


int

main()

{

int

a;

// dlugosc boku a

int

b;

// dlugosc boku b


// wczytaj boki: a oraz b

cout <<

"Podaj dlugosc boku a [2,60]: "

;

cin >> a;
cout <<

"Podaj dlugosc boku b [2,60]: "

;

cin >> b;

// zakładamy ze podane dane sa poprawne


for

(

int

i = 1; i <= a; i++)

cout <<

'x'

;

// rysowanie gornej linii

cout << endl;

for

(

int

j = 2; j <= b-1; j++)

// petla kolejnych wierszy - rysowanie linii bocznych

{
cout <<

'x'

;

// znak ’x’ na lewym brzegu

for

(

int

i = 2; i < a; i++)

// wypisanie a-2 spacji we wn

ę

trzu j-tego wiersza

cout <<

' '

;

cout <<

'x'

<< endl;

// znak ’x’ na prawym brzegu

}

for

(

int

i = 1; i <= a; i++)

cout <<

'x'

;

// rysowanie dolnej linii

cout << endl;

system(

"pause"

);

return

0;

}

Pytania

a)

Skompiluj i uruchom program dla (a = 60, b = 20) oraz (a = 2, b = 2). Jaka jest kolejność wypisywania

znaków na ekranie?

b)

W programie użyto 4 pętli for, przy czym pętla druga jest zagnieżdżona w pętli trzeciej. Czy ilość

zagnieżdżeń jest ograniczona? Czy można zagnieżdżać w sobie pętle różnego typu?

c)

Napisz program L3_F0_P3.cpp tak, aby użyć tylko dwóch instrukcji iteracji (można dodatkowo użyć

instrukcji warunkowych). Ponownie skompiluj i uruchom program.

Odpowiedzi

a)

Wierszami, z góry na dół. W wierszu, od lewej do prawej.

b)

Nie. Tak.

background image

S t r o n a

| 4 WETI Politechnika Gdańska, POP v.1.5.2

c)

//-------------------------------------------------------------rysowanie--------

for

(

int

y = 1; y <= b; y++)

// petla wierszy

{

for

(

int

x = 1; x <= a; x++)

// petla kolumn

{

if

( (y == 1) || (y == b) )

// pierwszy i ostatni wiersz rysujemy

cout <<

'x'

;

// jako linie ciagla ( znaki ‘x’)

else

if

( (x == 1) || (x == a) )

// pierwsza i ostatnia kolumne rowniez

cout <<

'x'

;

// rysujemy jako linia ciagla ( znaki ‘x’)

else

cout <<

' '

;

// pozostaly obszar wypelniamy spacjami

}

// koniec petli kolumn

cout << endl;

// po kazdym wierszu przejscie do nowej linii

}

//--------------------------------------------------------------------------------

Testy

1.

Co wypiszą na ekranie następujące iteracje?

a)

int

i=5;

while

(i >= 0) {

cout << i+1 <<

' '

;

i--;
}

cout << endl;

b)

int

j=8;

do

{

cout <<

'-'

;

j--;

if

(j<5)

continue

;

cout <<

'+'

;

}

while

(j);

cout << endl;

c)

int

x=1, max=1;

for

(

int

k=0; k<3 ; k+=1){

while

(x <= max) cout << x++;

cout << endl;
max++;
x=1;
}

2.

Czy poniższe pętle są równoważne, w sensie wypisywanych wyników, z iteracją z Testu 1 a)?

a)

for

(

int

i=7, k=2 ; ; k++){

cout << i-k+1 <<

' '

;

if

(k > i-1)

break

;

}

b)

int

i=5;

do

{

cout << i+1 <<

' '

; i-=1;

}

while

(i);

c)

int

k=2;

for

(k--, k--; k<6; cout << 6-k <<

' '

, k+=1);

3.

Które pętle kompilator uzna za nieprawidłowe ze względu na błędy syntaktyczne?

a)

for

(;0;)

for

(;1;)

for

(;2;);

b)

for

(

int

a=11, b=a+4; ; b-=1, cout<<b);

c)

for

(

int

a=2,,a++)

if

(a==2)

break

;

d)

while

(1)(cout <<

"hello\n"

;

break

;)

e)

do

{cout <<

"witaj\n"

;

break

;}

while

{1};

background image

S t r o n a

| 5 WETI Politechnika Gdańska, POP v.1.5.2

4.

Wskaż pętle, które nigdy się nie kończą:

Pętla 1:

int

k = 12;

while

(k){ cout <<

"Jupi!\n"

; }

Pętla 2:

for

(

int

i = 0; i < 100; i = i-2)

cout <<

":) "

;

Pętla 3:

int

progress = 1;

cout <<

"Loading, please wait"

;

do

{

cout <<

"."

;

if

(progress == 100)

break

;

progress = progress + 2;

}

while

(1);

Pętla 4:

int

j = 15;

do

{

if

(j%2 == 0) j = j-2;

else

j = j-1;

}

while

(j);

Pętla 5:

int

j = 15;

do

{

if

(j%2 == 0) j = j-2;

else

j = j-1;

}

while

(j = 8);

5.

Podaj liczby, jakie należy wczytać w poniższych pętlach, aby pętle zakończyły się:

a)

int

c, d;

do

{

cin >> c >> d;
d = d+1;
}

while

( !(c==d-3 and d==5));

b)

int

m, n;

do

{

cin >> m >> n;
}

while

( n!=m-2 or m!=5);

Odpowiedzi

Test 1:

a)

6 5 4 3 2 1

b)

-+-+-+-----

c)

1

12

123

Test 2: a) tak, b) nie, c) tak.

Test 3: a), b) – prawidłowe; c), d), e) – nieprawidłowe.

Test 4: Pętle 1, 2, 3 i 5 nie kończą się. Pętla 4 kończy się dla każdej początkowej dodatniej liczby j .

Test 5: a) c = 2, d = 4, b) m = 5, n = 3.

background image

S t r o n a

| 6 WETI Politechnika Gdańska, POP v.1.5.2

Zadania przygotowujące do laboratorium

Napisz, uruchom i przetestuj następujące programy

Zadanie L3_F0_Z1

Napisz program wyznaczający sumę n iloczynów liczb naturalnych o postaci:

= 1 ∙ 2 + 2 ∙ 3 + ⋯ + ( + 1)

gdzie n jest podawane z klawiatury przez użytkownika.

Program nie wykonuje obliczeń i podaje komunikat "Zła wartość n", gdy n nie należy do przedziału [2, 100].

Przykład:

dla n = 2 wynik jest w postaci:

= 1 ∙ 2 + 2 ∙ 3 = 6

dla n = 10 wynik jest w postaci:

= 1 ∙ 2 + 2 ∙ 3 + ⋯ + 10 ∙ 11 = 440

Polecenie: W podanym niżej szkielecie programu L3_F1_S1.cpp uzupełnij linie oznaczone przez //$$$. Nie zmieniaj

pozostałych części szkieletu.


// L3_F0_S1.cpp Suma iloczynow – Iteracja ograniczona

#include

<iostream>

using namespace

std;

int

main()

{

int

i;

// licznik petli

int

n;

// dana wejsciowa n

int

suma ;

// suma iloczynow

//---------------------------------------------------------------------------------

cout <<

"Program wyznacza sume 1*2+2*3+...+n*(n+1)"

<< endl;

cout << endl <<

"Podaj wartosc n: "

;

//$$$ wczytanie n

if

( ) {

//$$$ czy n jest poprawne?

suma = ;

//$$$

i = ;

//$$$

while

( ) {

//$$$ petla - obliczanie sumy

suma =

//$$$

i++;

// to samo co i=i+1; albo i += 1;

}
cout << endl <<

" 1*2+...+"

<< <<

'*'

<< <<

" = "

<< << endl;

//$$$

}

else

cout << endl << << endl;

//$$$

//---------------------------------------------------------------------------------

cout << endl;
system (

"pause"

);

return

0;

}

background image

S t r o n a

| 7 WETI Politechnika Gdańska, POP v.1.5.2

Rozwiązanie


// L3_F0_Z1.cpp Suma iloczynow – Iteracja ograniczona

#include

<iostream>

using namespace

std;

int

main()

{

int

i;

// indeks petli

int

n;

// dana wejsciowa n

int

suma ;

// suma iloczynow

//-----------------------------------------------------------------------------------

cout <<

"Program wyznacza sume 1*2+2*3+...+n*(n+1)"

<< endl;

cout << endl <<

"Podaj wartosc n: "

; cin >> n;

//$$$

if

( n >= 2 && n <= 100 ) {

//$$$

suma = 0 ;

//$$$

i = 1 ;

//$$$

while

( i <= n ) {

//$$$

suma = suma + i*(i+1);
i++;
}
cout << endl <<

" 1*2+...+"

<< n <<

'*'

<< n+1 <<

" = "

<< suma << endl;

//$$$

}

else

cout << endl <<

"Zla wartosc n"

<< endl;

//$$$

//------------------------------------------------------------------------------------

cout << endl;
system (

"pause"

);

return

0;

}



Zadanie L3_F0_Z2

Napisz program, który na przemian dodaje i odejmuje kolejno wczytane liczby całkowite, aż do wczytania liczby

zero. Po podaniu każdej kolejnej liczby program wyświetla aktualną sumę.


// L3_F0_Z2.cpp Program dodaje i odejmuje (na przemian) liczby - Iteracja warunkowa

#include

<iostream>

using namespace

std;

int

main( )

{

int

liczba;

int

suma = 0;

int

znak = 1;

do

{

if

(znak > 0) cout <<

"Dodaj "

;

else

cout <<

"Odejmij "

;

cout <<

"liczbe calkowita: "

;

cin >> liczba;
suma = suma + znak*liczba;
cout <<

"Suma: "

<< suma << endl << endl;

znak = -znak;
}

while

( liczba != 0 );


system(

"pause"

);

return

0;

}

background image

S t r o n a

| 8 WETI Politechnika Gdańska, POP v.1.5.2

Zadanie L3_F0_Z3

Napisz program rysujący trójkąt prostokątny równoramienny za pomocą znaku ’o’. Długość przyprostokątnych

zadaje użytkownik jako liczbę całkowitą w zakresie od 1 do 30. Program sprawdza poprawność wczytanej liczby.

Przykład: Wynik działania programu dla n = 7

ooooooo
oooooo
ooooo
oooo
ooo
oo
o


// L3_F0_Z3.cpp Rysowanie Trojkata - Petle zagniezdzone

#include

<iostream>

using namespace

std;

int

main()

{

char

znak =

'o'

;

int

n;

// licznik linii = dlugosc przyprostokatnej


cout <<

"Podaj dlugosc przyprostokatnej [1, 30]: "

;

cin >> n;

if

( (n < 1) || (n > 30) )

{
cout <<

"Blad: dlugosc przyprostokatnej spoza zakresu"

<< endl;

system(

"pause"

);

exit(0);
}

// ----------------------------------------------------------rysowanie-------

while

(n) {

// petla liczaca linie, petla trwa dopoki n rozne od zera

for

(

int

i = 1; i <= n; i++)

cout << znak;

// petla rysujaca jedna linie

cout << endl;

// przejdz do nastepnej linii

n--;

// zmniejsz licznik n = n-1;

}

system(

"pause"

);

return

0;

}


Zadanie L3_F0_Z4

Niech

= 1

oraz

=

+

1

Dla danego n (liczba naturalna, 0 < n < 11) obliczyć n pierwszych wyrazów ciągu liczb rzeczywistych

, … , oraz

wyświetlić je w kolejnych liniach na ekranie z dokładnością 4 miejsc po przecinku.

Przykład:

Wej

ś

cie:

Wyj

ś

cie:

3

2.0000

4.5000

13.8333

background image

S t r o n a

| 9 WETI Politechnika Gdańska, POP v.1.5.2


//L3_F0_Z4.cpp - Wypisywanie wyrazow ciagu wg wzoru

#include

<iostream>

#include

<iomanip>

using namespace

std;

int

main ()

{

int

n, i=1;

double

a=1;


cout <<

"Podaj n : "

;

cin >> n;

if

( n<=0 || n>=11 )

{
cout <<

"zle dane\n\n"

;

system(

"PAUSE"

);

exit(0);
}

cout << fixed << setprecision(4);

while

(n--)

{

// wartosc a po prawej stronie wyrazenia jest elem. ciagu z poprzedniej iteracji,

a = a*i + 1./i;

// natomiast po lewej stronie jest elementem ciagu wyznaczanym w biezacej iteracji

i = i + 1;
cout << setw(15) << a << endl;
}

system(

"PAUSE"

);

return

0;

}

Zadania do samodzielnego rozwiązania po laboratorium

Zadanie L3_F3_Z1

Oblicz przybliżoną wartość funkcji sinus dla kąta x

r

podanego w radianach jako liczba rzeczywista. Przybliżenie

wartości funkcji wyznacz na podstawie jej rozwinięcia w szereg potęgowy:

( ) = 1 − 3! +

5! −. . . =

= # + #

$

+ # +…

Iteracje są kontynuowane dopóki wyraz w

i

szeregu jest większy od zadanej dokładności eps. Skorzystaj z faktu, że

# = &

'(

= 1

−1 ∙

#

−1

2

(2 − 2)(2 − 1)

'(

> 1

*

co oznacza, że kolejny wyraz szeregu można obliczyć na podstawie wartości wyrazu poprzedniego.

Wejście: x

r

oraz eps (obie liczby rzeczywiste np. x

r

= 30.0, eps = 1e-8).

Wyjście: wartości funkcji sinus wyznaczone odpowiednio na podstawie szeregu oraz przy pomocy funkcji sin

z biblioteki <cmath>. Obie liczby wypisz w formacie wykładniczym (10 miejsc po przecinku). Podaj liczbę

wyrazów szeregu większych od eps.

Testując program porównaj wyniki dla różnych wartości eps.

background image

S t r o n a

| 10 WETI Politechnika Gdańska, POP v.1.5.2

Zadanie L3_F3_Z2

Napisz program tablicujący funkcję sinus w zakresie od 0 do 360 stopni z krokiem 5 stopni. Obok wartości kąta

w stopniach oraz wartości funkcji wypisywanych w równych kolumnach, z lewej strony ekranu należy dodatkowo

rysować szkic wykresu funkcji wykorzystując znak ’*’ (patrz rysunek). Przesunięcie gwiazdki o odpowiednią ilość

znaków wylicz na podstawie wartości funkcji. Przyjmij, że przedział [-1,1], do którego należą wartości funkcji,

odpowiada 60 znakom na ekranie.

Przykład:

x sin(x) -1 0 1

-----------------------------------------------------------------------------

0.000 0.000 *

5.000 0.087 *

10.000 0.174 *

15.000 0.259 *

20.000 0.342 *

25.000 0.423 *

30.000 0.500 *

. . . .

. . .

Zadanie L3_F3_Z3

Ciąg Collatz’a jest ciągiem danym następującym wzorem

+

,

= -

1

2 +

.'/+ 01 23 45/ 2

3+ + 1 .'/+ 01 2 13 45/ 2

*

Zauważ, że kolejne wyrazy ciągu Collatz’a mogą przyjmować różne wartości w zależności od wartości pierwszego

wyrazu c

0

.

Przykład:

c

0

= 20 C

20

= (20, 10, 5, 16, 8, 4, 2, 1)

c

0

= 19 C

19

= (19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, . . . , 1)

c

0

= 18 C

18

= (18, 9, 28, 14, 7, 22, . . . , 1)

Napisz program, który wypisuje elementy ciągu Collatz’a zaczynającego się od podanej na wejściu programu

liczby całkowitej c

0

będącej pierwszym wyrazem ciągu. Program powinien zakończyć wypisywanie, gdy wartość

kolejnego wyrazu będzie miała wartość równą 1.

Zadanie L3_F3_Z4

Hipoteza Collatz’a mówi, że niezależnie od jakiej liczby c

0

zaczniemy, zawsze dojdziemy do wyrazu o wartości

równej 1. Napisz program, który dla każdego 1 < c

0

< 10

4

sprawdza, czy hipoteza Collatz’a jest prawdziwa.

Hipotezę udowodniono dotychczas dla liczb mniejszych niż 20*2

58

. Program powinien wyznaczyć c

0

, z podanego

powyżej zakresu, dla którego wygenerowany ciąg ma najwięcej elementów oraz podać liczbę tych elementów.

Zastanów się czy jest gwarancja, że program, który napisałeś w zadaniu L3_F3_Z3 jest poprawny? Czy zatrzyma

się on dla każdych danych wejściowych? Jeżeli nie, to jak można zabezpieczyć się przed jego ewentualnym

„zapętleniem”, czyli nieskończonym działaniem?


Wyszukiwarka

Podobne podstrony:
Lab 3 Iteracje
Lab 3 Iteracje
spis lab I sem 2010
III WWL DIAGN LAB CHORÓB NEREK i DRÓG MOCZ
Diagnostyka lab wod elektrolit
ZW LAB USTAWY, OCHRONA
LAB PROCEDURY I FUNKCJE
sprzet lab profilografy
sprzet lab mikromanometry
Mechanika Plynow Lab, Sitka Pro Nieznany
Lab 02 2011 2012
PO lab 5 id 364195 Nieznany
lab pkm 4
MSIB Instrukcja do Cw Lab krystalizacja
lab [5] id 258102 Nieznany
lab 8 9 1
lab 3 2 9

więcej podobnych podstron