jezyk C skrypt cz 2

background image

III. Przykłady programów w języku C/C++ i zadania

1. Proste algorytmy i programy komputerowe

W rozdziale tym przedstawiono rozwiązania najprostszych zadań z zakresu

programowania, których celem jest praktyczne zapoznanie studenta z

podstawowymi funkcjami i instrukcjami języka C/C++. Dodatkowym

zamierzeniem autorów w tym etapie nauki programowania, było wykształcenie

u czytelnika zasad myślenia algorytmicznego oraz niezbędnej przy

programowaniu dokładności. Dlatego istotną częścią zadań w tym rozdziale są

sieci działań programów (schematy blokowe) będące graficznym obrazem toku

czynności przetwarzania danych według danego programu.

Przedstawione algorytmy, jak i zamieszczone wskazówki i zalecenia nie należy

rozumieć jako jedyne i najlepsze rozwiązania w danym przypadku. Zadania

mają służyć do ćwiczeń i nauki pewnego sposobu myślenia, a nie podania

uniwersalnych sposobów programowania. W pewnych przypadkach w celu

pokazania jakiejś konstrukcji programowej na możliwie prostym przykładzie

zrezygnowano z optymalności rozwiązania. Dla udokumentowania powyższych

faktów w kilku przykładach przedstawiono alternatywne możliwości

rozwiązania danego zagadnienia, pozostawiając studentom dokonania próby

określenia warunków, w których taki czy inny sposób będzie lepszy.

Rozwiązanie każdego zadania zawiera schemat blokowy algorytmu oraz tekst

ź

ródłowy programu w języku C.

Zadanie 1.

Dane są rozłączne przedziały [a,b], [c,d], [e,f] na osi x. Określić numer

przedziału, do którego należy dana wartość zmiennej x. Gdy wartość ta nie

należy do żadnego z przedziałów, podać nr = 0.

Dane: a,b,c,d,e,f,x (liczby zmiennoprzecinkowe, typ float).

background image

Tekst programu:

#include <stdio.h>

float a,b,c,d,e,f,x;

int nr;

main()

{

printf("x=");scanf("%f",&x);

printf("a=");scanf("%f",&a);

printf("b=");scanf("%f",&b);

printf("c=");scanf("%f",&c);

printf("d=");scanf("%f",&d);

printf("e=");scanf("%f",&e);

printf("f=");scanf("%f",&f);

background image

if ((x>a) && (x<b)) nr=1; else

if ((x>c) && (x<d)) nr=2; else

if ((x>e) && (x<f)) nr=3; else nr=0;

printf("nr=%d",nr);

return;

}

Zadanie 2

Dany jest n-wymiarowy wektor V {n}. Ułożyć program wyznaczający długość

L tego wektora.

Dane:

n (int)

V

1

, V

2

, ..., V

n

(float)

Uwagi do algorytmu

Długość wektora V=[

V

1

, V

2

, ..., V

n

] oblicza się ze wzoru:

=

=

n

i

i

V

L

1

2

background image

Tekst programu:

#include <stdio.h>

#include <math.h>

int n,i;

float s,l;

float v[100];

main()

{

printf("n=");

scanf("%d",&n);

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

{

printf("V[%d]=",i);

scanf("%f",&v[i]);

}

s=0;

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

s=s+v[i]*v[i];

l=sqrt(s);

printf("Dlugosc L = %f",l);

return;

}

Zadanie 3

Obliczyć wartość całki S =

dx

x

b

b

3

metodą trapezów przyjmując podział odcinka

ab na 100 równych części.

Dane:

a,b (float)

background image

Uwagi do algorytmu

,

100

1

=

=

i

i

S

S

,

2

1

h

y

y

s

i

i

i

+

100

a

b

h

=

W pętli wyznaczone i sumowane są pola stu trapezów. pola te obliczane są z

tego samego wzoru, przy czym przy plou następnym rzędna y

i

staje się rzedną

y

i-1

. Fakt ten wykorzystano w programie, aby nie przeprowadzać obliczania tej

rzędnej.

background image

Tekst programu:

#include <stdio.h>

int i;

float a,b,s,y,yn,h,x;

main()

{

printf("a=");scanf("%f",&a);

printf("b=");scanf("%f",&b);

h=(b-a)*0.01;

s=0;

y=a*a*a;

for (i=1;i<=100;i++)

{

x=a*i*h;

yn=x*x*x;

s=s+(y+yn)*h/2;

y=yn;

}

printf("S=%f",s);

}

Zadanie 4

Ułożyć program obliczający sumę S elementów o wskaźnikach parzystych

macierzy prostokątnej A{m,n}.

Dane: m, n (int)

A [m][n] (float)

Uwagi do algorytmu

W przypadku macierzy A{4,5}:

background image

=

45

45

43

42

41

35

35

33

32

31

25

24

23

22

21

15

14

13

12

11

a

a

a

a

a

a

a

a

a

a

a

a

a

a

a

a

a

a

a

a

A

Suma elementów o indeksach parzystych wynosi:

S = a

22

+ a

24

+ a

42

+ a

44

Wybór odpowiednich elementów macierzy określenia odpowiednich wartości

indeksów, zadanych przez zmienne sterujące pętli i,j. Wartości parzyste tych

zmiennych uzyskamy przez przyjęcie zarówno wartości początkowej, jak i

kroku równego liczbie 2.

Tekst programu:

#include <stdio.h>

int i,k,m,n;

float s;

float a[50][50];

main()

background image

{

printf("m=");scanf("%d",&m);

printf("n=");scanf("%d",&n);

for (i=1;i<=m;i++)

for (k=1;k<=n;k++)

{

printf("a[%d][%d]=",i,k);

scanf("%f",&a[i][k]);

}

s=0;

for (i=2;i<=n;i=i+2)

for (k=2;k<=n;k=k+2)

s=s+a[i][k];

printf("S=%f",s);

return;

}

Innym sposobem zapisu dwóch pętli z krokiem 2 jest wykorzystanie instrukcji

do ... while. Poniżej zamieszczono program oparty o konstrukcję while...do:

#include <stdio.h>

int i,k,m,n;

float s;

float a[50][50];

main()

{

printf("m=");scanf("%d",&m);

printf("n=");scanf("%d",&n);

for (i=1;i<=m;i++)

for (k=1;k<=n;k++)

{ printf("a[%d][%d]=",i,k);

scanf("%f",&a[i][k]);

}

background image

s=0;

i=0;

do

{

i+=2;

k=0;

do

{

k+=2;

s=s+a[i][k];

}

while (k<=n);

}

while (i<=m);

printf("S=%f",s);

return;

}

Możliwe jest również rozwiązanie zadania z zastosowaniem pętli while.

Najczęściej jednak z pętli tej korzystamy wtedy, gdy nie jest znana liczba

powtórzeń i być może pętla nie będzie wykonana.

Zadanie 5

Ułożyć program, który w danej macierzy kwadratowej o elementach

całkowitych A{n,n} oblicza iloczyny p i q elementów znajdujących się na obu

przekątnych oraz sumę s elementów k-tej kolumny (k<n).

Dane:

n,k (int),

a[n][n] (float)

background image

Uwagi do algorytmu

p

 s  q 

nn

nk

n

n

n

k

n

k

a

a

a

a

a

a

a

a

a

a

a

a

...

...

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

...

...

...

...

2

1

2

2

22

21

1

1

12

11

Ponieważ każdą z poszukiwanych wartości tworzy ta sama liczba elementów,

wszystkie operacje są wykonywane w jednej pętli. Dobór pożądanych

elementów odbywa się przez odpowiednie operacje na indeksach.

background image

#include <stdio.h>

int i,j,n,k2;

float s,p,q;

float a[50][50];

main()

{

printf("n=");scanf("%d",&n);

printf("k=");scanf("%d",&k);

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

for (j=1;j<=n;j++)

{

printf("a[%d][%d]=",i,j);

scanf("%f",&a[i][j]);

}

p=q=1;

s=0;

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

{

s+=a[i][k];

q*=a[i][n+1-i];

p*=a[i][i];

}

printf("S=%f\tq=%f\tp=%f",s,q,p);

return;

}

background image

Zadanie 6

Napisać program obliczający liczbę D elementów dodatnich, liczbę Z zer i

liczbę U elementów ujemnych w zbiorze n liczb całkowitych (n<1000).

Dane

a[n] (int)

Tekst programu:

#include <stdio.h>

int z,d,u,i,n;

int a[1000];

background image

main()

{

printf("n=");

scanf("%d",&n);

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

{

printf("a[%d]=",i);

scanf("%d",&a[i]);

}

d=u=z=0;

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

if (a[i]>0) d++; else if (a[i]<0) u++; else z++;

printf("Ilosc liczb ujemnych: %d\n",u);

printf("Ilosc liczb dodatnich: %d\n",d);

printf("Ilosc zer: %d\n",z);

return;

}

Zadanie 7.

Obliczyć w punkcie x sumę szeregu trygonometrycznego:

...,

cos

...

2

cos

cos

2

+

+

+

+

ix

x

x

e

ix

e

x

e

x

z zadaną dokładnością

ε

. Obliczenia należy zakończyć dopiero, gdy powyższy

warunek będą spełniać trzy kolejne sumy. Dodatkowo podać n wyrazów

tworzących szukaną sumę.

Dane

x (float)

background image

Uwagi do algorytmu

Rozwiązanie zadania sprowadza się do zastosowania typowego algorytmu na

obliczanie sumy, z uwzględnieniem warunków podanych w zadaniu:

=

=

n

i

ix

e

ix

S

1

cos

gdy jednocześnie:

,

0

cos

<

jx

e

jx

j=n-2, n-1, n

background image

Tekst programu:

#include <stdio.h>

#include <math.h>

int i,n;

float x,s,s1,x1,eps;

main()

{

printf("x=");scanf("%f",&x);

printf("Dokladnosc obliczen, EPS=");

scanf("%f",&eps);

n=0;

s=0.0;

i=0;

do

{

i++;

x1=x*i;

s1=cos(x1)/exp(x1);

s=s+s1;

if (s1<eps) n++; else n=0;

}

while (n<3);

printf("i=%d\n",i);

printf("S=%f\n",s);

return;

}

background image

Zadanie 8

Na płaszczyźnie 0XY dany jest dowolny wielobok zamknięty, którego

wierzchołki A

1

, A

2

, A

3

, ..., A

n

określone są przez współrzędne (x

1

, y

1

),...,(x

n

, y

n

).

Ułożyć program na obliczenie pola powierzchni S tego wieloboku. Ułożyć

program na obliczenie pola powierzchni S tego wieloboku. Położenie

wierzchołka A

1

jest dowolne, a numery następnych wierzchołków występują

kolejno zgodnie z dodatnią orientacją płaszczyzny 0XY (zwykle lewostronnie).

Dane

n (int)

x[n] ,y[n] (float)

Uwagi do algorytmu

Punkt 0 z każdym z boków wielokąta tworzy n trójkątów:

0A

1

A

2

,

0A

2

A

3

, ...,

0A

n-1

A

n

,

0A

n

A

1

. Ich pole powierzchni opisuje wzór:

=

=

+

+

+

+

1

1

1

det

2

1

1

1

0

0

0

det

2

1

i

i

i

i

i

j

i

i

i

y

x

y

x

y

x

y

x

P

background image

Jeżeli kierunek opisu trójkata jest zgodny z orientacją układu, to ze wzoru

otrzymujemy wartość dodatnią i odwrotnie. Suma pól trójkątów z

uwzględnieniem znaków daje szukane pole wielokąta.

=

=

n

i

P

S

1

Ponieważ współrzędne punktu A

1

wchodzą do opisu zarówno pierwszego jak i

ostatniego trójkąta, należy więc tak przygotować tablicę X, Y w celu pamiętania

danych, aby współrzędne punktu A

1

były zarówno na 1 jak i na n+1 pozycji.

Tekst programu:

#include <stdio.h>

int i,n;

float s;

float x[50],y[50];

background image

main()

{

printf("n=");scanf("%d",&n);

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

{

printf("x[%d]=",i);

scanf("%f",&x[i]);

printf("y[%d]=",i);

scanf("%f",&y[i]);

}

x[n+1]=x[1];

y[n+1]=y[1];

s=0;

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

s+=x[i]*y[i+1]-x[i+1]*y[i];

s*=0.5;

printf("Pole powierzchni wieloboku = %f\n",s);

return;

}

Zadanie 9

Ułożyć program, który w danej macierzy kwadratowej o elementach

całkowitych A{n,n} znajduje element o wartości maksymalnej znajdujący się w

części macierzy nad główną przekątną.

Dane:

n (int),

a[n][n] (float)

background image

Tekst programu:

#include <stdio.h>

int i,j,n;

float a[50][50];

float max;

main()

{

printf("n=");scanf("%d",n);

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

for (j=1;j<=n;j++)

{

printf("a[%d][%d]=",i,j);

background image

scanf("%f",&a[i][j]);

}

max=a[1][2];

for (i=1;i<=n-1;i++)

for (j=i+1;j<=n;j++)

if (a[i][j]>max) max=a[i][j];

printf("Max = %f",max);

return;

}

Zadanie 10

Opracować program, który w zadanym n - elementowym zbiorze liczb

całkowitych (n>0) znajduje wartość występującą najczęściej, oraz liczbę jej

wystąpień. Jeżeli dwie różne wartości zbioru występują w nim tyle samo razy, to

można wybrać którąkolwiek z nich.

Dane:

n (int), zbior[100] (int)

background image

W przedstawionym algorytmie wywoływana jest funkcja o nazwie ile_razy,

której schemat blokowy jest następujący:

Tekst programu:

#include <stdio.h>

#include <conio.h>

int i,n,max,element;

int zbior[100];

int ile_razy(int element); /*deklaracja funkcji*/

main()

{

clrscr(); /*czyszczenie ekranu*/

printf("n=");

scanf("%d",&n);

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

background image

{

printf("zbior[%d]=",i);

scanf("%d",&zbior[i]);

}

max=ile_razy(zbior[1]);

element=zbior[1];

for (i=2;i<=n;i++)

{

if (ile_razy(zbior[i])>max)

{

max=ile_razy(zbior[i]);

element=zbior[i];

}

}

printf("W zbiorze najczesciej wystepowala liczba:

%d\n",element);

printf("Liczba wystapien wynosi: %d\n",max);

return;

}

int ile_razy(int element)

{

int i,znaleziono;

znaleziono=0;

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

if (element==zbior[i])

znaleziono++;

return (znaleziono);

}

background image

Zadanie 11

W danym zbiorze liczb naturalnych znaleźć najdłuższy podciąg liczb

parzystych.

Dane

n (int), a[100] (int).

background image

Treść programu:

#include <stdio.h>

#include <conio.h>

int i,j,n,max_dlug,dlugosc;

int podciag[100],max_podciag[100],a[100];

main()

{

clrscr();

printf("n=");scanf("%d",&n);

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

{

printf("a[%d]=",i);

scanf("%d",&a[i]);

}

max_dlug=0;

dlugosc=0;

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

if (a[i]%2==0)

{

dlugosc++;

podciag[dlugosc]=a[i];

if (dlugosc>max_dlug)

{

max_dlug=dlugosc;

for (j=1;j<=dlugosc;j++)

max_podciag[j]=podciag[j];

}

}

else dlugosc=0;

background image

printf("Najdluzszy podciag ma: %d",max_dlug);

printf("elementow\n");

for (i=1;i<=max_dlug;i++)

printf("a[%d]=%d\n",i,max_podciag[i]);

return;

}

Zadanie 12.

Analizując ciąg liczb naturalnych od 1 do 1000, znaleźć podciąg 9 liczb taki, że

nie ma wśród nich liczby pierwszej.

background image

W przedstawionym algorytmie występuje wywołanie funkcji liczba_pierwsza,

której zadaniem jest sprawdzenie czy liczba całkowita będąca parametrem tej

funkcji jest liczbą pierwszą. Funkcja ta zwraca wartość 1 gdy liczba jest liczbą

pierwszą oraz wartość o gdy liczba nie jest liczbą pierwszą. Schemat blokowy

tej funkcji przedstawiono poniżej:

Tekst programu:

#include <stdio.h>

#include <conio.h>

int znaleziono,i;

int podciag[10];

int liczba_pierwsza(int liczba);

main()

{

clrscr();

i=2;

znaleziono=0;

background image

do

{

i++;

if (!liczba_pierwsza(i))

{

znaleziono++;

podciag[znaleziono]=i;

}

else znaleziono=0;

}

while (znaleziono<=9);

for (i=1;i<=9;i++)

printf("%d ",podciag[i]);

return;

}

int liczba_pierwsza(int liczba)

{

int i,prawda;

prawda=1;

i=1;

do

{

i++;

if ((liczba % i)==0) prawda=0;

}

while (i<liczba-1);

return (prawda);

}


background image

2. Programy z zagadnień rachunku macierzowego

Zadanie 13.

Opracować program generujący wartości elementów macierzy kwadratowej

stopnia n-tego (n<=10).

Dane:

n (int)

Uwagi do programu

Generowanie wartości elementów macierzy odbywa się poprzez użycie funkcji

random(int zakres), która losuje wartość całkowitą z przedziału 0-zakres.

Użycie tej funkcji wymaga przyłączenia piku nagłówkowego stdlib.h. Przed

pierwszym użyciem funkcji random() należy wywołać funkcję randomize(),

która inicjuje generator liczb pseudolosowych.

Tekst programu:

#include<iostream.h>;

#include<conio.h>;

#include<stdlib.h>;

int i,j,n;

int a[10][10];

void main(void)

{

clrscr();

gotoxy(1,1);

do

{

cout<<"Podaj stopien macierzy:";

cin>>n;

}

background image

while (n>10);

clrscr();

randomize();

for (i=0;i<n;i++)

for (j=0;j<n;j++)

{

a[i][j]=random(100);

gotoxy((i+1)*7,j+2);

cout<<a[i][j];

};

cout<<"\nKONIEC !!!";

getch(); // zatrzymanie programu do czasu

// nacisniecia klawisza

return;

}

Ponieważ plik zawiera funkcje języka C++ np. cout i cin, uruchamiany program

w środowisku Borland C++ należy zapisać w pliku o rozszerzeniu .cpp.

Zadanie 14

Napisać program w języku C++ wczytujący dwie macierze kwadratowe A i B

stopnia 3 i wyznaczający macierz C stanowiącą sumę tych dwóch macierzy.

Dane

macierzA[5][5], macierzB[5][5] (int)

Tekst programu:

#include <iostream.h>

#include <conio.h>

int main()

{

const rozmiar=3;

background image

int macierzA[rozmiar][rozmiar];

int macierzB[rozmiar][rozmiar];

int macierzC[rozmiar][rozmiar];

clrscr();

cout<<"\nWprowdz wartosci macierzy A :"<<endl;

for(int a=0; a<rozmiar; a++)

{

cout<<"rzad "<<a+1<<":"<<endl;

for(int b=0; b<rozmiar; b++)

{

cin>>macierzA[a][b];

}

}

cout<<"Wprowdz wartosci macierzy B :"<<endl;

for(int c=0; c<rozmiar; c++)

{

cout<<"rzad "<<c+1<<":"<<endl;

for(int d=0; d<rozmiar; d++)

{

cin>>macierzB[c][d];

}

}

for(int i=0; i<rozmiar; i++)

{

for(int j=0; j<rozmiar; j++)

{

macierzC[i][j]=0;

for(int k=0; k<rozmiar; k++)

{

background image

macierzC[i][j] += macierzA[i][k] * macierzB[k][j];

}

}

}

cout<<"Macierz wynikowa C: "<<endl;

for(i=0;i<rozmiar;i++)

{

for(int j=0;j<rozmiar;j++)

{

cout<<macierzC[i][j]<<" ";

}

cout<<"\n";

}

getch();

return 0;

}

Zadanie 15

Obliczyć iloczyn macierzy prostokątnej X{m,n} przez macierz prostokątną

Y{n,p}.

Dane:

m,n,p (int)

x[m][n], y[n][p] (float)

Uwagi do algorytmu

W wyniku iloczynu:

=

np

n

n

p

p

mn

m

m

n

n

y

y

y

y

y

y

y

y

y

x

x

x

x

x

x

x

x

x

...

...

...

...

...

...

...

*

...

...

...

...

...

...

...

2

1

2

22

21

1

12

11

2

1

2

22

21

1

12

11

background image

otrzymujemy macierz o m. wierszach i p kolumnach Z{m,p}, której elementy są

określone wzorami:

=

=

n

j

jk

ij

ik

y

x

z

1

dla i=1,2,...m; k=1,2,...,p

Tekst programu:

#include <stdio.h>

int i,j,k,n,m,p;

float x[10][10],y[10][10],z[10][10];

main()

{

printf("n=");scanf("%d",&n);

printf("m=");scanf("%d",&m);

printf("p=");scanf("%d",&p);

background image

for (i=1;i<=m;i++)

for (j=1;j<=n;j++)

{

printf("x[%d][%d]=",i,j);

scanf("%f",&x[i][j]);

}

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

for (j=1;j<=p;j++)

{

printf("y[%d][%d]=",i,j);

scanf("%f",&y[i][j]);

}

for (i=1;i<=m;i++)

for (k=1;k<=p;k++)

{

z[i][k]=0;

for (j=1;j<=n;j++)

z[i][k]+=x[i][j]*y[j][k];

printf("z[%d][%d]=%f\n",i,k,z[i][k]);

}

return;

}

Dla tego zadania opracowany został również program w języku C++, w którym

wprowadzono zdefiniowaną funkcję o nazwie mnoz_w_k. Parametrami tej

funkcji są numer wiersza pierwszej macierzy oraz numer kolumny drugiej

macierzy. Funkcja zwraca wartość obliczonego elementu macierzy wynikowej

będącego sumą iloczynów elementów w i-tym wierszu macierzy pierwszej oraz

w j-tej kolumnie macierzy drugiej.

Zarówno macierze wejściowej jak i macierz wynikowa są prezentowana na

ekranie w bardzo czytelny sposób dzięki wykorzystaniu funkcji gotoxy.

background image

#include<iostream.h>;

#include<conio.h>;

int macierz1[10][10],macierz2[10][10];

int i,j,n;

int mnoz_w_k(int i,int j)

{ int x,suma=0;

for (x=0;x<n;x++)

suma=suma+macierz1[i][x]*macierz2[x][j];

return(suma);

};

void main(void)

{ clrscr();

gotoxy(1,1);

cout<<"Podaj stopien macierzy:";

cin>>n;

gotoxy(1,3);

cout<<"Podaj wyrazy macierzy pierwszej:";

for (i=0;i<n;i++)

for (j=0;j<n;j++)

{ gotoxy(j*4+1,i*2+4);

cin>>macierz1[i][j];

};

gotoxy(1,3);

cout<<"Podaj wyrazy macierzy drugiej: ";

for (i=0;i<n;i++)

for (j=0;j<n;j++)

{ gotoxy(j*4+31,i*2+4);

cin>>macierz2[i][j];

};

background image

gotoxy(1,12);

cout<<"Wynik pomnozenia tych dwoch macierzy:";

for (i=0;i<n;i++)

for (j=0;j<n;j++)

{ gotoxy(j*4+1,i*2+14);

cout<<mnoz_w_k(i,j);

};

getch();

};

Zadanie 16

Opracować program służący do rozwiązywania układu równań linowych metodą

eliminacji Gaussa. Układ N równań linowych:

n

n

nn

n

n

n

b

x

a

x

a

b

x

a

x

a

=

+

+

=

+

+

...

...

..........

..........

..........

...

1

1

1

1

1

11

jest określony przez macierz A{n,n} oraz wektor B{n}.

Dane

n (int)

A[n][n] (float)

B[n] (float)

Uwagi do algorytmu

Metoda Gaussa polega na takim systematycznym przekształcaniu nieosobliwej

macierzy A (niezerowy wyznacznik), aby na diagonali zostały tylko jedynki,

pozostałe zaś elementy były zerowe. Wtedy przekształcony wektor B jest

szukanym rozwiązaniem układu równań. W programie zastosowano

uproszczony wariant metody Gaussa, sprowadzający macierz A do postaci

trójkątnej, skąd łatwo już metodą podstawiania można uzyskać rozwiązanie

układu równań liniowych. Gdy macierz A jest osobliwa, a wektor B niezerowy,

wówczas brak jest rozwiązań układu równań, o czym program informuje

background image

komunikatem „brak rozwiązań nietrywialnych”. W przypadku szukania

rozwiązania układu równań jednorodnych (wektor B zerowy), gdy macierz jest

nieosobliwa, program znajdzie rozwiązanie zerowe (w granicach dokładności

numerycznej). Gdy macierz A jest osobliwa, istnieje nieskończenie wiele

rozwiązań, ale program nie potrafi ich znaleźć, informuje więc również o

„braku rozwiązań nietrywialnych”.

background image

background image

Tekst programu:

#include<stdio.h>

#include<conio.h>

#include<math.h>

#include<stdlib.h>

int n,i,j,n1,r,i1,k;

float a[6][6],b[6],x[6];

float m,s;

background image

main()

{

clrscr();

n=0;

do {

gotoxy(10,10);

printf("Ilosc niewiadomych: n=");

scanf("%d",&n);

if (n>5) {gotoxy(40,10);

printf("n<=5");}

}

while (n>5);

clrscr();

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

{

for (j=1;j<=n;j++)

{ gotoxy(3+(j-1)*12,i+1);

printf("a[%d,%d]=",i,j);

scanf("%f",&a[i][j]); }

gotoxy(3+n*12,i+1);

printf("b[%d]=",i);

scanf("%f",&b[i]);

}

n1=n-1;

for (i=1;i<=n1;i++)

{

r=i;

m=a[i][i];

i1=i+1;

for (j=i1;j<=n;j++)

if (abs(a[j][i])>abs(m)) r=j;

background image

if (m==0)

{clrscr();

gotoxy(10,10);

puts("Brak rozwiazan nietrywialnych !!!");

exit(0);}

if (r!=i)

{for (k=1;k<=n;k++)

{s=a[i][k];

a[i][k]=a[r][k];

a[r][k]=s;}

s=b[i];

b[i]=b[r];

b[r]=s;

}

for (j=i1;j<=n;j++)

{ m=a[j][i]/a[i][i];

for (k=1;k<=n;k++)

a[j][k]-=m*a[i][k];

b[j]-=m*b[i]; }

}

if (a[n][n]==0)

{clrscr();

gotoxy(10,10);

puts("Brak rozwiazan nietrywialnych !!!");

exit(0);}

x[n]=b[n]/a[n][n];

for (i=n1;i>=1;i--)

{

s=0;

i1=i+1;

for (j=i1;j<=n;j++)

background image

s+=x[j]*a[i][j];

x[i]=(b[i]-s)/a[i][i];

}

clrscr();

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

{gotoxy(5,i+2);

printf("X[%d]=%f",i,x[i]);}

return;

}

Zadanie 17

Opracować program służący do obliczania wyznacznika macierzy kwadratowej

A{n,n} oraz do znajdowania macierzy odwrotnej X[n,n]. Wymienione macierze

muszą spełniać równanie:

A * X = I

gdzie: I jest macierzą jednostkową (tylko jedynki na diagonali);

Uwagi do algorytmu

Powyższe równanie można zapisać w postaci wektorowej:

A * x

i

= e

i

i=1,...,N

gdzie:

x

i

oznacza wektor zbudowany z i-tej kolumny macierzy X,

e

i

jest wektorem mającym jedynkę na i-tek pozycji oraz zerowe pozostałe

elementy.

W ten sposób problem odwracania macierzy został sprowadzony do problemu

rozwiązania N układów N równań liniowych. W tym celu program

wykorzystuje metodę eliminacji Gaussa, opisaną w zadaniu nr 16.

Dane

n (int)

a[n][n] (float)

background image

Tekst programu:

#include<stdio.h>;

#include<stdlib.h>;

#include<math.h>;

#include<conio.h>

int n,i,j,k,i1,i2;

float a[10][10];

float t,w;

int p[10];m[10][2];

void wydruk_macierzy(int x ,int y);

main()

{

do

{

clrscr();

gotoxy(1,1);

printf("Wymiar macierzy N: ");

scanf("%d",&n);

}

while(n>10);

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

for (j=1;j<=n;j++)

{

gotoxy(1,3);

puts(" ");

gotoxy(1,3);

printf("a[%d,%d]=",i,j);

scanf("%f",&a[i][j]);

}

background image

clrscr();

wydruk_macierzy(1,1);

w=1;

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

p[i]=0;

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

{

t=0.0;

for (j=1;j<=n;j++)

if (p[j]!=1)

{

for (k=1;k<=n;k++)

if ((p[k]!=1)||(abs(t)<abs(a[j][k])))

{

i1=j;

i2=k;

t=a[j][k];

}

}

p[i2]+=1;

if (i1!=i2)

{

w=-w;

for (j=1;j<=n;j++)

{

t=a[i1][j];

a[i1][j]=a[i2][j];

a[i2][j]=t;

}

}

m[i][1]=i1;

background image

m[i][2]=i2;

t=a[i2][i2];

w*=t;

a[i2][i2]=1;

for (j=1;j<=n;j++)

a[i2][j]=a[i2][j]/t;

for (j=1;j<=n;j++)

if (j!=i2)

{

t=a[j][i2];

a[j][i2]=0;

for (k=1;k<=n;k++)

a[j][k]-=a[i2][k]*t;

}

}

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

{

j=n-i+1;

i1=m[j][1];

i2=m[j][2];

if (i1!=i2)

{

for (k=1;k<=n;k++)

{

t=a[k][i1];

a[k][i1]=a[k][i2];

a[k][i2]=t;

}

}

}

gotoxy(2,n+3);

background image

printf("Wyznacznik W=%4.4f",w);

wydruk_macierzy(1,n+5);

return;

}

void wydruk_macierzy(int x ,int y)

{

int i,j;

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

for (j=1;j<=n;j++)

{

gotoxy(x+j*7,y+i);

printf("%3.3f",a[i][j]);

}

return;

}

Zadanie 18

Opracować program służący do diagonalizacji macierzy symetrycznej w celu

wyznaczenia wartości własnych i obliczający wektory własne.

Dane:

n (int)

q[n][n] (float)

Uwagi do algorytmu

Program stosuje metodę Jacobiego, czyli metodę przekształceń unitarnych przez

obroty płaskie. Najpierw wyszukiwany jest największy element pozadiagonalny,

a następnie dokonuje takiego przekształcenia macierzy, by ten element

wyzerować. Proces ten jest powtarzany tak długo, aż moduł największego

elementu pozadiagonalnego, otrzymanego w wyniku przekształceń, będzie

mniejszy niż zadana liczba – dokładność. Przyjmuje się wtedy, że na przekątnej

background image

otrzymanej macierzy znajdują się wartości własne, równolegle zaś

przekształcana macierz jednostkowa tworzy macierz złożoną z wektorów

własnych.

Program ma charakter iteracyjny, więc wykonanie dużej liczby kroków

prowadzi do małej dokładności numerycznej. W szczególności, gdy macierz

wyjściowa ma duże elementy pozadiagonalne (w stosunku do elementów

diagonalnych), liczba iteracji może być duża, a co za tym idzie i błędy

numeryczne mogą być znaczne.

Z uwagi na złożony schemat algorytmu zawierający szereg warunków

powodujących powrót do wcześniejszych operacji, zastosowano w programie

instrukcje skoku goto.

Tekst programu:

#include<stdio.h>;

#include<stdlib.h>;

#include<math.h>;

#include<conio.h>

int n,m,m1,m2,i,j,i1,j1,l;

float d,p1,x1,p,t,c,s,q1;

float q[10][10],v[10][10];

float x[10];

int k[10];

main()

{

do {

clrscr();

gotoxy(1,1);

printf("Wymiar macierzy N: ");

scanf("%d",&n);

}

while(n>10);

background image

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

{

for (j=i;j<=n;j++)

{

gotoxy(1,3);

puts(" ");

gotoxy(1,3);

printf("q[%d,%d]=",i,j);

scanf("%f",&q[i][j]);

v[i][j]=0.0;

v[j][i]=0.0;

}

v[i][i]=1.0;

}

start:

clrscr();

gotoxy(1,5);

printf("Dokladnosc wyznaczenia: d=");

scanf("%f",&d);

m=0;

m1=n-1;

for (i=1;i<=m1;i++)

{x[i]=0.0;

m2=i+1;

for (j=m2;j<=n;j++)

{p1=abs(q[i][j]);

if (x[i]<=p1)

{x[i]=p1;

k[i]=j;}

}

}

background image

x1=x[1];

i1=1;

j1=k[1];

for (i=2;i<=m1;i++)

if (x1<=x[i])

{x1=x[i];

i1=i;

j1=k[i];}

if (x1<=d) goto wyjscie;

m=m+1;

l=1;

if (q[i1][i1]<=q[j1][j1]) l=-1;

p=q[i1][i1]-q[j1][j1];

p1=pow((p*p+4*q[i1][j1]*q[i1][j1]),2);

t=2*l*q[i1][j1]/(abs(p)+p1);

c=1/pow((1+t*t),2);

s=t*c;

p1=q[i1][i1];

q[i1][i1]=c*c*(p1+t*(2*q[i1][j1]+t*q[j1][j1]));

q[j1][j1]=c*c*(q[j1][j1]-t*(2*q[i1][j1]-t*p1));

q[i1][j1]=0.0;

if (q[i1][i1]<q[j1][j1])

{

p1=q[i1][i1];

q[i1][i1]=q[j1][j1];

q[j1][j1]=p1;

if (s>=0) p=-c;

else p=c;

c=s;

s=p;

}

background image

for (i=1;i<=m1;i++)

{

if ((i!=i1)&&(i!=j1))

if (k[i]==j1)

{

p1=k[i];

p=q[i][p1];

q[i][p1]=0;

m2=i+1;

x[i]=0.0;

for (j=m2;j<=n;j++)

{

t=abs(q[i][j]);

if (x[i]<=t)

{

x[i]=t;

k[i]=j;

}

}

q[i][p1]=p;

}

}

x[i1]=0.0;

x[j1]=0.0;

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

{

if (i==i1) goto E3;

if (i>i1) goto E4;

p=q[i][i1];

q[i][i1]=c*p+s*q[i][j1];

q1=abs(q[i][i1]);

background image

if (x[i]>=q1) goto E1;

x[i]=q1;

k[i]=i1;

E1:

q[i][j1]=-s*p+c*q[i][j1];

q1=abs(q[i][j1]);

if (x[i]>=q1) goto E3;

x[i]=q1;

k[i]=j1;

goto E3;

E4:

if (i==j1) goto E3;

p=q[i1][i];

if (i>j1) goto E2;

q[i1][i]=c*p+s*q[i][j1];

q1=abs(q[i1][i]);

if (x[i1]>=q1) goto E1;

x[i1]=q1;

k[i1]=i;

goto E1;

E2:

q[i1][i]=c*p+s*q[j1][i];

q1=abs(q[i1][i]);

if (x[i1]<q1)

{

x[i1]=q1;

k[i1]=i;

}

q[j1][i]=-s*p+c*q[j1][i];

q1=abs(q[j1][i]);

if (x[j1]>=q1) goto E3;

background image

x[j1]=q1;

k[j1]=i;

E3:

}

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

{

p=v[i][i1];

v[i][i1]=c*p+s*v[i][j1];

v[i][j1]=-s*p+c*v[i][j1];

}

wyjscie:

clrscr();

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

{

printf("\nWartosc wlasna nr:%d=%f\n",i,q[i][i]);

puts("Skladowe wektora wlasnego\n");

for (j=1;j<=n;j++) printf("%f\n",v[j][i]);

}

printf("\nDokladnosc %f po %d obrotach\n",d,m);

l=2;

do

{printf("\nCzy zmiana dokladnosci: 1-Tak,0-Nie");

printf("\nL=");scanf("%d",&l);}

while (l>1);

if (l==1) goto start;

return;

}





background image

3. Sortowanie liczb

Sortowanie liczb lub znaków tj. ustawianie ich w zdefiniowanym wcześniej

porządku w celu późniejszego łatwiejszego ich wyszukiwania – stanowi jeden z

najważniejszych problemów przetwarzania danych. Sortowane liczby ustawione

są początkowo na ogół w nieznanym porządku. Z reguły wymaga się, żeby po

sortowaniu liczby występowały w porządku wzrastających ich wartości.

Istnieje wiele metod sortowania różniących się od siebie rozmaitymi cechami,

jak: szybkością działania, prostotą algorytmu, wielkością wymaganej pamięci.

Najprostszą z tych metod jest metoda pęcherzykowa (ang. bubble-sort), której

nazwa wiąże się z faktem unoszenia się ku górze największych (jako

najlżejszych) pęcherzyków gazu w wodzie.

W przypadku tablicy a jednowymiarowej o rozmiarze n, za jej „górę” można

uważać jej część zawierającą elementy a

k

o indeksach k największych. Tę

„górę” nazwiemy jednak stronę prawą tablicy a w odróżnieniu od strony lewej,

zawierającej elementy a

k

o najmniejszych indeksach.

Sortowanie pęcherzykowe liczb (tj. sortowanie ich metodą pęcherzykową)

polega na przeglądaniu sąsiadujących ze sobą kolejnych par elementów a

k

i a

k+1

tablicy a od jej strony lewej do prawej i przestawianiu (zamianie miejscami) w

elementach a

k

i a

k+1

liczb o zaburzonym porządku. Łatwo stwierdzić, że po

jednym takim „przejrzeniu” całej tablicy a, w jej ostatnim elemencie, a

n

znajdzie

się liczba największa. Takie jedno „przejrzenie” nazywa się przebiegiem lub

przejściem.

W przebiegu drugim odbywa się analogiczne przeglądanie (oczywiście z

ewentualnym przestawianiem liczb w elementach a

k

i a

k+1

w razie zaburzonego

porządku) obejmujące już jednak tylko elementy a

1

÷

a

n-1

(bo liczba największa

jest już w wymaganym elemencie a

n

). W wyniku, liczba największa spośród

występujących w elementach a

1

÷

a

n-1

znajdzie się w elemencie a

n-1

.

Dalsze przebiegi obejmą kolejno elementy: a

1

÷

a

n-2

, a

1

÷

a

n-3

itd. aż do a

1

÷

a

2

, po

tym na pewno nastąpi spełnienie wymaganej nierówności: a

1

<a

2

<...<a

n

.

background image

Algorytm sortowania pęcherzykowego n liczb zawartych w elementach a

1

, a

2

,

...,

a

n

ma więc dla przebiegu i-tego (i=1,2,...,n-1), w którym jest m=n-i

następującą postać:

- dla kolejnych wartości j od 1 do m. co 1, czyli dla j=1(1)m bada się, czy

spełniona jest nierówność a

i

>a

j+1

i w razie jej spełnienia zamienia się ze sobą

miejscami liczby w elementach a

j

i a

j+1

.

Przykład wykorzystania metody sortowania metodą pęcherzykową przedstawia

zadanie nr 19.

Zadanie nr 19

Opracować program porządkujący rosnąco zbiór n-elementowy stosując metodę

sortowania pęcherzykowego. Program ma zawierać moduł generowania

wartości elementów zbioru w zakresie liczb od –100 do 100.

Dane

n (int)

a[n] (int)

Tekst programu:

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#include<time.h>

int i,j,c,znak,kolumna,wiersz,n;

int a[101];

main()

{

randomize();

clrscr();

background image

printf("(0<n<100) n=");

scanf("%d",&n);

n--;

clrscr();

for (i=0;i<=n;i++)

{

a[i]=random(100);

znak=random(2)-1;

if (znak==0) a[i]=a[i]*(-1);

}

for (i=n-1;i>=0;i--)

for (j=0;j<=i;j++)

if (abs(a[j]) > abs(a[j+1]))

{

c=a[j];

a[j]=a[j+1];

a[j+1]=c;

}

for (i=0;i<=n;i++)

{

kolumna=5*(i%10)+1;

wiersz=i/10+1;

gotoxy(kolumna,wiersz);

printf("%d ",a[i]);

}

return;

}

Inną znaną metodą sortowania liczb jest metoda sortowanie szybkiego (quick-

sort). W metodzie tej w odróżnieniu od metody pęcherzykowej porównuje się ze

sobą (i przestawia) nie elementy sąsiadujące bezpośrednio ze sobą, ale elementy

odległe.

background image

Zadanie 20

Opracować w języku C++ program komputerowy zawierający funkcję

sortowania tablicy n liczb metodą sortowania quicksort.

Tekst programu:

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

void quicksort(int tablica[10], int x, int y)

{

int i,j,v,temp;

i=x;

j=y;

v=tablica[div(x+y,2).quot];

do {

while (tablica[i]<v) i++;

while (v<tablica[j]) j--;

if (i<=j)

{

temp=tablica[i];

tablica[i]=tablica[j];

tablica[j]=temp;

i++;

j--;

}

}

while (i<=j);

if (x<j) quicksort(tablica,x,j);

if (i<y) quicksort(tablica,i,y);

}

background image

void main(void)

{

int ile_liczb,i,liczba;

int tablica[10];

clrscr();

printf("Ile liczb chcesz posortowac (do 10) ? ");

scanf("%i",&ile_liczb);

for(i=0; i<ile_liczb; i++)

{

printf("Wprowadz liczbe #%i: ",i+1);

scanf("%i",&liczba);

tablica[i]=liczba;

}

clrscr();

printf("Tablica przed posortowaniem:");

for(i=0; i<ile_liczb; i++)

printf("\n%i",tablica[i]);

quicksort(tablica,0, ile_liczb-1);

printf("\nTablica po posortowaniu:");

for(i=0; i<ile_liczb; i++)

printf("\n%i",tablica[i]);

printf("\nDowolny klawisz...");

getch();

}

Trzecim przykładem sortowania jest metoda sortowania przez wstawianie

(insertionsort). Algorytm tej metody usprawnia metodę pęcherzykową poprzez

kolejne wstawianie analizowanych elementów w właściwe im miejsca ustalone

w wyniku porównań z elementami o malejących indeksach.

background image

Zadanie 21

Opracować w języku C++ program komputerowy zawierający funkcję

sortowania tablicy n liczb metodą sortowania insertionsort.

Tekst programu:

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

void insertionsort(int tablica[10], int ile_liczb)

{

int i,j,v;

for (i=1;i<ile_liczb;i++)

{

j=i;

v=tablica[i];

while ((tablica[j-1]>v)&&(j>0))

{

tablica[j]=tablica[j-1];

j--;

}

tablica[j]=v;

}

printf("\nTablica po posortowaniu:");

for(i=0; i<ile_liczb; i++) printf("\n%i",tablica[i]);

}

void main(void)

{

int ile_liczb,i,liczba;

int tablica[10];

background image

clrscr();

printf("Ile liczb chesz posortowac (do 10) ? ");

scanf("%i",&ile_liczb);

for(i=0; i<ile_liczb; i++)

{

printf("Wprowadz liczbe #%i: ",i+1);

scanf("%i",&liczba);

tablica[i]=liczba;

}

clrscr();

printf("Tablica przed posortowaniem:");

for (i=0; i<ile_liczb; i++)

printf("\n%i",tablica[i]);

insertionsort(tablica,ile_liczb);

printf("\nDowolny klawisz...");

getch();

}


Wyszukiwarka

Podobne podstrony:
jezyk C skrypt cz 1
jezyk C skrypt cz 1
Medycyna Katastrof skrypt cz 1
Estetyka skrypt cz 2, Problem wartości
Prezenterzy sportowi i piękny język polski cz 2
Kopia skrypt cz. ogólna KK i KW, SZKOŁA POLICJI W PILE
Medycyna Katastrof skrypt cz 3
skrypt cz ogólna i prawo rodzinne, Prawo cywilne
Teoria bytu skrypt cz II
Io 5 Język UML, cz I
Język skryptowy Tcl i pakiet okienkowy Tk W Paluszyński
Medycyna Katastrof skrypt cz 2

więcej podobnych podstron