wiki:ohj2k10vk1T5
Last modified 8 years ago Last modified on 2010-04-14 00:59:27

Toteuta metodit, joiden avulla voidaan lukea tekstitiedostosta muotoa

1|1|1
2|1|2
6|6|6

oleva kokonaislukumatriisi, kertoa se kokonaisluvulla ja kirjoittaa uusi matriisi tiedostoon.

Testiohjelman

        int[ ][ ] matriisi = lueMatriisi("matriisi.txt");
        matriisi = kerroMatriisiKokonaisluvulla(matriisi, 2);
        kirjoitaMatriisi(matriisi, "matriisi2.txt");

tulisi tuottaa matriisi2.txt -niminen tiedosto, jonka sisältö olisi seuraavanlainen:

2|2|2
4|2|4
12|12|12

Mallivastaus:

	public static int[] erotaIntTaulukko(String taulukko, char erotinmerkki)
	{
		String[] luvut = taulukko.split("["+erotinmerkki+"]");
		int[] uusiRivi = new int[luvut.length];
		for (int i=0; i<luvut.length; i++)
		{
			uusiRivi[i] = Mjonot.erotaInt(luvut[i],'|');
		}
		return uusiRivi;
	}
	
	public static int[][] lueMatriisi(String tiedostonNimi)
	{
		// Luodaan väliaikaisvarasto matriisin riveille 
		ArrayList<int[]> intRivit = new ArrayList<int[]>();
		
		BufferedReader br=null;
		try{
			
			br = new BufferedReader(new FileReader(tiedostonNimi));
			
			String rivi;
			while ( (rivi = br.readLine() ) != null){
				intRivit.add( (erotaIntTaulukko(rivi, '|') ) );
			}
		}catch (IOException ioe)
		{
			return null;
		}
		finally {
			try{
				br.close();
			}catch (IOException ioe){
				return null;
			}
			
		}
		// kopioidaan tiedot väliaikaisvarastosta matriisiin
		int[][] matriisi = new int[intRivit.size()][];
		
		for (int i=0; i<intRivit.size(); i++)
			matriisi[i] = intRivit.get(i);
		return matriisi;
	}
	public static boolean kirjoitaMatriisi(int[][] matriisi, String tiedostonNimi)
	{
		
		// Muodostetaan merkkijonotaulukko kirjoitettavista riveistä
		String[] rivit = new String[matriisi.length];
		for (int riviIndex = 0; riviIndex<rivit.length; riviIndex++)
		{
			StringBuilder riviBuilder = new StringBuilder();
			for ( int i=0; i<matriisi[riviIndex].length; i++)
			{
				riviBuilder.append(matriisi[riviIndex][i]+"|");
			}
			rivit[riviIndex] = riviBuilder.deleteCharAt(riviBuilder.lastIndexOf("|")).toString();
		}

		// Kirjoitetaan rivit tiedostoon
		PrintWriter file=null;
		try {
			file = new PrintWriter(new FileOutputStream(tiedostonNimi));
			for (int rivi = 0; rivi < rivit.length; rivi++)
				file.println(rivit[rivi]);
		}catch (IOException ioe){
			return false;
		}finally{
			file.close();
		}
		return true;
	}

Tässä jotain tyypillisiä virheitä:

Oletetaan, että kyseessä on vakiokokoinen neliömatriisi. Samalla vaivalla voisi lukea minkä tahansa matriisin, myös ei-neliömatriisin. Paikoin oletus on tehty vain joko lukiessa tai kirjoitettaessa. Toisinaan metodi lukee useamman rivin, mutta koska sille ei löydy tilaa luodussa matriisissa, tulee poikkeus, jota ei huomioida. Plussaa siitä jos oli erikseen dokumentoinut tämän oletuksen.

Yritetään parsia koko riviä yhdeksi kokonaisluvuksi. Toisinaan yritetään myös parsea ilman try-catchia. Toisinaan yritetään sijoittaa suoraan ilman minkäänmoista parsea.

Jos luettava matriisi on iso, suoraan valmiiseen tietorakenteeseen lukeminen tuplaa muistintarpeen.

BufferedReaderista? luetaan rivejä ilman että ne otetaan talteen, joten tietoa menee hukkaan.

Jokainen matriisin alkio tulostetaan println:n kautta, eli jokainen tulee omalle rivilleen.

Rivien loppuun jää ylimääriset tolpat. Toisinaan tolppien lisääminen alkioiden väliin oli unohdettu.

Foreachin käytön kanssa vaikutti olevan ongelmia.

Matriisi kerrotaan hihavakiolla, eikä parametrinä tulleella kokonaisluvulla.

Println tulostaa myös rivinvaihdon, ja println(matriisi[i][j]+'|') tulostaa jokaisen alkion omalle rivilleen.

Pisteitä vähennettiin seuraavasti:

-Oletus, että matriisi 3x3 - 1pts (jos toiminnallisuus dokumentoitu, -0.5pts)

-Try-catchin puuttuminen - 0.5pts

-Ei lueta/kirjoiteta kaikkea tietoa - 1pts

-Koodin toteutus harvinaisen epäselvä - 0.5pts

-Toimintalogiikassa virheitä - vaiheleva määrä