73
 Tipus de dades compostes Joan Arnedo Moreno Programació bàsica (ASX) Programació (DAM)

fp_asix_m03_u3_pdfindex

Embed Size (px)

DESCRIPTION

ioc java 3

Citation preview

  • Tipus de dades compostesJoan Arnedo Moreno

    Programaci bsica (ASX)Programaci (DAM)

  • Programaci bsica (ASX)Programaci (DAM) Tipus de dades compostes

    ndex

    Introducci 5

    Resultats daprenentatge 7

    1 Tipus de dades compostes: "arrays" 91.1 Declaraci i inicialitzaci d"arrays" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    1.1.1 Inicialitzaci a un valor concret . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.1.2 Inicialitzaci a un valor per defecte . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

    1.2 Manipulaci de dades dins d"arrays" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.3 Emmagatzematge de lentrada de dades en un "array" . . . . . . . . . . . . . . . . . . . . . . 15

    1.3.1 Entrada de seqncies de valors per teclat . . . . . . . . . . . . . . . . . . . . . . . . 151.3.2 "Arrays" completament ocupats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.3.3 "Arrays" parcialment ocupats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

    1.4 Esquemes fonamentals en la utilitzaci d"arrays" . . . . . . . . . . . . . . . . . . . . . . . . 221.4.1 Inicialitzaci procedural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221.4.2 Recorregut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241.4.3 Cerca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251.4.4 s d"arrays" auxiliars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271.4.5 Cpia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291.4.6 Canvi de mida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301.4.7 Ordenaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

    1.5 "Arrays" multidimensionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341.5.1 Declaraci d"arrays" bidimensionals . . . . . . . . . . . . . . . . . . . . . . . . . . 351.5.2 Esquemes ds d"arrays" bidimensionals . . . . . . . . . . . . . . . . . . . . . . . . 361.5.3 "Arrays" de ms de dues dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

    1.6 Solucions dels reptes proposats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    2 Tractament de cadenes de text 472.1 La classe "String" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

    2.1.1 Inicialitzaci dobjectes "String" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482.1.2 Manipulaci dobjectes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482.1.3 Accs als carcters duna cadena de text . . . . . . . . . . . . . . . . . . . . . . . . . 502.1.4 Concatenaci de cadenes de text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522.1.5 "Arrays" de cadenes de text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

    2.2 Entrada de cadenes de text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532.2.1 Lectura des de teclat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542.2.2 Argument del mtode principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    2.3 Manipulaci de cadenes de text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602.3.1 Cerca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612.3.2 Comparaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632.3.3 Creaci de subcadenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642.3.4 Transformacions entre cadenes de text i tipus primitius . . . . . . . . . . . . . . . . . 67

    2.4 Solucions dels reptes proposats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

  • Programaci bsica (ASX)Programaci (DAM) 5 Tipus de dades compostes

    Introducci

    Qualsevol dada manipulada dins dun programa pertany a algun dels tipusprimitius, ja que sn els nics que sap processar el maquinari de lordinador.Normalment, aquestes dades sn emmagatzemades dins de variables, un delselements bsics dun programa amb vista amanipular dades. Aquesta aproximacis til sempre que el nombre de dades que es vol tractar sigui relativament limitat.Ara b, precisament, un dels aspectes en qu es fa especialment recomanable laresoluci dun problema usant un programa dordinador s quan el volum de dadesper processar s molt gran. Suposeu que en lloc de treballar amb uns quantsvalors independents, que us cal desar i processar, nheu de treballar amb molts:50, 100, 2.000 o molts ms. En aquest cas, laproximaci de desar cada valor enuna variable dins el programa faria la tasca del programador molt farragosa. Elcodi font tindria ms instruccions de declaraci de variables que no pas potser perresoldre el problema!

    Per solucionar aquesta qesti, els llenguatges de programaci ofereixen uns tipusde dades especials, anomenats tipus compostos, que permeten aglutinar en unanica variable una quantitat arbitrria de dades individuals pertanyents a alguntipus concret. Aquestes queden empaquetades duna manera fcil de gestionar alhora de consultar i modificar cada valor individual.

    A lapartat Tipus de dades compostes: arrays es presenta el tipus compost dedades ms bsic, larray, disponible en la majoria de llenguatges dalt nivell.Aquest permet emmagatzemar en una nica variable un conjunt de valors en formade seqncia, amb lnica restricci que tots pertanyin al mateix tipus de dades.Daquesta manera, en una nica variable podem disposar de qualsevol nombredenters, reals, etc. Dins lapartat en veureu la sintaxi en Java i els mecanismesms habituals de tractament de dades emmagatzemades dins seu.

    A part dels arrays, hi ha altres tipus compost de dades de diferents graus decomplexitat i amb lobjectiu de solucionar problemtiques semblants, per ambcerts matisos. Un exemple s la manipulaci de text. El tipus primitiu carcter, persi mateix, no t excessiva utilitat, ja que normalment les persones usem paraules o,si ms no, text de longitud arbitrria per comunicar-nos. Per tant, gestionar aquesttipus dinformaci carcter per carcter tamb s poc viable. Seria interessantdisposar dalgun mecanisme per gestionar de manera senzilla una combinaciqualsevol de diversos carcters. Aquesta s precisament la tasca destinada al tipusde dades anomenat cadena de text.

    A lapartat segent, Tractament de cadenes de text, es presenta amb ms detallaquest tipus compost de dades molt til, anomenat String en el llenguatge Java.Si b ja shavia presentat de manera superficial en apartats anteriors, veureu comusar-lo per fer tasques ms complexes que mostrar text per pantalla, com processarels carcters que cont o convertir el text a altres tipus primitius.

  • Programaci bsica (ASX)Programaci (DAM) 7 Tipus de dades compostes

    Resultats daprenentatge

    En finalitzar aquesta unitat, lalumne/a:

    1. Escriu i prova programes senzills reconeixent i aplicant els fonaments de laprogramaci modular.

  • Programaci bsica (ASX)Programaci (DAM) 9 Tipus de dades compostes

    1. Tipus de dades compostes: "arrays"

    Suposeu que voleu fer un programa per analitzar les notes finals dun conjuntdestudiants. Les operacions per fer poden ser diverses: calcular la nota mitjana,veure quants estudiants han aprovat, susps o han superat cert llindar de nota, fergrfiques de rendiment, etc. A ms, no es descarta que en el futur el programa esmodifiqui per afegir-hi noves funcionalitats. El quid de la qesti s que, per poderpreveure totes aquestes possibilitats i daltres de futures encara desconegudes, uscal disposar dins del programa del valor de cada nota individual. En un cas comaquest, tal com sha plantejat fins ara laproximaci per manipular dades dins dunprograma, aix implica que cada nota sha demmagatzemar dins duna variablediferent. Si hi ha 50 estudiants, aix vol dir que caldria declarar 50 variables.

    Malauradament, aquesta aproximaci no funciona en un cas com aquest, en quel nombre de dades per processar s relativament alt. Duna banda, imagineu-vos laspecte que tindr un codi font en qu cal declarar i manipular 50 variablesper fer tota mena de clculs. Les expressions per fer clculs entre elles, comsimplement fer la mitjana (sumar-les totes i dividir pel nombre de valors), serienenormes. Daltra banda, qu passa si cal processar les notes de dos-cents o milestudiants? s factible declarar mil variables? Pitjor encara: qu passa si elnombre destudiants de cada curs s totalment diferent? En cada curs el nombre devariables usades no encaixar amb el destudiants i ser necessari modificar el codifont tenint en compte el nombre exacte de valors per tractar i tornar a compilar.

    Ja a simple vista es pot apreciar que tot plegat s inviable. Cal un sistema flexibleper emmagatzemar un nombre arbitrari de valors de manera que aquests siguinfcils de manipular. Encara ms, ha de ser possible que el nombre de valorsemmagatzemats pugui ser diferent per a cada execuci del programa. Per resoldreaquesta problemtica, els llenguatges de programaci dalt nivell ofereixen el tipusde dada compost array, o taula.

    Un "array" s com una calaixera.Imatge de Liverpool Design Festival

    Un tipus de dada compost s aquell que permet emmagatzemar ms dunvalor dins duna nica variable. En el cas de larray, aquest permetemmagatzemar, en forma de seqncia, una quantitat predeterminada devalors pertanyents al mateix tipus de dades.

    Per tal de diferenciar els diferents valors emmagatzemats, larray gestiona elseu contingut dacord amb posicions que segueixen un ordre numric: el valoremmagatzemat a la primera posici, a la segona, a la tercera, etc. A efectesprctics, es pot considerar que cada posici individual es comporta exactamentigual que una variable del tipus de dada triat. Tant es pot consultar el valor comemmagatzemar-hi dades. Aquest comportament sesquematitza a la figura 1.1.

  • Programaci bsica (ASX)Programaci (DAM) 10 Tipus de dades compostes

    Figura 1.1. Organitzaci de les dades emmagatzemades dins dun array

    Abans de veure amb ms detall com funcionen, heu de tenir present que la sintaxiper usar arrays en els diferents llenguatges de programaci pot ser relativamentdiferent. Aquest apartat se centrar en la sintaxi concreta del Java, que t certesparticularitats niques. Tot i aix, el concepte general daccs a valors ordenatscom una seqncia en forma darray s aplicable a qualsevol llenguatge.

    1.1 Declaraci i inicialitzaci d"arrays"

    Com passa amb dades de qualsevol altre tipus, abans de poder fer s duna variablede tipus array, cal declarar-la i atorgar-li un valor inicial correctament. La sintaxiper declarar un array s fora semblant a la daltres tipus, per la inicialitzaci tunes particularitats especials a causa de les seves caracterstiques prpies:

    Duna banda, cal decidir de quantes posicions disposar larray: la sevamida. Mai no hi podr haver emmagatzemats ms valors que la sevacapacitat.

    Duna altra banda, cal decidir el valor inicial per a cada posici individual delarray. En aquest aspecte, cada posici t el mateix paper que una variableindividual dins del programa, i per tant, ha destar inicialitzada amb algunvalor.

    En el moment de la inicialitzaci dun array, la seva mida ha de serconeguda. Un cop ha estat inicialitzat amb un nombre de posicionsconcretes, aquesta ja no pot canviar.

    Abans de poder usar un array s obligatori inicialitzar-lo. Java donar un error decompilaci en cas contrari.

  • Programaci bsica (ASX)Programaci (DAM) 11 Tipus de dades compostes

    1.1.1 Inicialitzaci a un valor concret

    Com passa amb les variables individuals, hi ha la possibilitat que en el momentde generar el codi font ja tingueu uns valors concrets al cap amb els quals voleuinicialitzar cadascuna de les posicions de larray. En aquest cas, la sintaxi de lainicialitzaci s la segent:

    1 paraulaClauTipus[] identificadorVariable = {valor1, valor2, ... , valorN};

    La part esquerra s prcticament igual que per a la declaraci duna variablequalsevol. El que indica que en realitat sest declarant un array sn els dosclaudtors [] immediatament desprs de la declaraci del tipus. Cadascuna de lesposicions de larray noms podr emmagatzemar valors del tipus declarat aqu.

    Per especificar els valors emmagatzemats inicialment a cada posici nhi ha prouque aquests senumerin entre claus {...}, separats per comes (,). Aquestsvalors han de ser del mateix tipus de dada que el declarat a la part esquerra isemmagatzemaran en el mateix ordre en qu shagin enumerat: el primer valor ala primera posici de larray, el segon a la segona posici, etc. En aquest cas, lamida de larray ser automticament igual que el nombre de valors enumerats.

    Per exemple, per declarar un array de 5 posicions en qu es poden emmagatzemarvalors de tipus enter, cadascuna amb els valors inicials 10, 20, 30, 40 i 50,respectivament, es faria de la manera segent. La mida daquest array seria 5.

    1 int[] arrayEnters = {10, 20, 30, 40, 50};

    El resultat es mostra a la figura 1.2.

    Figura 1.2. Esquema dinicialitzaci dun array en Java amb valors concrets.

    No hi pot haver dades detipus barrejats dins dunarray.

  • Programaci bsica (ASX)Programaci (DAM) 12 Tipus de dades compostes

    1.1.2 Inicialitzaci a un valor per defecte

    Moltes vegades les dades que es volen emmagatzemar depenen de la lecturaduna entrada (per exemple, per teclat), o b sn resultat de clculs que sn mscmodes de dur a terme de manera automatitzada dins del codi de programa (perexemple, una llista de 1.000 nombres primers). En aquest cas, no hi ha un valorinicial concret que calgui assignar a les posicions de larray, ja que els valorssemmagatzemaran a posteriori.

    En aquest cas, una altra manera, ms simple i habitual, de declarar i inicialitzar-lo,s assumint que totes les posicions prenen automticament un valor per defecte,que s 0 per a les dades de tipus numric i els carcters, i false per a booleans.Ms endavant ja assignareu a cada posici el valor que vulgueu.

    Aix es fa de la manera segent:

    1 paraulaClauTipus[] identificadorVariable = new paraulaClauTipus[mida];

    Noms varia la part dreta, relativa a lassignaci dels valors inicials. En aquestcas la sintaxi s molt estricta i cal emprar el format indicat. Susa la paraula claunew, seguida novament del tipus de les dades dins larray i, entre claudtors, lamida que vulguem. Els tipus de dades especificats a la part esquerra i dreta hande ser idntics, o hi haur un error de compilaci.

    No cal fer res ms per assignar valors a les posicions de larray, Java ja hi assignaautomticament el valor per defecte. Ara b, alerta, aquesta s una propietatespecfica del Java i no ha de ser aix necessriament en altres llenguatges, enqu el valor inicial de cada posici pot ser indeterminat.

    Per exemple, per declarar un array de 10 posicions en qu es poden emmagatzemarvalors de tipus real, tots inicialment amb el valor 0, es faria de la manera segent:

    1 double[] arrayReals = new double[10];

    Aquest codi s equivalent a fer:

    1 double[] arrayReals = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    El resultat de fer qualsevol de les dues instruccions es visualitza a la figura 1.3.

    Figura 1.3. Esquema dinicialitzaci dun array en Java amb valors per defecte

  • Programaci bsica (ASX)Programaci (DAM) 13 Tipus de dades compostes

    1.2 Manipulaci de dades dins d"arrays"

    Tot i conformar un tipus de dada (com els enters, reals, etc.), els arrays sn unamica especials a lhora de ser manipulats, ja que no disposen de cap operaci. Nos possible usar lidentificador de larray directament per invocar operacions i aixmanipular les dades contingudes, tal com es pot fer amb variables daltres tipus.Per exemple, no s possible fer el segent:

    1 ...2 int[] a = {10, 20, 30, 40, 50};3 int[] b = {50, 60, 70, 80, 100};4 int[] c = a + b;5 ...

    Sempre que es vulgui fer alguna operaci amb les dades emmagatzemades dinsdarrays cal manipular-les de manera individual, posici per posici. En aquestaspecte, cada posici dun array t exactament el mateix comportament queuna variable tal com les heu estudiades fins ara. Les podeu aprofitar tant peremmagatzemar dades com per llegir-ne el contingut.

    Per tal de distingir entre les diferents posicions dun array, cadascuna t assignatun ndex, un valor enter que nindica lordre dins de lestructura. Sempre que usvulgueu referir a una de les posicions, nhi ha prou dusar lidentificador de larrayjuntament amb lndex de la posici buscada entre claudtors []. La sintaxi exactas:

    1 identificadorArray[ndex]

    El rang dels ndexs pot variar segons el llenguatge de programaci. En el cas delJava, aquests van de 0, per a la primera posici, a (mida - 1), per a la darrera.Per exemple, per accedir a les posicions dun array de cinc posicions usareu elsndexs 0, 1, 2, 3 i 4. Tot seguit es mostra un exemple de com saccedeix a les dadesdun array mitjanant els ndexs de les seves posicions:

    1 ...2 int[] arrayA = {10, 20, 30, 40, 50};3 int[] arrayB = {50, 60, 70, 80, 100};4 int[] arrayC = new int[5];5 //La variable de tipus enter "r" valdr 140, 40 + 100.6 int r = arrayA[3] + arrayB[4];7 //La segona posici (ndex 1) d"arrayC" valdr 150, 140 + 10.8 arrayC[1] = r + arrayA[0];9 ...

    La figura 1.4 esquematitza laccs a les dades dins daquest codi.

    En el Java, fer operacionsentre arrays comporta unerror de compilaci.

  • Programaci bsica (ASX)Programaci (DAM) 14 Tipus de dades compostes

    Figura 1.4. Exemple de manipulaci de dades dins darrays

    s molt important que en accedir a un array sutilitzi un ndex correcte, dacordamb el rang admissible. Si susa un valor no admissible, com per exemple un valornegatiu o un valor igual o superior a la seva mida, hi haur un error dexecuci.Concretament, es produir una IndexOutOfBoundsException. Si aix succeeix,podeu tenir la certesa que el programa t una errada i lhaureu de repassar icorregir. Per tant, els codi segent seria incorrecte:

    1 ...2 //"arrayA" t mida 5.3 //Els ndexs vlids van de 0 a (mida 1), que s 4.4 int[] arrayA = {10, 20, 30, 40, 50};5 //Sassigna un valor a una posici incorrecta (ndex 5).6 arrayA[5] = 60;7 //Lndex 6 s invlid, no es pot consultar el valor.8 int r = arrayA[2] + arrayA[4] + arrayA[6];9 ...

    Per tal dajudar-vos en la tasca de controlar si un ndex concret est dins del rangadmissible per a una variable de tipus array concreta, Java disposa duna einaauxiliar, latribut length (llargria). La seva sintaxi s la segent:

    1 identificadorArray.length

    El resultat daquesta instrucci s equivalent a avaluar una expressi que coma resultat obt la mida de larray anomenat identificadorArray. Ara b,recordeu que length us dna la mida, per el rang dndexs vlid s 0 ... (mida -1). Per exemple:

    1 ...2 //"arrayA" t mida 5. Els ndexs vlids van de 0 a 4.3 int[] arrayA = {10, 20, 30, 40, 50};4 //"length" us diu la mida.5 //Recordeu que lndex mxim s (mida 1).6 if (index < arrayA.length) {7 System.out.println("La posici " + index + " val " + a[index]);8 } else {9 System.out.println("Aquest array no t tantes posicions!");

    10 }11 ...

  • Programaci bsica (ASX)Programaci (DAM) 15 Tipus de dades compostes

    1.3 Emmagatzematge de lentrada de dades en un "array"

    Com sha esmentat, els arrays sn especialment tils per poder emmagatzemar demanera eficient un nombre arbitrari de dades provinents del sistema duna entrada(per exemple, des del teclat). Normalment, les dades saniran llegint una per una,i a mesura que es faci, caldr anar-les assignant a cadascuna de les posicions delarray a partir del seu ndex. Tot seguit veureu diferents esquemes per dur a termeaquesta tasca.

    Emmagatzemar en "arrays" dadesllegides seqencialment s com unacadena dembotellament

    Si b els exemples se centraran en ls del teclat, ja que s el sistema dentradaque per ara sabeu utilitzar, heu de tenir en compte que aquests esquemes seranaplicables a qualsevol altre mecanisme dentrada (per exemple, un fitxer). Lnicacondici s que les dades estiguin en forma de seqncia, de manera que es puguinanar llegint una per una, ordenadament.

    Un cop exposats aquests esquemes, en la resta dexemples de lapartat sobviarel codi relatiu a lentrada de dades pel teclat.

    1.3.1 Entrada de seqncies de valors per teclat

    Els arrays tenen sentit quan el programa ha de processar moltes dades, especial-ment provinents de lentrada del programa (com el teclat). Abans de continuar,val la pena veure com es poden llegir seqncies de dades entrades des del teclaten una sola lnia de text, de manera que sigui senzill emmagatzemar-les dins dunarray. Si b ja sabeu com llegir dades individualment des del teclat, fer-ho aixpot ser una mica avorrit i molest amb vista a lexecuci dels programes en qusintrodueixen moltes dades, preguntant cada valor un per un i havent de pitjar latecla de retorn cada vegada.

    En realitat, quan susa una instrucci lector.next... i el programa saturaesperant que lusuari introdueixi dades pel teclat, res no impedeix que, en llocduna nica dada, aquest nescrigui ms duna abans de pitjar la tecla de retorn.O sigui, una seqncia de valors. Lnica condici s que cada valor individualestigui separat de la resta per almenys un espai, de manera que siguin fcilmentidentificables. Quan aix succeeix, tots els valors de la seqncia queden latents,pendents de lectura. Successives invocacions a noves instruccions de lecturaautomticament aniran consumint aquests valors pendents, en lloc de causar unanova espera duna entrada de lusuari. Mentre quedin valors a la seqnciapendents de llegir, les instruccions de lecturamai no causaran una espera dentradade dades. Un cop la seqncia ha estat consumida totalment, llavors s que lapropera instrucci de lectura causar que el programa es torni a aturar esperantuna nova entrada de lusuari. I aix el cicle de lectura torna a comenar.

    Dins daquest procs hi ha una crida amb un comportament especial:lector.nextLine();. Quan aquesta crida sinvoca, automticament es descar-

  • Programaci bsica (ASX)Programaci (DAM) 16 Tipus de dades compostes

    ten tots els valors pendents de llegir de la seqncia actual. La propera crida a unainstrucci de lectura sempre causar que el programa saturi de nou i esperi unaentrada de lusuari.

    La taula 1.1 mostra un exemple daquest mecanisme de lectura, en qu es llegeixenvalors de tipus enter.

    Taula 1.1. Exemple de lectura duna seqncia de valors enters

    Acci del programa Resultat obtingut Dades pendents de lectura

    (Inici del programa) El programa sinicia { } (no nhi ha cap)

    Llegir valor El programa espera entrada delusuari

    { } (no nhi ha cap)

    Lusuari entra els valors 1 2 4 8 16 32 i pitja la tecla de retorn

    La lectura avalua 1 { 2, 4, 8, 16, 32 }

    Llegir valor La lectura avalua 2 { 4, 8, 16, 32 }

    Llegir valor La lectura avalua 4 { 8, 16, 32 }

    Llegir valor Es buida la seqncia de dadespendents

    { }

    Llegir valor El programa espera entrada delusuari

    { }

    Es torna a comenar el cicle de lectura duna nova seqncia de valors...

    Un fet important quan es llegeixen seqncies de diversos valors escrites des delteclat s que res no impedeix que hi pugui haver valors de diferents tipus de dadesbarrejats. Aix tant pot ser per error de lusuari en entrar les dades, com perqu elprograma realment espera una seqncia amb valors de diferents tipus intercalats.En qualsevol cas, s important que abans de fer cap lectura duna dada es comprovisi el tipus s el que correspon usant les instruccions lector.hasNext....

    Per llegir mltiples valors el ms senzill s fer-ho mitjanant una estructura derepetici que vagi invocant successivament les instruccions de lectura de dades.En usar aquest mecanisme cal tenir present un fet ben important. Sha de saberexactament quan heu obtingut ja totes les dades necessries i cal deixar llegir.Normalment hi ha dues aproximacions depenent de si es coneix la quantitat dedades exactes que cal llegir o no.

    Quantitat de dades coneguda

    Si el nombre de valors que es vol llegir s conegut per endavant, per tractar lalectura de la seqncia de valors hi ha prou dusar una estructura de repeticibasada en un comptador. Aquest comptador controlar el nombre de valors llegitsi les iteracions finalitzaran en assolir el nombre de lectures que vulguem.

    Compileu i executeu lexemple segent, en qu es mostra com cal fer la lecturadun seguit de valors enters. Si se nescriuen ms dels esperats, la resta esdescarten. Fixeu-vos que no s necessari escriure tots els valors en una sola lniade text. Si la lnia introduda, abans de pitjar la tecla de retorn, no disposa desuficients valors, el programa satura esperant la resta. A ms a ms, aquest codi

  • Programaci bsica (ASX)Programaci (DAM) 17 Tipus de dades compostes

    controla mitjanant una estructura de selecci si el valor que s a punt de ser llegitser realment un enter o no.

    1 import java.util.Scanner;2 //Un programa que llegeix un nombre conegut de valors enters.3 public class LectorValorsConeguts {4 //Es llegiran 10 valors.5 public static final int NUM_VALORS = 10;6 public static void main (String[] args) {7 Scanner lector = new Scanner(System.in);8 System.out.println("Escriu " + NUM_VALORS + " enters. Es pot fer en

    diferents lnies.");9 //Es llegeixen exactament NUM_VALORS valors.

    10 int numValorsLlegits = 0;11 while (numValorsLlegits < NUM_VALORS) {12 //Abans de llegir, comprovem si realment hi ha un enter.13 if (lector.hasNextInt()) {14 int valor = lector.nextInt();15 System.out.println("Valor " + numValorsLlegits + " llegit: " + valor);16 numValorsLlegits++;17 } else {18 //Si el valor no s enter, es llegeix per signora.19 //No savana tampoc el comptador.20 lector.next();21 }22 }23 //Els valors que sobrin a la darrera lnia escrita es descarten.24 lector.nextLine();25 System.out.println("Ja shan llegit " + NUM_VALORS + " valors.");26 }27 }

    Quantitat de dades desconeguda

    Un cas ms complex s quan el nombre de valors no s conegut a priori, jaque pot variar en diferents execucions del programa. Quan aix succeeix, unasoluci simple seria preguntar simplement, abans de llegir cap valor, quantesdades sintroduiran, o b fer que el primer valor dins de la seqncia nindiquila longitud.

    Si aix no s possible, o es considera que no sha de fer, una altra opci s establirun valor especial que no forma part de les dades per tractar dins el programa,sin que es considerar com a marca de final de seqncia. Tan bon punt esllegeixi aquest valor, la lectura sha de donar per finalitzada. La condici per poderusar aquesta estratgia s que la marca no sigui un valor que pugui aparixer maientre els valors introduts. Ha de ser nic. Per exemple, dins una llista de notes,qualsevol valor negatiu o major que 10 serviria. La resta de valors no es podenusar, ja que poden correspondre a una nota real que cal tractar.

    Si tots els valors possibles sn acceptables dins de la seqncia una opci s usarun valor dun tipus de dada diferent. Per exemple, un programa que processa valorsreals arbitraris per fer clculs matemtics podria usar un carcter com a marca defi.

    En aquest cas, lestratgia per utilitzar s usar una estructura de repetici basadaen semfor. Aquest us indica si ja sha llegit la marca de fi i cal deixar diterar ono.

  • Programaci bsica (ASX)Programaci (DAM) 18 Tipus de dades compostes

    El codi segent dexemple llegeix una seqncia de valors enters de llargriaarbitrria. La lectura finalitza tan bon punt es llegeix el valor -1. Compareuaquest codi amb lexemple del cas anterior.

    1 import java.util.Scanner;2 public class LectorValorsDesconeguts {3 public static final int MARCA_FI = 1;4 public static void main (String[] args) {5 Scanner lector = new Scanner(System.in);6 System.out.print("Escriu diferents valors enters.");7 System.out.println("Desprs del darrer valor escriu un " + MARCA_FI);8 //Es llegeixen exactament NUM_VALORS valors.9 boolean marcaTrobada = false;

    10 while (!marcaTrobada) {11 //Abans de llegir, comprovem si realment hi ha un enter.12 if (lector.hasNextInt()) {13 int valor = lector.nextInt();14 //s la marca de fi?15 if (valor == MARCA_FI) {16 //S que ho s.17 marcaTrobada = true;18 } else {19 //No. s un valor que ha de ser tractat.20 System.out.println("Valor llegit: " + valor);21 }22 } else {23 //Si el valor no s enter, es llegeix per signora.24 lector.next();25 }26 }27 //Els valors que sobrin a la darrera lnia escrita es descarten.28 lector.nextLine();29 System.out.println("Ja shan llegit tots els valors.");30 }31 }

    1.3.2 "Arrays" completament ocupats

    Lesquema ms simple demmagatzematge de dades des duna entrada a lesposicions dun array s el cas en qu la quantitat de dades que es llegir s coneixprviament. Aix es deu a la important restricci que, per inicialitzar un array,prviament se nha destablir la mida. Aquest s un requisit indispensable, ja queen cas contrari qualsevol intent de desar-hi dades resultar en un error dexecuci.En aquest cas, nhi ha prou dinicialitzar larray amb les seves posicions ambvalor per defecte i una mida igual al nombre de dades que es llegiran. Un copfet, noms cal llegir de lentrada un nombre de dades esperat i anar assignant elsvalors daquestes dades a cadascuna de les posicions de larray, consecutivament.

    Un fet que heu de tenir amb compte s que pot ser que sindiqui que el nombre dedades per entrar s un valor, per desprs, per error, sen proporcionin ms. Enqualsevol cas, mai no es poden llegir ms dades que la capacitat real de larray,per la qual cosa totes aquestes dades sobrants signoraran. Un cop larray est almxim de la seva capacitat, sha dacabar el procs de lectura o us exposeu a unerror dexecuci en sobrepassar la mida de larray.

    La figura 1.5mostra un esquema de la lectura duna seqncia de valors per ocupartotalment un array.

  • Programaci bsica (ASX)Programaci (DAM) 19 Tipus de dades compostes

    Figura 1.5. Esquema dentrada de dades per crear un array totalment ocupat

    Com a exemple, suposeu un programa per tractar les notes davaluaci dunconjunt destudiants. Per obtenir les diferents notes, aquest llegeix una seqncia,de llargria coneguda, composta de nombres reals. Amb els valors llegits somplecompletament un array. Compileu i executeu el codi segent per dur a termeaquesta operaci. Fixeu-vos que, en aquest cas, es comproven un seguit derrorspossibles a lentrada de les dades abans demmagatzemar el valor final a larray:si els valors introduts sn realment de tipus real i si estan dins del rang vlid pera una nota (entre 0 i 10).

    1 import java.util.Scanner;2 //Programa que llegeix una seqncia de valors reals, de longitud coneguda.3 public class LectorSequencia {4 public static void main (String[] args) {5 Scanner lector = new Scanner(System.in);6 //Llegeix la longitud de la seqncia. Comprova tots els errors.7 int nombreValors = 0;8 while (nombreValors = 0)&&(nota

  • Programaci bsica (ASX)Programaci (DAM) 20 Tipus de dades compostes

    Cada posici dun arrayocupa tanta memria com el

    tipus primitiu que potemmagatzemar.

    Colloquialment, una posicien qu no hi ha cap valorvlid assignat es diu que

    est buida.

    40 }41 //Ignorem els valors sobrants de la darrera lnia.42 lector.nextLine();43 System.out.println("La seqncia llegida s:");44 for (int i = 0; i < arrayNotes.length;i++) {45 System.out.println(arrayNotes[i]);46 }47 }48 }

    1.3.3 "Arrays" parcialment ocupats

    Malauradament, hi ha circumstncies sota les quals no s possible inicialitzar unarray de manera que la seva mida sajusti exactament a la llargria de la seqnciade valors dentrada. Hi ha dos motius que poden dur a aquesta situaci. Dunabanda, si simplement no es coneix a priori el nombre de dades que sentraran, jaque en lloc del programa es pregunta prviament, i per tant lentrada de dades sduna llargria desconeguda. Daltra banda, aix tamb succeeix en llenguatgesde programaci en qu a lhora de declarar un array i inicialitzar-lo no s possibleusar una variable per especificar-ne la mida, i noms es pot usar un literal.

    En un cas com aquest, us haureu de conformar a triar un valor concret prefixatper a la mida de larray i donar per fet que el nombre de dades dentrada que elprograma pot tractar s limitat. Si per algunmotiu, en llegir les dades dentrada, sesupera aquest lmit, com que no s possible emmagatzemar els valors excedents,els haureu dignorar. Per tant, caldr triar aquesta mida arribant a un compromsentre un valor que sigui prou gran per no trobar-vos gaire sovint amb aquestasituaci, per tampoc massa exagerat, per no malbaratar memria. Per exemple,si ja sabeu que el nombre destudiants en una classe pot oscillar, per mai no espermetr que nhi hagi ms de 80 (en aquest cas, sobriria una nova aula), es pottriar aquest valor com a mida de larray. Cal estudiar cada cas concret.

    Figura 1.6. Esquema dentrada de dades que genera un array parcialment ocupat

    En un cas com aquest, en qu es disposa dun array amb una mida que mai no serexactament igual al nombre de dades llegides des de lentrada (de fet, normalment,ser inferior), noms hi ha un rang de posicions en qu hi ha dades llegides de

  • Programaci bsica (ASX)Programaci (DAM) 21 Tipus de dades compostes

    lentrada. La resta de posicions tenen valors per defecte que no tenen res a veureamb lentrada, i per tant, no han de ser previstes a lhora de fer cap tasca. Lafigura 1.6 esquematitza aquest fet partint de la seqncia dentrada 2.0, 5.5,9.0, 10.

    Un altre aspecte important s que latribut length ara no s suficient per saberel rang de les dades vlides. Noms indica la capacitat de larray. Per tant,ser necessari disposar duna variable auxiliar addicional, de tipus enter, en qusemmagatzemi el nombre de dades que realment hi ha dins de larray. Qualsevolaccs a larray noms obtindr dades correctes si lndex emprat es troba entre 0i aquest valor auxiliar - 1.

    El codi segent s lequivalent dentrada de notes per per al cas duna entradade dades de llargria desconeguda. Com que no se sap quantes dades cal llegir,s necessari indicar dalguna manera quan sha acabat dentrar dades, amb unamarca de final. En aquest cas, es tracta del valor -1. El lmit de dades que scapa demmagatzemar sha establert en 80, definit com la constant MAX_VALORS.

    Proveu-lo al vostre entorn de treball i estudieu-ne el funcionament.

    1 import java.util.Scanner;2 //Llegeix un conjunt de dades sense saber quantes sn.3 public class LectorSequenciaDimDesconeguda {4 public static final int MAX_VALORS = 80;5 public static final int MARCA_FI = 1;6 public static void main (String[] args) {7 //No se sap quantes nentraran. Cal fitar un valor mxim. Posem 80.8 float[] arrayNotes = new float[MAX_VALORS];9 //Cal un comptador de posicions actuals en qu hi ha valors.

    10 int elements = 0;11 Scanner lector = new Scanner(System.in);12 System.out.print("Escriure fins a " + MAX_VALORS + " valors.");13 System.out.println("En pots escriure diversos en una sola lnia, separats

    per espais.");14 //Caldr alguna manera de saber que sha acabat descriure.15 System.out.println("(Per acabar, escriu un" + MARCA_FI + ")");16 //Anar llegint fins a trobar la marca de fi. Per el mxim s la mida de l

    array.17 //Si sentren ms valors, els ignorem, ja que no queda lloc on emmagatzemar

    los.18 //Estructura de repetici amb semfor.19 while (elements < arrayNotes.length) {20 //Hi ha un real?21 if (lector.hasNextFloat()) {22 //Cal veure si s un valor vlid o final de seqncia.23 float nota = lector.nextFloat();24 if ((nota >= 0)&&(nota

  • Programaci bsica (ASX)Programaci (DAM) 22 Tipus de dades compostes

    41 for (int i = 0; i < elements;i++) {42 System.out.println(arrayNotes[i]);43 }44 }45 }

    A un array parcialment ocupat se li poden afegir noves dades posteriorment,sempre que no se superi la seva mida. Per fer-ho, aquestes shaurien dassignar apartir de la posici en qu es troba el darrer element vlid.

    1.4 Esquemes fonamentals en la utilitzaci d"arrays"

    El potencial dels arrays va molt ms enll de la mera capacitat de gestionarconjunts de dades de grandria arbitrria tan sols declarant una nica variable.Aquests tamb sn una eina extremadament verstil per processar totes les dadesque contenen amb poques lnies de codi de manera entenedora i eficient. El motiuprincipal s que les seves posicions sn accessibles a partir dndexs numrics.Aix en fa ideal el tractament usant estructures de repetici, que mitjanant uncomptador accedeixin una per una a totes les posicions.

    De fet, aquesta circumstncia ja ha quedat patent en lexemple de lectura dunaseqncia de dades des del teclat i lemmagatzemament en un array. Reflexioneusobre com seria el codi sense usar una estructura de repetici o arrays.

    Tot seguit veureu un seguit destratgies basades en aquesta circumstncia queval la pena que tingueu presents a lhora de treballar amb les dades contingudesdins dun array. Gaireb tots els programes basats en arrays nusen alguna. Persimplificar el codi dels exemples utilitzats, en lloc de partir duna entrada perteclat es treballar sobre un array inicialitzat amb valors concrets. Els algorismesno varien en absolut respecte dels arrays producte duna entrada per teclat.

    1.4.1 Inicialitzaci procedural

    Hi ha situacions en les quals els valors inicials dins dalguna o totes les posicionsde larray no necessriament han de dependre duna entrada, per usar el sistemadinicialitzaci amb valors concrets pot ser una mica incmode. Per exemple,suposeu que us cal disposar dels valors de les 20 primeres potncies de 2. Entractar-se de bastants valors, usar un array s ideal. Ara b, tot i que aquests valorses poden expressar directament com a literals, primer els haureu de calcular pelvostre compte i, tot seguit, inicialitzar larray. A ms, el resultat final s una lniafora llarga dins del codi, i nafecta la llegibilitat.

    Posats a haver de calcular prviament per la vostra banda els valors amb els qualscal inicialitzar larray, surt ms a compte que sigui el programa mateix qui faciaquest clcul i inicialitzi les posicions a mesura que trobi els resultats.

  • Programaci bsica (ASX)Programaci (DAM) 23 Tipus de dades compostes

    Sanomena generaci procedural el fet de generar contingutalgorsmicament, en lloc de fer-ho manualment partint de valorspreestablerts. s un terme especialment usat dins del disseny de videojocs.

    Com que quan es fa una inicialitzaci daquest tipus el nombre de valors sconegut, es pot assignar una mida a larray de manera que estigui totalmentocupat. Compileu i executeu el codi segent, que inicialitza proceduralment unarray de manera que el valor a cada posici sigui el doble de lanterior, partintduna primera posici amb valor 1.

    1 //Un programa que inicialitza proceduralment un array amb valors relacionatsentre si.

    2 public class InicialitzaciProcedural {3 public static void main (String[] args) {4 //Caldr emmagatzemar 20 enters.5 int[] arrayValorsDobles = new int[20];6 //La primera posici la posem directament.7 arrayValorsDobles[0] = 1;8 //La resta es va omplint seqencialment, a fora de clculs.9 for(int i = 1; i < arrayValorsDobles.length; i++) {

    10 arrayValorsDobles[i] = 2 * arrayValorsDobles[i 1];11 }12 System.out.print("Sha generat larray: [ ");13 for (int i = 0; i < arrayValorsDobles.length; i++) {14 System.out.print(arrayValorsDobles[i] + " ");15 }16 System.out.print("]");17 }18 }

    Per estudiar el funcionament del programa de manera ms detallada, resulta tilusar una taula que indiqui levoluci de les variables a cada iteraci, tal com fa lataula 1.2.

    Taula 1.2. Evoluci del bucle per inicialitzar un array amb potncies de 2

    Iteraci Inici del bucle Fi del bucle

    i val Condici val Posici modificada Valor assignat

    1 1 (1 < 20), true arrayValorsDobles[1] 2*arrayValorsDobles[0], 2 *1 = 2

    2 2 (2 < 20), true arrayValorsDobles[2] 2*arrayValorsDobles[1], 2 *2 = 4

    3 3 (3 < 20), true arrayValorsDobles[3] 2*arrayValorsDobles[2], 2 *4 = 8

    4 4 (4 < 20), true arrayValorsDobles[4] 2*arrayValorsDobles[3], 2 *8 = 16

    ...

    18 19 (19 < 20), true arrayValorsDobles[19] 2*arrayValorsDobles[18],2*262144 = 524288

    19 20 (20 < 20), false Ja hem sortit del bucle

    Repte 1: feu un programa que inicialitzi proceduralment un array amb els 100primers nombres parells (Nota: el 0 s parell).

  • Programaci bsica (ASX)Programaci (DAM) 24 Tipus de dades compostes

    Recorregut

    Parlem de recorregut quan caltractar tots els valors de larray.

    1.4.2 Recorregut

    Quan treballeu amb arrays, molt sovint haureu de fer clculs en qu estan implicatstots els valors emmagatzemats o, si ms no, una bona part. En aquest cas, cal fer-ne un recorregut seqencial de les posicions i anar-les processant per obtenir unresultat final. Un exemple duna situaci com aquesta pot ser calcular la mitjanaaritmtica dun seguit de notes, que requereix sumar els valors de totes i cadascunai dividir el resultat entre el seu nombre.

    El cas dun array totalment ocupat s el ms senzill, ja que s suficient recrrerlarray en tota la seva extensi fins arribar al final de lextensi, donada per lamida.

    Com a exemple, executeu el codi segent, que calcula la mitjana aritmtica dunseguit de notes, expressades com a valors reals, contingudes dins dun array.

    1 //Un programa que fa un recorregut dun array: clcul de la mitjana aritmtica.2 public class RecorregutTotalmentOcupat {3 public static void main(String[] args) {4 //Es parteix dun array que cont tots els valors.5 float[] arrayNotes = {2f, 5.5f, 9f, 10f, 4.9f, 8f, 8.5f, 7f, 6.6f, 5f, 9f,

    7f};6 //Acumulador de la suma de valors.7 float acumulat = 0;8 //Cal recrrer tot larray dextrem a extrem.9 for(int i = 0; i < arrayNotes.length; i++) {

    10 acumulat = acumulat + arrayNotes[i];11 }12 float resultat = acumulat / arrayNotes.length;13 System.out.println("El resultat s " + resultat);14 }15 }

    A la taula 1.3, mitjanant lestudi de levoluci del bucle, es pot veure com es vanrecorrent una per una totes les posicions de larray.

    Taula 1.3. Evoluci del bucle per recrrer larray i calcular la suma de tots els valors

    Iteraci Inici del bucle Fi del bucle

    i val Condici val Posici accedida acumulat val

    1 0 (0 < 12), true arrayNotes[0], 2.0 0 + 2.0 = 2.0

    2 1 (3 < 12), true arrayNotes[1], 5.5 2.0 + 5.5 = 7.5

    3 2 (4 < 12), true arrayNotes[2], 9.0 7.5 + 9.0 = 16.5

    ...

    12 11 (11 < 12), true arrayNotes[11], 7.0 75.5 + 7.0 = 82.5

    13 12 (12 < 12), false Ja hem sortit del bucle

    En el cas dun array parcialment ocupat cal anar amb compte, ja que el recorregutno necessriament ha de ser fins a la darrera posici, sin fins a la darrera posiciocupada. Lalgorisme de recorregut a escala general ser el mateix, per lacondici de sortida del bucle canviar. Per exemple, si el nombre de valors enlarray es troba en la variable darreraPosicio, el codi seria:

  • Programaci bsica (ASX)Programaci (DAM) 25 Tipus de dades compostes

    1 ...2 //Noms es tracten els valors realment vlids.3 for(int i = 0; i < darreraPosicio; i++) {4 ...

    Repte 2: modifiqueu el codi del recorregut perqu, en lloc de la mitjana, calculiquina s la nota mxima.

    1.4.3 Cerca

    Una altra tasca que sovint es fa en treballar amb arrays s cercar valors concretsdins seu. Per aix, cal anar mirant totes les posicions fins a trobar-lo. Per exemple,veure si entre un seguit de notes alg ha estat capa de treure un 10.

    Fins a cert punt, es pot considerar que una cerca no s ms que un tipus especialde recorregut. En aquest cas, lmfasi es fa en la circumstncia que no sempre calrecrrer tots els elements de larray, noms fins a trobar el valor que busquem.De fet, arribar al final de larray s el que indica que no sha trobat el valor cercat.

    Executeu el codi segent, que fa la cerca dalgun valor igual a 10 entre un seguitde notes. Fixeu-vos que en aquest codi se surt del bucle tan bon punt es troba elvalor que busquem. Ja no cal seguir iterant. Tal com es presenta aquest codi, el 10es troba a la quarta iteraci. Podeu veure qu passa si no sen troba cap si abansde compilar modifiqueu manualment quest valor per un altre en la inicialitzacide larray.

    1 //Un programa per veure si alg ha tret un 10.2 public class Cerca {3 public static void main(String args[]) {4 //Es parteix dun array que cont tots els seus valors.5 float[] arrayNotes = {2f, 5.5f, 9f, 10f, 4.9f, 8f, 8.5f, 7f, 6.6f, 5f, 9f,

    7f};6 //Semfor. Sha trobat?7 boolean trobat = false;8 //Comptador de posicions.9 int i = 0;

    10 //Es va mirant cada posici, mentre no sarriba al final i no es trobi un10.

    11 while ((i < arrayNotes.length)&&(!trobat)) {12 if (arrayNotes[i] == 10) {13 trobat = true;14 }15 i = i + 1;16 }17 //Sha trobat?18 if (trobat) {19 System.out.println("Alg ha tret un 10.");20 } else {21 System.out.println("Ning no ha tret un 10");22 }23 }24 }

    Un cop ms, una taula per veure levoluci del bucle us pot ajudar a veure com,tan bon punt es troba el valor cercat, les iteracions acaben immediatament. Com

    Cerca

    Parlem de cerca quan noms caltractar els valors de larray fins atrobar lobjectiu.

  • Programaci bsica (ASX)Programaci (DAM) 26 Tipus de dades compostes

    es pot veure a la taula 1.4, no cal recrrer tot larray. A la darrera iteraci sesubratlla la part de lexpressi que causa que avalu a false.

    Taula 1.4. Evoluci del bucle per recrrer larray i calcular la suma de tots els valors

    Iteraci Inici del bucle Fi del bucle

    i val trobat val Condici val Posici accedida trobat val

    1 0 false (0 < 12)&&(!false),true

    arrayNotes[0], 2.0 false

    2 1 false (1 < 12)&&(!false),true

    arrayNotes[1], 5.5 false

    3 2 false (2 < 12)&&(!false),true

    arrayNotes[2], 9.0 false

    4 3 false (3 < 12)&&(!false),true

    arrayNotes[3], 10.0 true

    5 4 true (4 < 12)&&(!true),false

    Ja hem sortit del bucle

    Repte 3: modifiqueu el codi de lexemple per poder veure si hi ha alg que hasusps lassignatura o no. Feu-ho usant la sentncia break.

    Si b fins al moment els esquemes ds darrays shan centrat en valors numrics,tamb sn aplicables a altres tipus primitius com els carcters. Saber aplicar-lossobre conjunts de carcters s especialment interessant per entendre les estratgiesper tractar text. A ttol illustratiu, tot seguit es mostra un exemple darray basaten la cerca dun carcter concret. Observeu com el codi relatiu a la cerca, a granstrets, s idntic al relatiu a valors numrics. Noms varia en els petits detallsrelatius al tipus de dada que cont larray.

    1 //Cerca si hi ha la lletra w entre un seguit de carcters.2 public class CercaCaracter {3 public static void main (String[] args) {4 //Es parteix dun array que cont un seguit de carcters.5 char[] arrayNotes = {a, z, g, d, w, o, h, e, x, s};6 //Semfor. Sha trobat?7 boolean trobat = false;8 //Comptador de posicions.9 int i = 0;

    10 //Es va mirant cada posici, mentre no sarriba al final i no es trobi una"w".

    11 while ((i < arrayNotes.length)&&(!trobat)) {12 if (arrayNotes[i] == w) {13 trobat = true;14 }15 i = i + 1;16 }17 //Sha trobat?18 if (trobat) {19 System.out.println("La lletra w s a la llista.");20 } else {21 System.out.println("La lletra w no s a la llista.");22 }23 }24 }

  • Programaci bsica (ASX)Programaci (DAM) 27 Tipus de dades compostes

    1.4.4 s d"arrays" auxiliars

    La utilitzaci dun array dins del codi dun programa pot anar ms enll demma-gatzemar seqncies de dades de longitud arbitrria obtingudes des duna entrada.Tamb sn tils com a manera senzilla de gestionar molts valors diferents ambun nic identificador, en lloc dhaver de declarar diverses variables. Aquestavia s especialment til per a casos en qu cal gestionar dades que tenen un certvincle entre elles. Una altra utilitat dels arrays es pot extreure de la seva capacitatdaccedir a les seves posicions usant un ndex per simplificar el codi.

    Per exemple, suposeu que voleu fer un programa que, a partir de les notes delsestudiants duna aula, generi un grfic de barres (o histograma) en qu sindiqui elnombre destudiants que han tret susps, aprovat, notable o excellent. Per poderdur a terme aquesta tasca, us caldr disposar dun seguit de comptadors, un pera cada categoria de nota, i fer un recorregut de totes les notes. Segons el rang alqual pertanyi cada nota, sincrementar un comptador o un altre.

    Tot seguit teniu el codi del programa que fa aquesta tasca usant un array, en llocde quatre variables diferents. Compileu i proveu que funciona. En aquest cas,larray de notes ja est donat directament, per podreu adaptar el codi de maneraque llegs els valors pel teclat.

    1 public class Histograma {2 public static void main (String[] args) {3 float[] arrayNotes = {2f, 5f, 9f, 6.5f, 10f, 4.5f, 8.5f, 7f, 6f, 7.5f, 9f,

    7f};4 //Inicialitzaci dels 10 comptadors, per a cada barra del grfic.5 int[] barres = new int[4];6 //Clcul dels comptadors. Es fa un recorregut de les notes.7 for (int i = 0; i < arrayNotes.length; i++) {8 //A quin rang pertany?9 if ((arrayNotes[i] >=0 )&&(arrayNotes[i] < 5)) {

    10 barres[0]++;11 } else if (arrayNotes[i] < 6.5) {12 barres[1]++;13 } else if (arrayNotes[i] < 9) {14 barres[2]++;15 } else if (arrayNotes[i]

  • Programaci bsica (ASX)Programaci (DAM) 28 Tipus de dades compostes

    37 System.out.print("Excel lent: ");38 break;39 }40 //Imprimim tantes estrelles com el valor del comptador.41 for (int j = 0; j < barres[i]; j++) {42 System.out.print("*");43 }44 System.out.println();45 }46 }47 }

    En aquest cas, la granularitat del grfic s baixa, i per aix es podria fer ambquatre variables diferents sense problemes. Ara b, hi ha una part del programaen qu disposar dun accs als quatre valors per ndex resulta de gran utilitat persimplificar el codi: en escriure el grfic per pantalla. Si susessin quatre variables,el codi per imprimir el grfic seria:

    1 ...2 System.out.println("Grfic de barres de les notes");3 System.out.println("");4 //Simprimeix el grfic.5 //Primer els suspesos.6 System.out.print("Susps: ");7 for (int j = 0; j < comptadorSuspes; j++) {8 System.out.print("*");9 }

    10 System.out.println();11 //Ara els aprovats.12 System.out.print("Aprovat: ");13 for (int j = 0; j < comptadorAprovats; j++) {14 System.out.print("*");15 }16 System.out.println();17 //Ara els notables.18 System.out.print("Notable: ");19 for (int j = 0; j < comptadorNotable; j++) {20 System.out.print("*");21 }22 System.out.println();23 //Ara els excel lents.24 System.out.print("Excel lent: ");25 for (int j = 0; j < comptadorExcellent; j++) {26 System.out.print("*");27 }28 System.out.println();29 ...

    Per escriure el resultat final en forma de grfic cal escriure tantes estrelles com valcada comptador individual. Si susen quatre variables separades, caldria repetirel mateix codi per a cada variable. Usant un array, nhi ha prou dusar unaestructura de repetici i fer un recorregut. A ms a ms, el valor de lndex alqual sest accedint tamb serveix per saber quin comptador sest tractant i, pertant, quin ttol cal escriure per a cada iteraci. Ara imagineu que es vol modificar elprograma per comptar la gent que ha tret notes dins de rangs amb ms granularitat(0-1, 1-2, ..., 9-10).

    Per tant, aquest s un exemple de cas en qu usar arrays auxiliars pot ser de granutilitat per no haver de repetir el codi.

  • Programaci bsica (ASX)Programaci (DAM) 29 Tipus de dades compostes

    1.4.5 Cpia

    Com sha dit, el tipus de dada array, al contrari que els tipus de dades primitius,no t cap operaci disponible. Noms es pot operar en les posicions individuals.El que s que est perms s fer assignacions usant directament les identificadorsde les variables de tipus array. Ara b, un fet certament curis s que lassignacino crea una cpia de les dades de larray original, sin que el que fa s confi-gurar lidentificador de destinaci perqu, a partir de llavors, per mitj daquestsaccedeixi a les mateixes dades en memria que lidentificador origen.

    La millor manera de veure la diferncia de comportament entre una assignacientre tipus de dades primitius i els arrays s amb un exemple de codi.

    1 ...2 //Assignaci amb tipus primitius:3 int i = 0;4 int j = 5;5 //A la variable "i" se li assigna el valor de "j".6 i = j;7 //Es modifica el valor de "j".8 j = 10;9 //"i" conserva el valor copiat des de "j", 5.

    10 System.out.println(i);11 ...

    1 ...2 //Assignaci amb arrays:3 int[] arrayA = {10, 20, 30, 40, 50};4 int[] arrayB = {60, 70, 80, 90, 100};5 //A la variable "arrayA" se li assigna el valor d"arrayB".6 arrayA = arrayB;7 //Es modifica el valor de lndex 2 noms d"arrayB".8 arrayB[2] = 60;9 //"arrayA" tamb ha vist modificat el seu valor a lndex 2!

    10 System.out.println(arrayA[2]);11 //Es modifica el valor de lndex 4 noms d"arrayA".12 arrayA[4] = 70;13 //"arrayB" tamb ha vist modificat el seu valor a lndex 4!14 System.out.println(arrayB[4]);15 //De fet, "a" i "b" accedeixen exactament a les mateixes dades.16 ...

    Una pregunta que pot sorgir ara s: qu ha passat amb les dades que hi haviainicialment a la variable arrayB? La resposta s que shan perdut. Ja no hi hamanera daccedir-hi. En el cas del Java, aix no s cap inconvenient, ja que quanunes dades deixen destar accessibles, sesborren de lamemria i el seu espai passaa estar disponible per a altres aplicacions. En altres llenguatges, les implicacionspoden ser diferents, o fins i tot es considera un error greu de programaci.

    Tenint en compte el comportament de lassignaci, per generar una cpia indepen-dent dun array cal tractar les posicions com a elements individuals, com passavaamb la resta doperacions.

    1 //Un programa que crea una cpia idntica, i independent, dun altre array.2 public class Copia {3 public static void main (String[] args) {

    La no-creaci duna cpiareal en dur a terme unaassignaci, sin dues viesdaccs a una mateixadada, s un tret com a totsels tipus de dadescompostos.

    En fer assignacions entrevariables de tipus array,lorigen i destinaci ni tansols han de tenir la mateixamida.

  • Programaci bsica (ASX)Programaci (DAM) 30 Tipus de dades compostes

    4 float[] llistaNotes = {2f, 5.5f, 9f, 10f, 4.9f, 8f, 8.5f, 7f, 6.6f, 5f, 9f,7f};

    5 //La cpia ha de tenir la mateixa mida que loriginal.6 float[] copiaLlistaNotes = new float[llistaNotes.length];7 //Anem copiant posici per posici.8 for (int i = 0; i < llistaNotes.length; i++) {9 copiaLlistaNotes[i] = llistaNotes[i];

    10 }11 //Mostrem la cpia per pantalla.12 System.out.print("Larray copiat s: [ ");13 for (int i = 0; i < llistaNotes.length;i++) {14 System.out.print(copiaLlistaNotes[i] + " ");15 }16 System.out.println("]");17 }18 }

    1.4.6 Canvi de mida

    Un cop us heu decidit per un valor concret per a la mida dun array, ja no hi havolta enrere. No es pot canviar. Aix t certs inconvenients, ja que pot passarque, en determinades condicions, us quedeu sense espai per poder emmagatzemardades. Per si b no s possible canviar la mida dun array, aquest problema nos irresoluble. Noms cal seguir les passes segents:

    1. Generar un nou array en una variable diferent, amb una mida superior aloriginal.

    2. Copiar-hi les dades de larray original en el mateix ordre. En fer-ho, el nouarray quedar amb posicions buides.

    3. Aprofitant les propietats de lassignaci entre arrays, sassigna el nou arraya larray original.

    4. Finalment, afegir al nou array els valors extra que ja no cabien en loriginal.

    Arribats a aquest punt, s com si a efectes prctics shagus fet ms gran larrayoriginal. El codi segent mostra un exemple daquest esquema.

    Un exemple de boc de codi que fa aquestes accions seria el que es mostra acontinuaci. En aquest, la mida de larray original sincrementa de manera queshi afegeixen MAX_VALORS, noves posicions.

    1 ...2 float[] arrayNotes = new float[...];3 ...4 //PAS 15 float[] arrayNou = new float[arrayNotes.length + MAX_VALORS];6 //PAS 27 for (int i = 0; i < arrayNotes.length; i++) {8 arrayNou[i] = arrayNotes[i];9 }

    10 //PAS 311 arrayNotes = arrayNou;12 //Ara ja es poden desar MAX_VALORS nous valors extra dins darrayNotes13 ...

  • Programaci bsica (ASX)Programaci (DAM) 31 Tipus de dades compostes

    El codi segent adapta la lectura per teclat duna seqncia de llargria descone-guda de manera que, si se supera la capacitat de larray en qu semmagatzemenels valors, la seva mida sincrementa per poder encabir-ne de nous. Compileu-loi executeu-lo per veure com funciona.

    1 import java.util.Scanner;2 public class CanviMida {3 public static final int MAX_VALORS = 5;4 public static void main (String[] args) {5 //Dentrada, la mida ser 5.6 //Sescull un valor molt baix perqu de seguida es forci el canvi de mida.7 float[] arrayNotes = new float[MAX_VALORS];8 //Cal un comptador de posicions en qu hi ha valors vlids.9 int elements = 0;

    10 Scanner lector = new Scanner(System.in);11 System.out.print("Vs escrivint notes (valors reals entre 0 i 10).");12 System.out.println("En pots escriure diversos en una sola lnia, separats

    per espais.");13 //Caldr alguna manera de saber que sha acabat descriure.14 System.out.println("(Per acabar, escriu un 1)");15 //Anar llegint fins a trobar la marca de fi. Per el mxim s la mida de l

    array.16 //Si sentren ms valors, canviem la mida de larray i continuem llegint.17 //Estructura de repetici amb semfor.18 boolean marcaFi = false;19 while (!marcaFi) {20 //Hi ha un real?21 if (lector.hasNextFloat()) {22 //Cal veure si s un valor vlid o final de seqncia.23 float nota = lector.nextFloat();24 if ((nota >= 0)&&(nota

  • Programaci bsica (ASX)Programaci (DAM) 32 Tipus de dades compostes

    Lalgorisme dordenaci msrpid i eficient que hi ha s

    el QuickSort.

    Cal dir que fer aquest tipus de tasca s especialment ineficient i t un impacte sobreel rendiment del programa. s millor noms usar aquest esquema si realment nohi ha ms remei. Si es fa, normalment, a lhora de triar la mida del nou array smillor no ajustar massa i deixar espai de sobres per omplir noves posicions si snecessari sense haver-vos de veure forats a repetir aquest procs constantment.

    1.4.7 Ordenaci

    Hi ha vegades en qu resulta molt til reorganitzar els valors que hi ha dinslarray de manera que estiguin ordenats de manera ascendent o descendent. Enmolts casos, mostrar les dades de manera ordenada s simplement un requisit delaplicaci, de manera que lusuari les pugui visualitzar i extreuren conclusionsde manera ms cmoda. Per hi ha casos en qu disposar de les dades ordenadesfacilita la codificaci del programa i leficincia.

    Per exemple, en aquest mateix apartat heu vist com cercar, a partir dun seguit denotes, si algun estudiant ha tret un 10. Per fer aquesta tasca, calia una estructurade repetici i anar mirant un per un tots els valors dins larray. Per si les dadesestan ordenades en ordre ascendent, llavors podem usar una estratgia ms efica.Si alg t un 10, aquesta nota estar per fora a la darrera posici. Per tant, tota lacerca queda reduda directament al codi:

    1 ...2 if (arrayNotes[arrayNotes.length 1] == 10) {3 System.out.println("Alg ha tret un 10.");4 } else {5 System.out.println("Ning no ha tret un 10");6 }7 ...

    De cop i volta el codi es fa ms rpid i curt, ja que no cal lestructura derepetici. En general, les dades ordenades resulten dutilitat a lhora de fer cerqueso recorreguts en qu les dades per tractar tenen un rang o un valor concret, ja quepermeten establir estratgies que minimitzin els nombre diteracions dels bucles.

    Per ordenar una seqncia de valors hi ha diversos algorismes. Els ms eficientssn fora complexos i es troben ms enll dels objectius daquest mdul. Nhi haprou de veuren un de ms senzill.

    Lalgorisme de la bombolla (BubbleSort) serveix per ordenar elementsmitjanant recorreguts successius al llarg de la seqncia, en qu es vancomparant parelles de valors. Cada cop que es troben dues parelles en ordreincorrecte, sintercanvia la seva posici.

    Bsicament, el que es fa s cercar el valor ms baix, recorrent tot larray, i posar-lo a la primera posici. Amb aix ja tenim la garantia dhaver resolt quin valor hadacabar a la primera posici. Llavors se cerca el segon valor ms baix, recorrentla seqncia des de la segona posici fins al final, i es posa a la segona posici.

  • Programaci bsica (ASX)Programaci (DAM) 33 Tipus de dades compostes

    I loperaci es va repetint fins a arribar a la darrera posici. Per fer aquesta tascasopera directament sobre els valors emmagatzemats a larray, intercanviant-loscada cop que trobem un valor ms baix que el que hi ha a la posici que sesttractant.

    El codi seria el segent. Analitzeu-lo per entendre qu est fent i proveu quefunciona correctament:

    1 //Un programa per ordenar valors usant lalgorisme de la bombolla.2 public class Ordenar {3 public static void main (String[] args) {4 float[] llistaNotes = {5.5f, 9f, 2f, 10f, 4.9f};5 //Bucle extern.6 //Sanir posant a cada posici tractada, comenant per la 0,7 //el valor ms baix que es trobi.8 for (int i = 0; i < llistaNotes.length 1; i++) {9 //Bucle intern.

    10 //Se cerca entre la resta de posicions quin s el valor ms baix.11 for(int j = i + 1; j < llistaNotes.length; j++) {12 //La posici tractada t un valor ms alt que el de la cerca. Els

    intercanviem.13 if (llistaNotes[i] > llistaNotes[j]) {14 //Per intercanviar valors cal una variable auxiliar.15 float canvi = llistaNotes[i];16 llistaNotes[i] = llistaNotes[j];17 llistaNotes[j] = canvi;18 }19 }20 }21 //El mostrem per pantalla.22 System.out.print("Larray ordenat s: [");23 for (int i = 0; i < llistaNotes.length;i++) {24 System.out.print(llistaNotes[i] + " ");25 }26 System.out.println("]");27 }28 }

    Com que aquest algorisme dordenaci es basa en dos bucles imbricats, val lapena fer una ullada ms detallada al seu funcionament. La taula 1.5 mostra unseguit diteracions fins a tenir en les dues primeres posicions els valors ms baixos.Fixeu-vos com el valor de la variable comptador j sempre s superior a i. A lescelles en qu sindica lestat de larray desprs de cada iteraci, se subratllen lesposicions que shan intercanviat, si s el cas.

    Taula 1.5. Evoluci de lalgorisme de la bombolla

    Inici del bucle Fi del bucle

    i val j val llistaNotes val llistaNotes[i] >llistaNotes[j]

    llistaNotes val

    Inici primera iteraci bucle extern. Se cerca el valor ms petit per posar-lo a la posici 0.

    0 1 {5.5, 9, 2, 10, 4.9} 5.5 > 9, false {5.5, 9, 2, 10, 4.9}

    0 2 {5.5, 9, 2, 10, 4.9} 5.5 > 2, true {2, 9, 5.5, 10, 4.9}

    0 3 {2, 9, 5.5, 10, 4.9} 2 > 10, false {2, 9, 5.5, 10, 4.9}

    0 4 {2, 9, 5.5, 10, 4.9} 2 > 4.9, false {2, 9, 5.5, 10, 4.9}

    Fi primera iteraci bucle extern. A llistaNotes[0] hi ha el valor ms petit.

    Inici segona iteraci bucle extern. Se cerca el segon valor ms petit per posar-lo a la posici 1.

    1 2 {2, 9, 5.5, 10, 4.9} 9 > 5.5, true {2, 5.5, 9, 10, 4.9}

  • Programaci bsica (ASX)Programaci (DAM) 34 Tipus de dades compostes

    Lordre dels ndexs simportant.

    Taula 1.5 (continuaci)

    Inici del bucle Fi del bucle

    1 3 {2, 5.5, 9, 10, 4.9} 5.5 > 10, false {2, 5.5, 9, 10, 4.9}

    1 4 {2, 5.5, 9, 10, 4.9} 5.5 > 4.9, true {2, 4.9, 9, 10, 5.5}

    Fi segona iteraci bucle extern. A llistaNotes[1] hi ha el segon valor ms petit.

    Inici tercera iteraci bucle extern. Se cerca el tercer valor ms petit per posar-lo a la posici 2.

    2 3 {2, 4.9, 9, 10, 5.5} 9 > 10, false {2, 4.9, 9 , 10, 5.5}

    2 4 {2, 4.9, 9, 10, 5.5} 9 > 5.5, true {2, 4.9, 5.5, 10, 9}

    Fi tercera iteraci bucle extern. A llistaNotes[2] hi ha el tercer valor ms petit.

    Inici quarta iteraci bucle extern. Se cerca el quart valor ms petit per posar-lo a la posici 3.

    3 4 {2, 4.9, 5.5, 10, 9} 10 > 9, true {2, 4.9, 5.5, 9, 10}

    Fi tercera iteraci bucle extern. A llistaNotes[3] hi ha el quart valor ms petit.

    Per fora, a la posici 4 hi ha el valor ms alt.

    4 4 Hem sortit del bucle extern (4 > llistaNotes.length - 1)

    Repte 4: modifiqueu lexemple dordenaci de manera que, un cop ordenatlarray, es calculi la mitjana aritmtica noms dels estudiants que han susps. Elbucle del recorregut ha de fer exactament tantes iteracions com estudiants suspesoshi hagi, i no pas com tota la mida de larray. Reflexioneu atentament sobre com elfet que larray estigui ordenat s determinant per assolir aquesta darrera condici.

    1.5 "Arrays" multidimensionals

    Quan es declara un array, hi ha una propietat especial, a part del seu identificadorde tipus i mida, que fins al moment sha obviat. Es tracta de la seva dimensi,el nombre dndexs que cal usar per establir la posici que es vol tractar. Tots elsarrays amb els quals heu treballat fins ara eren unidimensionals. Nhi havia prouamb un sol valor dndex per indicar la posici que es volia accedir. Ara b, resno impedeix que el nombre dndexs sigui ms gran que 1.

    Un array multidimensional s aquell en qu per accedir a una posiciconcreta, en lloc dusar un sol valor com a ndex, susa una seqncia dediversos valors. Cada ndex serveix com a coordenada per a una dimensidiferent.

    Un "array" de dimensi 2: una taula

    Entre els arrays multidimensionals, el cas ms usat s el dels arrays bidimensio-nals, de dues dimensions. Aquest s un dels ms fcils de visualitzar i s, per tant,un bon punt de partida. Com que es tracta dun tipus darray en qu calen dosndexs per establir una posici, es pot considerar que el seu comportament s comel duna matriu, taula o full de clcul. El primer ndex indicaria la fila, mentre queel segon indicaria la columna on es troba la posici que es vol accedir.

  • Programaci bsica (ASX)Programaci (DAM) 35 Tipus de dades compostes

    Per exemple, suposeu que el programa per tractar notes destudiants ara ha degestionar les notes individuals de cada estudiant per a un seguit dexercicis, demanera que es poden fer clculs addicionals: calcular la nota final segons elsresultats individuals, veure levoluci de cada estudiant al llarg del curs, etc. Enaquest cas, tota aquesta informaci es pot resumir de manera eficient en una taula ofull de clcul, en qu els estudiants es poden organitzar per files, on cada columnacorrespon al valor duna prova, i en qu la darrera columna pot ser la nota final.

    1.5.1 Declaraci d"arrays" bidimensionals

    La sintaxi per declarar i inicialitzar un array de dues dimensions s semblant ala dels unidimensionals, si b ara cal especificar que hi ha un ndex addicional.Aix es fa usant un parell de claus extra, [], sempre que calgui especificar un noundex.

    Per declarar-ne un dinicialitzat amb totes les posicions dels seus valors perdefecte, caldria usar la sintaxi:

    1 paraulaClauTipus[] identificadorVariable = new paraulaClauTipus[nombreFiles][nombreColumnes];

    Com passava amb els arrays unidireccionals, el valor dels ndexs, files i columnes,no ha de ser necessriament un literal. Pot ser definit dacord amb el contingutduna variable, diferent per a cada execuci del programa. El valor del nombre defiles i columnes tampoc no ha de ser necessriament el mateix.

    La inicialitzaci mitjanant valors concrets implica indicar tants valors com elnombre de files per columnes. Per fer-ho, primer senumeren els valors individualsque hi ha a cada fila de la mateixa manera que sinicialitza un array unidimensio-nal: una seqncia de valors separats per comes i envoltats per claudtors, {...}.Un cop enumerades les files daquesta manera, aquestes senumeren al seu tornseparades per comes i envoltades per claudtors. Conceptualment, s com declararun array de files, en qu cada posici t un altre array de valors. Aix es veu msclar amb la sintaxi, que s la segent:

    1 paraulaClauTipus[][] identificadorVariable = {2 {Fila0valor1, Fila0valor2, ... , Fila0valorN},3 {Fila1valor1, Fila1valor2, ... , Fila1valorN},4 ...,5 {FilaNvalor1, FilaNvalor2, ... , FilaNvalorN}6 };

    Fixeu-vos com a linici i al final hi ha els claudtors extra que tanquen la seqnciade files i desprs de cada fila hi ha una coma, per separar-les entre si. Perfer ms clara la lectura, shan usat diferents lnies de text per indicar els valorsemmagatzemats a cada fila, per res no impedeix escriure-ho tot en una sola lniamolt llarga. De tota manera, s recomanable usar aquest format i intentar deixarespais on pertoqui de manera que els valors quedin alineats verticalment, ja queaix facilita la comprensi del codi font.

  • Programaci bsica (ASX)Programaci (DAM) 36 Tipus de dades compostes

    Assegureu-vos dusarvariables diferents per

    indicar cada ndex.

    Per exemple, per declarar i inicialitzar amb valors concrets un array bidimensionalde tres files per cinc columnes de valors de tipus enter es faria:

    1 int[][] arrayBidi = {2 {1 ,2 ,3 ,4 ,5 },3 {6 ,7 ,8 ,9 ,10},4 {11,12,13,14,15}5 };

    Des del punt de vista duna taula o matriu, La primera fila seria {1, 2, 3, 4, 5}, lasegona {6 ,7 ,8 ,9 ,10} i la tercera {11,12,13,14,15}, tal com mostra la taula 1.6.

    Taula 1.6. Resultat dinicialit-zar amb valors concrets un ar-ray bidimensional de tres filesper cinc columnes

    1 2 3 4 5

    6 7 8 9 10

    11 12 13 14 15

    En usar aquest tipus dinicialitzaci cal assegurar-se que les mides de totes les filessiguin exactament igual (que tinguin el mateix nombre de valors separats entrecomes), ja que cal garantir que totes les files tenen el mateix nombre de columnes.

    1.5.2 Esquemes ds d"arrays" bidimensionals

    Laccs a les posicions dun array bidimensional s prcticament idntic alunidireccional, per tenint en compte que ara hi ha dos ndexs per preveurereferents a les dues coordenades.

    1 identificadorVariable[ndexFila][ndexColumna]

    La taula 1.7 fa un resum de com saccediria a les diferents posicions dun array de4 * 5 posicions. En qualsevol cas, en accedir-hi, sempre cal mantenir present quecada ndex mai no pot ser igual o superior al nombre de files o columnes, segonscorrespongui. En cas contrari, es produeix un error.

    Taula 1.7. Aquesta taula mateixa s un array bidimensional de 4 * 5 posicions

    a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]

    a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]

    a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]

    a[3][0] a[3][1] a[3][2] a[3][3] a[3][4]

    Com que ara hi ha dos ndexs, tots els esquemes fonamentals per treballar ambarrays bidimensionals es basen en dues estructures de repetici imbricades, unaper tractar cada fila i laltra per tractar cada valor individual dins de la fila.

    En el cas darrays bidimensionals, latribut length t un comportament unamica especial, ja que ara hi ha dos ndexs. Per entendrel, cal recordar que perinicialitzar larray el que es fa s enumerar una llista de files, dins de les qualshi ha els valors emmagatzemats realment. Per tant, el que us diu latribut s elnombre de files que hi ha.

  • Programaci bsica (ASX)Programaci (DAM) 37 Tipus de dades compostes

    Per saber el nombre de valors duna fila heu de fer:

    1 identificadorVariable[ndexFila].length

    Per exemple, si la taula 1.7 correspon a una variable anomenada arrayBidi,arrayBidi.length avalua a 4 (hi ha quatre files) i arrayBidi[0].length,arrayBidi[1].length, etc. tots avaluen a 5 (hi ha 5 columnes).

    Inicialitzaci procedural

    Novament, es pot donar el cas en qu vulgueu assignar a cada posici valors quecal calcular prviament i que, per tant, calgui anar assignant un per un a totes lesposicions de larray bidimensional.

    A mode dexemple, compileu i executeu el codi font segent, que emmagatzemaa cada posici la suma dels ndexs dun array bidimensional de dimensionsarbitrries i desprs visualitza el resultat per pantalla, ordenat per files.

    1 import java.util.Scanner;2 //Un programa que inicialitza un array bidimensional.3 public class InicialitzacioBidi {4 public static void main (String[] args) {5 Scanner lector = new Scanner(System.in);6 //Llegeix les files.7 int nombreFiles = 0;8 while (nombreFiles

  • Programaci bsica (ASX)Programaci (DAM) 38 Tipus de dades compostes

    46 for(int i = 0; i < nombreFiles; i++) {47 //Inici de fila, obrim claudtors.48 System.out.print("Fila " + i + " { ");49 for (int j = 0; j < nombreColumnes; j++) {50 System.out.print(arrayBidi[i][j] + " ");51 }52 //Al final de cada fila es tanquen claudtors i es fa un salt de lnia.53 System.out.println("}");54 }55 }56 }

    Recorregut

    En el cas darrays bidimensionals, tamb pot passar que sigui necessari fer clculsfent un recorregut per tots els valors continguts. Novament, cal anar fila per fila,mirant totes les posicions de cadascuna.

    Per exemple, suposeu un programa en qu es desa a cada fila el valor de les notesdels estudiants dun curs. Es demana calcular la nota final de cada estudiant iemmagatzemar-la a la darrera columna, i tamb saber la mitjana de totes les notesfinals. El codi es mostra tot seguit; analitzeu-lo i proveu que funciona. En aquestcas, per facilitar-ne lexecuci, els valors de les notes estan inicialitzats per a valorsconcrets. En el cas de la nota final de cada estudiant, inicialment es deixa a 0 iser el programa el qui la calculi.

    Ara s: observeu atentament ls de latribut length per controlar els ndexs enrecrrer larray i saber quin s el nombre de valors en una fila o el nombre de files.

    1 //Un programa que calcula notes mitjanes en un array bidimensional.2 public class RecorregutBidi {3 public static void main (String[] args) {4 //Dades de les notes.5 float[][] arrayBidiNotes = {6 { 4.5f, 6f , 5f , 8f , 0f },7 { 10f , 8f , 7.5f, 9.5f, 0f },8 { 3f , 2.5f, 4.5f, 6f , 0f },9 { 6f , 8.5f, 6f , 4f , 0f },

    10 { 9f , 7.5f, 7f , 8f , 0f }11 };12 //Mitjana aritmtica del curs per a tots els estudiants.13 float sumaFinals = 0f;14 //Es fa tractant fila per fila, indicada per "i". Cada fila s un estudiant

    .15 //"arrayBidiNotes.length" avalua al nombre de files.16 for(int i = 0; i < arrayBidiNotes.length; i++) {17 //Aqu sacumulen les notes de lestudiant tractat.18 float sumaNotes = 0f;19 //Tractem cada fila (cada estudiant). Cada nota la indexa "j".20 //"arrayBidiNotes[i].length" avalua al nombre de posicions de la fila.21 for(int j = 0; j < arrayBidiNotes[i].length; j++) {22 //Estem a la darrera posici de la fila?23 if(j != (arrayBidiNotes[i].length 1)) {24 //Si no s la darrera posici, anem acumulant valors.25 sumaNotes = sumaNotes + arrayBidiNotes[i][j];26 } else {27 //Si ho s, cal escriure la mitjana.28 //Hi ha tantes notes com la mida duna fila 1.29 float notaFinal = sumaNotes/(arrayBidiNotes[i].length 1);30 arrayBidiNotes[i][j] = notaFinal;31 System.out.println("Lestudiant " + i + " ha tret " + notaFinal +

    ".");

  • Programaci bsica (ASX)Programaci (DAM) 39 Tipus de dades compostes

    32 //Sactualitza la suma de mitjanes de tots els estudiants.33 sumaFinals = sumaFinals + notaFinal;34 }35 }36 //Fi del tractament duna fila.37 }38 //Fi del tractament de totes les files.39 //Es calcula la mitjana: suma de notes finals dividit entre nombre d

    estudiants.40 float mitjanaFinal = sumaFinals / arrayBidiNotes.length;41 System.out.println("La nota mitjana del curs s " + mitjanaFinal);42 }43 }

    Cerca

    En arrays bidimensionals la cerca tamb implica haver de gestionar dos ndexs peranar avanant per files i columnes. Ara b, aquest cas s especialment interessant,ja que en assolir lobjectiu cal sortir de les dues estructures de repetici imbricades.Per tant, no es pot usar simplement una sentncia break, ja que noms serveix persortir dun nic bucle. Cal tenir un semfor que savalu en tots dos bucles.

    Per exemple, suposeu que el programa de gesti de notes vol cercar si algunestudiant ha tret un 0 en algun dels exercicis al llarg del curs. Caldr anarmirant fila per fila totes les notes de cada estudiant, i quan es trobi un 0, acabarimmediatament la cerca. El codi per fer-ho, basant-se exclusivament en un semforque diu si ja sha trobat el valor, seria el segent. Proveu-lo al vostre entorn detreball.

    En un cas com aquest, cal anar amb molt de compte a inicialitzar i incrementarcorrectament lndex per recrrer la posici de cada fila (s a dir, que miracada columna), ja que en usar una sentncia while en lloc de for no es faautomticament. Si us despisteu i no ho feu, el valor ser incorrecte per asuccessives iteracions del bucle que recorre les files i el programa no actuarcorrectament.

    1 //Un programa que cerca un 0 entre els valors dun array bidimensional.2 public class CercaBidi {3 public static void main (String[] args) {4 //Dades de les notes.5 float[][] arrayBidiNotes = {6 { 4.5f, 6f , 5f , 8f },7 { 10f , 8f , 7.5f, 9.5f},8 { 3f , 2.5f, 0f , 6f },9 { 6f , 8.5f, 6f , 4f },

    10 { 9f , 7.5f, 7f , 8f }11 };12 //Mirarem quin estudiant ha tret el 0.13 //Inicialitzem a un valor invlid (de moment, cap estudiant t un 0)14 //Aquest valor fa de semfor. Si pren un valor diferent, cal acabar la

    cerca.15 int estudiant = 1;16 //"i indica la fila.17 int i =0;18 //Es va fila per fila.19 //Sacaba si sha trobat un 0 o si ja sha cercat a totes les files.20 while ((estudiant == 1)&&(i < arrayBidiNotes.length)){21 //"j indica la "columna".22 int j =0;

  • Programaci bsica (ASX)Programaci (DAM) 40 Tipus de dades compostes

    23 //Se cerca en una fila.24 //Sacaba si sha trobat un 0 o si ja sha cercat a totes les posicions.25 while ((estudiant == 1)&&(j < arrayBidiNotes[i].length)){26 //Aquesta nota s un 0?27 if (arrayBidiNotes[i][j] == 0f) {28 //Lndex que diu lestudiant s el de la fila.29 estudiant = i;30 }31 //Savana a la posici segent dins de la fila.32 j++;33 }34 //Fi del tractament duna fila.35 //Savana a la fila segent.36 i++;37 }38 //Fi del tractament de totes les files.39 if (estudiant == 1) {40 System.out.println("Cap estudiant no t un 0.");41 } else {42 System.out.println("Lestudiant " + estudiant + " t un 0.");43 }44 }45 }

    Repte 5: modifiqueu el programa de manera que se cerqui si alg ha tret un 0,per noms en el segon exercici (posici 1 de cada fila). Reflexioneu atentamentsobre si ara realment cal usar dues estructures de repetici o no.

    1.5.3 "Arrays" de ms de dues dimensions

    El cas dels arrays bidimensionals s el ms com, per res no impedeix queel nombre dndexs necessaris per situar una posici sigui tamb ms gran dedos, dun valor arbitrari. Un array de tres dimensions encara es pot visualitzarcom una estructura tridimensional en forma de cub, per dimensions superiors jarequereixen ms grau dabstracci, i per aix noms es presentaran, sense entraren ms detall.

    Un "array" amb tres dimensions: elcub de Rubik. Imatge de Wikimedia

    Commons

    Conceptualment, es pot considerar que defineixen una estructura darrays imbri-cats a diferents nivells com el que es mostra a la figura 1.7. Cada nivell correspona una dimensi diferent.

    Figura 1.7. Un array multidimensional: arrays dins darrays dins darrays...

  • Programaci bsica (ASX)Programaci (DAM) 41 Tipus de dades compostes

    Cada ndex individual identifica una casella de larray triat duna dimensideterminada, de manera que el conjunt dndexs serveix com a coordenada perestablir el valor final (que ja no ser un altre array) al qual es vol accedir. Lafigura 1.8 en mostra un exemple de quatre dimensions.

    Figura 1.8. Accs a un array de quatre dimensions (calen 4 ndexs)

    Tot i que aquesta estructura sembla fora complexa, no s gaire diferent dunaestructura de carpetes i fitxers, en qu les carpetes prenen el paper dels arrays iels fitxers el de les dades que es volen desar. Podeu tenir una nica carpeta peremmagatzemar totes les fotos, que seria el cas dun nic nivell darray (o sigui,els arrays tal com shan vist fins ara). Per tamb les podreu organitzar amb unacarpeta que al seu torn cont altres carpetes, dins de les quals es desen diferentsfotos. Aix seria equivalent a disposar de dos nivells darrays. I aix podreu anarcreant una estructura de carpetes amb tants nivells com volgussiu. Per triar unfitxer nhi ha prou a saber en quin ordre cal anar obrint les carpetes fins a arribara la carpeta final, on ja noms us cal lordre del fitxer.

    Estenent les restriccions que compleixen els arrays bidireccionals al cas delsarrays multidimensionals:

    En una mateixa dimensi, tots els arrays tindran exactament la mateixamida.

    El tipus de dada que es desa a les posicions de la darrera dimensi ser elmateix per a tots. Per exemple, no es poden tenir reals i enters barrejats.

    En llenguatge Java, per afegir noves dimensions per sobre de la segona, cal anarafegint claus [] addicionals a la declaraci, una per a cada dimensi.

    1 paraulaClauTipus[]...[] identificadorVariable = new paraulaClauTipus[midaDim1]...[midaDimN];

    Per exemple, per declarar amb valors per defecte un array de quatre dimensions,la primera de mida 5, la segona de 10, la tercera de 4 i la quarta de 20, caldria lainstrucci:

  • Programaci bsica (ASX)Programaci (DAM) 42 Tipus de dades compostes

    1 ...2 int[][][][] arrayQuatreDimensions = new int[5][10][4][20];3 ...

    Laccs seria anleg als arrays bidimensionals, per usant quatre ndexs envoltatsper parells de claus.

    1 ...2 int valor = arrayQuatreDimensions[2][0][1][20];3 ...

    En qualsevol cas, es tracta destructures complexes que no se solen usar excepteen casos molt especfics.

  • Programaci bsica (ASX)Programaci (DAM) 43 Tipus de dades compostes

    1.6 Solucions dels reptes proposats

    Repte 1:

    1 public class InicialitzaParells {2 public static void main(String[] args) {3 //Caldr emmagatzemar 100 enters.4 int[] arrayParells = new int[100];5 //Anem omplint cada posici.6 for(int i = 0; i < arrayParells.length; i++) {7 arrayParells[i] = 2*i;8 }9 }

    10 }

    Repte 2:

    1 public class RecorregutMaxima {2 public static void main(String[] args) {3 //Es parteix dun array que cont tots els seus valors.4 float[] arrayNotes = {2f, 5.5f, 9f, 10f, 4.9f, 8f, 8.5f, 7f, 6.6f, 5f, 9f,

    7f};5 //Valor mxim fins al moment.6 float notaMaxima = 0;7 //Cal recrrer tot larray dextrem a extrem i desar el valor ms gran.8 for(int i = 0; i < arrayNotes.length; i++) {9 if (notaMaxima < arrayNotes[i]) {

    10 notaMaxima = arrayNotes[i];11 }12 }13 System.out.println("La nota mxima s " + notaMaxima);14 }15 }

    Repte 3:

    1 public class CercaSuspes {2 public static void main (String[] args) {3 //Es parteix dun array que cont tots els seus valors.4 float[] arrayNotes = {2f, 5.5f, 9f, 10f, 4.9f, 8f, 8.5f, 7f, 6.6f, 5f, 9f,

    7f};5 int i = 0;6 //Es va mirant cada posici, mentre no sarriba al final i no es trobi un

    susps.7 //Es pot usar tant "break" com "for".8 //En trobar un susps, directament sortim del bucle.9 while (i < arrayNotes.length) {

    10 if (arrayNotes[i] < 5) {11 break;12 }13 i++;14 }15 if (i > arrayNotes.length) {16 //Si sha superat la mida de larray, s que no sha trobat cap susps.17 System.out.println("Ning no ha susps.");18 } else {19 //Si sha sortit abans dacabar larray, s que hi havia un susps.20 System.out.println("Alg ha susps.");21 }22 }23 }

  • Programaci bsica (ASX)Programaci (DAM) 44 Tipus de dades compostes

    Repte 4:

    1 public class MitjanaSuspesosOrdenats {2 public static void main (String[] args) {3 float[] llistaNotes = {5.5f, 9f, 2f, 10f, 4.9f};4 //Bucle extern.5 //Sanir posant a cada posici tractada, comenant per la 0,6 //el valor ms baix que es trobi.7 for (int i = 0; i < llistaNotes.length 1; i++) {8 //Bucle intern.9 //Se cerca entre la resta de posicions quin s el valor ms baix.

    10 for(int j = i + 1; j < llistaNotes.length; j++) {11 //La posici tractada t un valor ms gran que el de la cerca; els

    intercanviem.12 if (llistaNotes[i] > llistaNotes[j]) {13 //Per intercanviar valors cal una variable auxiliar.14 float canvi = llistaNotes[i];15 llistaNotes[i] = llistaNotes[j];16 llistaNotes[j] = canvi;17 }18 }19 }20 //El mostrem per pantalla.21 System.out.print("Larray ordenat s: [");22 for (int i = 0; i < llistaNotes.length;i++) {23 System.out.print(llistaNotes[i] + " ");24 }25 System.out.println("]");26 //Inici de les modificacions.27 //Valor acumulat per fer la mitjana.28 float acumulat = 0;29 //Nombre de suspesos.30 int numSuspes = 0;31 //Inici de la nova part.32 //Com larray est ordenat, noms cal fer un recorregut fins trobar un

    aprovat,33 //no cal arribar al final. Un cop es troba el primer aprovat, la resta de34 //posicions segur que tamb sn aprovats, ja que larray est ordenat.35 for (int i = 0; i < llistaNotes.length; i++) {36 //s la nota dun aprovat?37 if (llistaNotes[i] >= 5) {38 //Sha trobat el primer aprovat, sortim del bucle!39 break;40 } else {41 //s un susps, anem calculant.42 acumulat = acumulat + llistaNotes[i];43 //Sincrementa el nombre de suspesos.44 numSuspes++;45 }46 }47 float resultat = acumulat/numSuspes;48 System.out.println("La nota mitjana dels suspesos s " + resultat);49 }50 }

  • Programaci bsica (ASX)Programaci (DAM) 45 Tipus de dades compostes

    Repte 5:

    1 public class CercaBidiZero {2 public static void main (String[] args) {3 //Dades de les notes.4 float[][] arrayBidiNotes = {5 { 4.5f, 6f , 5f , 8f },6 { 10f , 8f , 7.5f, 9.5f},7 { 3f , 2.5f, 0f , 6f },8 { 6f , 8.5f, 6f , 4f },9 { 9f , 7.5f, 7f , 8f }

    10 };11 //Calen dues estructures de repetici si els dos ndexs han danar12 //variant per recrrer totes les posicions. En aquest cas, un valor s13 //sempre el mateix (posici 1 de cada fila); noms varia el nmero de fila.14 //Per tant, amb una nica estructura nhi ha prou.15 //Mirarem quin estudiant ha tret el 0.16 int estudiant = 1;17 for (int numFila = 0; numFila < arrayBidiNotes.length; numFila++) {18 if (arrayBidiNotes[numFila][1] == 0) {19 //Aquest estudiant t un 0.20 estudiant = numFila;21 //Ja podem sortir del bucle.22 //Ho podem fer, ja que noms hi ha una nica estructura de repetici.23 break;24 }25 }26 if (estudiant == 1) {27 System.out.println("Cap estudiant no t un 0.");28 } else {29 System.out.println("Lestudiant " + estudiant + " t un 0 en el segon

    exercici.");30 }31 }32 }

  • Programaci bsica (ASX)Programaci (DAM) 47 Tipus de dades compostes

    2. Tractament de cadenes de text

    Fins ara, el tipus de dada carcter no ha estat gaire rellevant a lhora dexposarexemples significatius de codi font de programes. s fora habitual que en elvostre dia a dia tracteu amb conjunts de dades numriques individuals, cadascunaindependent de les altres: dates, distncies, intervals de temps, quantitats, etc. Pertant, sn dades que t sentit emmagatzemar i processar mitjanant un programaper automatitzar-ne el clcul. En canvi, segurament no s gaire habitual queconstantment useu conjunts de carcters individuals i independents: lletres a,b, c, etc. La veritable utilitat dels carcters s poder usar-los agrupats enforma de paraules o frases: un nom, una pregunta, un missatge, etc. Per tant,si un llenguatge de programaci ha de ser til, sha de tenir en compte aquestacircumstncia.

    El tipus de dada compost cadena de text o String serveix per representar igestionar de manera senzilla una seqncia de carcters.

    2.1 La classe "String"

    En llenguatge Java, la manipulaci de qualsevol dada de tipus compost, incloent-hiles cadenes de text, t un seguit de particularitats i una terminologia fora diferentde la dels tipus primitius o els arrays. Si b no s necessari conixer-ne tots elsdetalls, abans de veure com manipular cadenes de text o altres tipus de dadescompostos s important aprendre un seguit de termes especfics, ja que apareixenamb freqncia a la documentaci de Java.

    En Java, exceptuant el cas de larray, susa el terme classe per referir-se aun tipus de dada compost.

    A les variables de tipus de dades compostos tamb els podem assignar directamentvalors, com a les de tipus primitius. Ara b, amb algunes particularitats en lanomenclatura.

    Susa el terme objecte per referir-se al valor assignat a una variable duntipus de dades compost.

    En llenguatge Java, la classe que representa una cadena de text sanomenaexplcitament String. Aix, doncs, a partir dara, en lloc de parlar del tipusde dada compost String, direm sempre la classe String, i en lloc de dir que

    String

    En Java, el tipus de dadacompost cadena de textsidentifica amb la paraula clauString.

    Ls dels termes classe iobjecte est estretamentlligat a la caracterstica dellenguatge Java de serorientat a objectes.

    Per convenci de codi, elsnoms de les classes al Javasescriuen sempre usantUpperCamelCase.

  • Programaci bsica (ASX)Programaci (DAM) 48 Tipus de dades compostes

    una variable s del tipus de dada compost String es dir que s de la classe oque pertany a la classe String. Per norma general, tamb es parlar de lobjecteassignat a la variable holaMon en lloc del valor assignat a la variable holaMon,o dun ob