Obojsmerná rotácia statického poľa
Zadajte prvky matice m x n. Napíšte program, ktorý pre zadané celé číslo k Î (-n; n):
a) Zrotujte maticu o k prvkov (pre kladné k posunie posuňie prvky v každom riadku doprava o k stĺpcov, pre záporné doľava, pre k = 0 zostanú prvky na mieste), pričom pri posunuti posledného prvku doprava o jedno bude tento prvok presunutý na prvú pozíciu toho istého riadku (analogicky pri posunutí prvého prvku doľava...).
c) Zmení všetky prvky pôvodnej matice deliteľné zadaným číslom k na 0 (vynuluje ich).
Špecifikácia
VSTUP:
- vstupné premenné: k, m, n, A[MAX][MAX]
- vstupná podmienka: 1 < m < MAX
1 < n < MAX
-n < k < n
VÝSTUP:
- výstupné premenné: A[MAX][MAX], B[MAX][MAX], C[MAX][MAX]
- výstupné podmienky: B:
a/ doprava: ak (k + j) < n
B[i][j + k] = A[i][j]
Inak
B[i][(j + k) - n] = A[i][j]
b/ k = 0: B[i][j] = A[i][j]
c/ doľava: ak (k + j) >= 0
B[i][j + k] = A[i][j]
Inak
B[i][k + j + n] = A[i][j]
C:
a/ k!= 0: ak A[i][j] % k) == 0
C[i][j] = 0
Inak
C[i][j] = A[i][j]
b/ k = 0: maticu C nevypíše
Analýza
Vo svojej podstate je tento program veľmi zaujímavý, teda aspoň pre mňa. Je pomerne jednoduché načítať jednotlivé premenné a taktiež aj prvky matice, kde som použil funkciu, preto sa k tomu nejdem viac vracať. Pri samotnom výpočte výstupnej matice som sa riadil pomerne jednoduchým matematickým analyzovaním a porovnávaním zadaného čísla k a počtom stĺpcov matice. V prvom rade som testoval číslo k voči 0. Ak je k väčšie ako 0, tak som musel použiť ďalší rozhodovací blok a to testovanie súčtu čísel k a j (j aktuálna pozícia stĺpca matice). Tento súčet by mal byť menší ako celkový počet stĺpcov matice. Potom som jednoducho začal priraďovať prvky matice A prvkom matice B, ale s tým, že ku aktuálnemu stĺpcu matice B som prirátal ešte aj hodnotu čísla k (napr.: j + k => 1 + 2). Ak bol súčet k + j väčší alebo rovný ako počet stĺpcov matice, tak každému prvku matice B priradil prvok matice A ale s tým rozdielom, že k aktuálnemu stĺpcu matice B pripočítal hodnotu k a od tohto súčtu ešte odpočítal celkový počet stĺpcov matice A. Toto bol posun doprava.
Ak hodnota čísla k je 0 tak každému prvku matice B bude priradený prvok matice A presne na tú istú pozíciu.
Čiže tu žiadny posun prvkov matice nenastáva.
Posun doľava nastane vtedy, keď je súčet čísla k a aktuálneho poradia stĺpca väčší, alebo rovný ako číslo 0. Vtedy ku každému prvku matice B priradím prvok matice A na pozíciu aktuálneho stĺpca matice B, ale s tým, že je k nemu ešte pripočítané číslo k. Ak neplatí táto podmienka, tak priraďovanie prvkov matice A matici B bude vypadať tak, že k tomu súčtu čísla k a aktuálnej pozície stĺpca matice B pripočítame ešte celkový počet stĺpcov matice A.
To je všetko čo sa posunu týka.
Pre výpočet matice C, kde som mal zistil deliteľnosť jednotlivých prvkov matice A číslom k a následne tieto prvky vynulovať, som použil ešte jednoduchší spôsob. Musel som samozrejme ošetriť prípad keď číslo k má nulovú hodnotu, vtedy sa ním samozrejme deliť nedá. A ďalej som postupoval asi tak, že som zisťoval zvyšok po celočíselnom delení jednotlivých prvkov matice A číslom k. Ak je tento zvyšok nulový znamená to, že daný prvok matice A je deliteľný číslom k a na jeho pozíciu, ale už v matici C priradí hodnotu 0. Ak je tento zvyšok nenulový, tak priradí na aktuálnu pozíciu matice C tú istú hodnotu matice A.
Na výpis jednotlivých matíc som tiež použil funkciu.
Aby som troška popísal funkčnosť jednotlivých funkcii, ktorá je tiež pomerne jednoduchá spomeniem to teraz. Funkcia na načítavanie jednotlivých prvkov matice využíva cyklus s pevným počtom krokov. Vlastne dva takéto cykly za sebou. Jeden posúva aktuálnu pozíciu riadku a druhý stĺpca. Súčasne pri každom posunutí sa načíta príslušný prvok matice.
Funkcia na výpis prvkov matice funguje presne na rovnakom princípe, lenže už nenačítava, ale vypisuje príslušné prvky matice, ku ktorej bola funkcia vyvolaná.
Návrh
Pseudojazyk:
začiatok
Definícia konštanty MAX;
opakuj
začiatok
vstup (m);
koniec
pokiaľ 1 > m > MAX
opakuj
začiatok
vstup (n);
koniec
pokiaľ 1 > n > MAX
opakuj
začiatok
vstup (k);
koniec
pokiaľ -n > k > n
vstupmatice (A);
pre i = 0; i < m; i++ opakuj
začiatok
pre j = 0; j < n; j++ opakuj
začiatok
ak k > 0 potom
začiatok
ak (k + j) < n potom
začiatok
B[i][j + k] = A[i][j];
koniec
inak
začiatok
ak (k + j) >= n potom
B[i][(j + k) - n] = A[i][j];
koniec
koniec
ak k == 0 potom
začiatok
B[i][j] = A[i][j];
koniec
inak
začiatok
ak (k + j) >= 0 potom
B[i][j + k] = A[i][j];
B[i][k + j + n] = A[i][j];
koniec
koniec
koniec
ak k != 0 potom
začiatok
pre i = 0; i < m; i++ opakuj
začiatok
pre j = 0; j < n; j++ opakuj
začiatok
ak (A[i][j] % k) == 0 potom
začiatok
C[i][j] = 0;
koniec
inak
začiatok
C[i][j] = A[i][j];
koniec
koniec
koniec
koniec
vypismaticu (A);
vypismaticu (B);
ak k != 0 potom
vypismaticu (C);
koniec
vypismaticu
začiatok
pre i = 0; i začiatok
pre j = 0; j < N; j++ opakuj
začiatok
výstup (matica[i][j]);
koniec
koniec
koniec
vstupmatice
začiatok
pre i = 0; i začiatok
pre i = 0; i začiatok
vstup (matica[i][j]);
koniec
koniec
koniec
Zdrojový text programu
//Zadanie cislo: 2 & uloha cislo: 9
//==================================
#include
#include
//definicia konstanty
#define MAX 10
// prototyp vlastnej funkcie
void vypisMaticu(int matica[MAX][MAX], int M, int N);
void vstupmatice(int matica[MAX][MAX], int M, int N);
void main()
{
int i, j, n, m, k;
clrscr();
// staticke 2rozmerne polia (matice)
int A[MAX][MAX];
int B[MAX][MAX];
int C[MAX][MAX];
// nacitanie velkosti matice a cisla k
do
{
printf("M (rozmer matice) = ");
scanf("%d", &m);
}
while (m < 1 || m > MAX);
do
{
printf("N (rozmer matice) = ");
scanf("%d", &n);
}
while (n < 1 || n > MAX);
do
{
printf("zadaj cislo K = ");
scanf("%d", &k);
}
while (k < -n || k > n);
// vstup jednotlivych prvkov matice
printf("nPrvky matice A:n");
// volanie funkcie na vstup matice
vstupmatice(A, m, n);
// vypocet prvkov matice B
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
if(k > 0)
{
//posun doprava
if ((k + j) < n)
{
B[i][j + k] = A[i][j];
}
else
{
if ((k + j) >= n)
B[i][(j + k) - n] = A[i][j];
}
}
if(k == 0)
{
B[i][j] = A[i][j];
}
else
{
//posun dolava
if((k + j) >= 0)
B[i][j + k] = A[i][j];
B[i][k + j + n] = A[i][j];
}
}
}
//vypocet prvkov matice C
if(k != 0)
{
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
if ((A[i][j] % k) == 0)
{
C[i][j] = 0;
}
else
{
// ked k=0
C[i][j] = A[i][j];
}
}
}
}
// vypis matic
printf("nMatica A:n");
vypisMaticu(A, m, n);
printf("n===============n");
printf("nMatica B:n");
vypisMaticu(B, m, n);
printf("n===============n");
if(k != 0)
{
printf("nMatica C:n");
vypisMaticu(C, m, n);
}
getch();
}
// funkcia na vypis matice
void vypisMaticu(int matica[MAX][MAX], int M, int N)
{
int i, j;
for (i = 0; i {
for (j = 0; j < N; j++)
{
printf(" %3d", matica[i][j]);
}
putchar('n');
}
}
//funkcia na nacitanie matice
void vstupmatice(int matica[MAX][MAX], int M, int N)
{
int i, j;
for (i = 0; i {
for (j = 0; j < N; j++)
{
printf("matica[%d][%d] = ", i + 1, j + 1);
scanf("%3d", &matica[i][j]);
}
}
}
Testovanie
Pre veľký objem údajov asi nie je vhodné robiť trasovaciu tabuľku, nakoľko by asi zabrala minimálne tri strany. Preto som zvolil trosku jednoduchší zápis testovania a to na príklade.
M = 2, N = 5, k = 2
A
1 2 3 4 5
2 4 6 8 10
B
4 5 1 2 3
8 10 2 4 6
C
1 0 3 0 5
0 0 0 0 0
M = 3, N = 3, k = -1
A
1 2 3
4 5 6
7 8 9
B
2 3 1
5 6 4
8 9 7
C
0 0 0
0 0 0
0 0 0
Záver
Matematicky je takmer celý program rozanalyzovaný v časti Analýza. Čo sa týka zložitosti celkového riešenia programu, nepokladám ho za veľmi zložitý aj keď mi síce dal zabrať o niečo viac, ako prvé zadanie.
Vedel by som ho ešte troška vylepšiť a to napríklad tým, že by som kontroloval aj veľkosť vkladanej hodnoty do matice, pretože pole ako také máme deklarované v pamäti, ale ak zadám väčšiu hodnotu ako je hodnota, pre ktorú má pole v pamäti vyhradené miesto, nebude sa to pravdepodobne správať podľa našich očakávaní.
Program je v C plne funkčný podľa požiadaviek zadania. Sú v ňom použité dve funkcie a to na načítavanie a výpis matice.
|