|
|
|
|
A la pràctica anterior, omplir una matriu ha estat
fet d'una manera ben matussera... element per element! Ara mirarem d'automatitzar
les coses. Al cap i a la fi, d'això tracta la informàtica...
|
|
|
|
|
|
Omplir una matriu: |
|
|
|
|
 |
Al projecte
Matrius de la pràctica anterior, crea la
classe MatriusDeNombres amb aquest codi: |
|
|
|
|
|
/**
* Manipulació elemental de matrius II.
*
* @author Carles Romero
* @version 2004/02/08
*/
public class MatriusDeNombres {
/**
* Una matriu que conté nombres
enters.
*/
int[] elsNombres;
/**
* Mètode constructor per a
objectes de la classe
* MatriusDeNombres.
* @param n la longitud de la matriu
elsNombres
*/
public MatriusDeNombres (int n) { //
constructor
elsNombres=new int[n];
}
}
|
|
|
|
|
|
|
La compiles
crees un objecte d'aquesta classe, amb 5 com a
paràmetre del mètode constructor i, després, l'inspecciones: |
|
|
|
|
|
|
|
|
|
|
|
Apareix
l'única variable
d'instància que hi has definit, això és,
la matriu elsNombres, la qual també pots
inspeccionar: |
|
|
|
|
|
|
|
|
|
|
|
Efectivament, tal
com mana la línia |
|
|
|
|
|
|
|
|
|
|
|
del mètode
constructor public MatriusDeNombres (int n), la
matriu elsNombres té 5 elements, nombres
enters, que, per defecte (no has manat altra cosa!) són 0. |
|
|
|
|
|
Ara l'omplim,ara... |
|
|
|
|
|
Ara afegeix aquest
mètode, que servirà per omplir-la amb nombres enters positius.
Retoca també, el mètode constructor per tal que, tot just
al construir l'objecte, la matriu ja estigui plena: |
|
|
|
|
|
/**
* Manipulació elemental de matrius II.
*
* @author Carles Romero
* @version 2004/02/08
*/
public class MatriusDeNombres {
/**
* Una matriu que conté nombres
enters.
*/
int[] elsNombres;
/**
* Mètode constructor per a
objectes de la classe
* MatriusDeNombres.
* @param n la longitud de la matriu
elsNombres
*/
public MatriusDeNombres (int n) { // constructor
elsNombres=new int[n];
|
posaValorsInicials();
|
}
|
/**
* Mètode que posa un 1 al primer
lloc de la matriu elsNombres
* (índex 0), un 2 al segon lloc
(índex 1), etc.
*/
public void posaValorsInicials () {
int quants=elsNombres.length;
for
(int i=0;i<quants;i++) {
elsNombres[i]=i+1;
}
}
|
} |
|
|
|
|
|
|
Aquesta és
una manera estàndar de manipular matrius: el codi comença
per preguntar com és de llarga la matriu: |
|
|
|
|
|
int
quants=elsNombres.length; |
|
|
|
|
|
|
tot dipositant a
la variable quants el valor de la variable length
(longitud) de la matriu elsNombres (totes
les matrius la tenen la variable length!). Després,
amb una estructura de control for(...){...}, (un
moment! ara mateix t'ho expliquem!) omple, un per un, els elements de la
matriu: |
|
|
|
|
|
for
(int i=0;i<quants;i++) {
elsNombres[i]=i+1;
} |
|
|
|
|
|
|
amb el nombre i+1
en aquest cas, però igual podries haver-hi posat |
|
|
|
|
|
|
|
|
|
|
|
o qualsevol altra
cosa... |
|
|
|
|
|
A
la pràctica anterior has vist una estructura de bucle. Ara en tenim
una altra: l'estructura de control for(...){...}
és un altre tipus de bucle
("loop") que es fa servir molt i molt. Requereix un comptador
enter (int i, en el nostre cas) al qual se li
ha de donar un valor inicial (i=0), una
condició que pot ser verdadera o falsa (i<quants),
i una operació d'increment del comptador (i=i++,
que és una abreviatura de i=i+1). El codi
entre els delimitadors "{" i "}"
s'executa una i una altra vegada fins que la condició resulti falsa.
El nostre codi |
|
|
|
|
|
for
(int i=0;i<quants;i++) {
elsNombres[i]=i+1;
} |
|
|
|
|
|
|
és completament
equivalent a aquest altre, amb una estructura
while(...){...}:
|
|
|
|
|
|
int
i=0;
while
(i<quants) {
elsNombres[i]=i+1;
i++; //
equivalent a i=i+1
} |
|
|
|
|
|
|
Adona't que el que
es fa, tant si s'escriu d'una manera com d'una altra, és repetir
l'acció del cos del bucle per als valors de la variable
i següents: 0,
1, 2, 3, ..., quants-1.
Si ara inspecciones la matriu elsNombres, |
|
|
|
|
|
|
|
|
|
|
|
veuràs que,
efectivament és plena amb els valors que establia el codi del mètode
public void posaValorsInicials ().
Pot ser interessant que analitzis què passa si canvies l'expressió
i+1 d'aquest mètode per una altra expressió
en funció de i. |
|
|
|
|
|
Canvis i més
canvis... |
|
|
|
|
|
La mateixa tècnica
que t'ha servit per omplir una matriu, ara pots aplicar-la per canviar-ne
allò que hi ha enmagatzemat. Per exemple, amb aquest nou mètode |
|
|
|
|
|
<
... codi anterior ... >
for
(int i=0;i<quants;i++) {
elsNombres[i]=i+1;
}
}
|
/**
* Mètode que substitueix els
nombres enmagatzemats a la matriu
* elsNombres pel residu que en resulta
en dividir-los per n.
* @param n el nombre (el mòdul!)
pel qual es divideixen els
* elements de la matriu elsNombres
*/
public void aModulN (int n) {
int quants=elsNombres.length;
for
(int i=0;i<quants;i++) {
elsNombres[i]=elsNombres[i]%n;
}
}
|
} |
|
|
|
|
|
|
podràs veure
l'efecte de l'operador
binari "%" sobre els elements
de la matriu: cada nombre enmagatzemat serà substituït pel residu
que en resulta en dividir-lo per l'enter n, que
és el paràmetre que cal passar en executar el mètode: |
|
|
|
|
|
En l'exemple següent
s'havia creat prèviament una nova còpia de la matriu elsNombres
amb longitud 16. |
|
|
|
|
|
|
|
|
|
|
|
Ara canviar-ne l'ordre: |
|
|
|
|
|
|
El següent mètode: |
|
|
|
|
|
<
... codi anterior ... >
for
(int i=0;i<quants;i++) {
elsNombres[i]=elsNombres[i]%n;
}
}
|
/**
* Mètode per intercanviar les
posicions de dos elements de
* la matriu elsNombres.
* @param m la posició d'un dels
elements a intercanviar
* @param n la posició de l'altre
dels elements a intercanviar
*/
public void intercanvia (int m,int n) {
int buffer=elsNombres[m];
// necessitem un
dipòsit intermedi!
elsNombres[m]=elsNombres[n];
elsNombres[n]=buffer;
}
|
} |
|
|
|
|
|
|
agafa l'element que hi
ha a la posició (quan diguem "posició"
en realitat heu de llegir "índex") m, |
|
|
|
|
|
int
buffer=elsNombres[m]; |
|
|
|
|
|
|
i el guarda
al dipòsit provisional int buffer
("buffer", en anglès, vol dir "esmorteïdor"
i, en l'argot informàtic, té el sentit de "dipòsit
provisional de dades"). Després, agafa l'element que hi ha a
la posició (índex) n i el
copia a la posició (índex) m.
El valor que hi havia a la posició m es
perd i, per això, cal guardar-lo abans en un dipòsit provisional. |
|
|
|
|
|
elsNombres[m]=elsNombres[n]; |
|
|
|
|
|
|
Finalment, copia el valor
guardat a buffer (el valor que hi havia inicialment
a la posició m!) a la posició n: |
|
|
|
|
|
|
|
|
|
|
|
i, així, l'intercanvi
de posicions queda complet. |
|
|
|
|
|
Prova-ho: amb una matriu
elsNombres de vuit elements: |
|
|
|
|
|
|
|
|
|
|
|
aplica el mètode
public void intercanvia (int m,int n) amb els
paràmetres 2 i 5: |
|
|
|
|
|
|
|
|
|
|
|
i ara inspecciona la
matriu: |
|
|
|
|
|
|
|
|
|
|
|
Efectivament!, el 3
i el 6, que eren a les posicions 2 i 4, han intercanviat
els seus llocs! |
|
|
|
|
|
I
ara... un parell d'exercicis: |
|
|
|
|
 |
Es tracta que, a partir
dels valors inicials: |
|
|
|
|
|
|
|
|
|
|
|
escriguis dos nous mètodes.
Un, que s'ha de dir public void capgira (), ha
d'aconseguir això: |
|
|
|
|
|
|
|
|
|
|
|
és a dir, capgirar
completament la matriu: el primer element ha d'anar a l'últim lloc,
el segon al penúltim, etc. |
|
|
|
|
|
L'altre
mètode, public void permutacióCircularDescendent
(), ha de fer desplaçar cada element un lloc: el segon element
al primer lloc, el tercer al segon, etc. excepte el primer, que ha d'anar
a parar a l'últim lloc: |
|
|
|
|
|
|
|
|
|
|
|
Aquests mètodes
han d'incloure el mètode public void intercanvia
(int m,int n) en el seu codi. Si no te'n surts (ei! només
si no te'n surts, eh?) aquí
tens una solució possible dels dos exercicis (n'hi ha més!).
|
|
|
|
|
|
I per què no? |
|
|
|
|
 |
I per què no escrius
ara un altre mètode, public void permutacioCircularAscendent
(), que faci desplaçar cada element un lloc però a
la inversa d'abans: el primer element al segon lloc, el segon al tercer,
etc. excepte l'últim, que ha d'anar a parar al primer lloc? |
|
|
|
|
|
|
 |