Szakkörök‎ > ‎Algoritmus szakkör‎ > ‎2011-2012‎ > ‎

1. óra

2011.09.19.


Szeptember során olyan egyszerű problémákkal foglalkozunk, ahol az összes eset felsorolása elegendő a megoldás megtalálásához.

Feladat

    Mastermind

Hogyan kell a bemenetet beolvasni?

Az órán kiderült, hogy a legnagyobb nehézséget a fenti címben megfogalmazott kérdés jelentette, ezért megpróbáljuk programozási nyelvek szerint csoportosítva összefoglalni a tudnivalókat.

Példa egy lehetséges bemenetre

A példa kedvéért egy olyan bemenettel fogunk dolgozni, amely térbeli pontok koordinátáit tárolja. Az első sor a pontok számát adja meg (feltesszük, hogy legfeljebb 1000 pont lehet), majd soronként három egész koordináta következik, szóközökkel elválasztva. A koordináták nem negatívak, és egyik sem nagyobb, mint 10000. A példaprogramok teljessége érdekében két dolgot fogunk az adatokkal csinálni:
  • tömbbe olvassuk őket, mert egy bonyolultabb algoritmusnál szükség lehet arra, hogy a bemenet teljes egészében a memóriában legyen;
  • kiírjuk őket a képernyőre, hogy ellenőrizni tudjuk a beolvasás helyességét.
A bemeneti állomány neve: bemenet.txt.

Pascal

program Bemenet;
var
    N,i : integer;
    T : array[1..1000,1..3] of integer;
    F : text;
begin
    assign(F,'bemenet.txt');
    reset(F);
    readln(F,N);
    for i := 1 to N do begin
        readln(F,T[i,1],T[i,2],T[i,3]);
        writeln(T[i,1],' ',T[i,2],' ',T[i,3]);
    end;
    close(F);
end.


Megjegyzések:
  • A Pascal nyelv readln utasítása kezelni tudja a bemeneti sorban az adatokat elválasztó szóközöket.
  • A fenti program nem érzékeny arra, ha a sorok végén további adatok is vannak a harmadik szám után.
  • Pascalban fordítási időben kell megadni a tömbök méretét, ezért a feladat specifikációjából ki kell derülnie, hogy mekkora lehet a legnagyobb lehetséges bemenet, és erre kell méretezni a tömböt.
  • Az inputot soronként olvassuk, ezért van jelentősége a sorvége karakterek helyes kezelésének.
  • A szöveg -> szám átalakítást a readln utasítás végzi.

Java

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;

public class bemenet {
    
    public static void main (String args[]) throws FileNotFoundException, IOException 
    {
        BufferedReader BE = new BufferedReader(new FileReader("bemenet.txt"));
        String sor = BE.readLine();
        int N = Integer.parseInt(sor);
        int[][] T = new int[N][3];
        for(int i = 0; i < N; i++){
            sor = BE.readLine();
            String[] nums = sor.split(" ");
            for(int j = 0; j < 3; j++){
                T[i][j] = Integer.parseInt(nums[j]);                
            }
            System.out.println(T[i][0]+" "+T[i][1]+" "+T[i][2]+" ");
        }
        BE.close();
    }
}

Megjegyzések:
  • Java-ban a tömböket 0-tól indexeljük
  • a sor.split(" ") dinamikusan hozza létre a szóköz mentén feldarabolt karakterlácból a karakterláncok tömbjét, azért nem kell előre tudnia, hogy hány részre esik szét egy sor
  • Az inputot soronként olvassuk, ezért van jelentősége a sorvége karakterek helyes kezelésének.
  • A szöveg -> szám átalakítást az Integer.parseInt() függvény végzi.
A Scanner objektum használata picit tömörebb kódot eredményez:

import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class bemenet {
    
    public static void main (String args[]) throws FileNotFoundException
    {
        Scanner BE = new Scanner(new FileReader("bemenet.txt"));        
        int N = BE.nextInt();
        int[][] T = new int[N][3];
        for(int i = 0; i < N; i++){            
            for(int j = 0; j < 3; j++){
                T[i][j] = BE.nextInt();                
            }
            System.out.println(T[i][0]+" "+T[i][1]+" "+T[i][2]+" ");
        }
        BE.close();
    }
}

C

#include "stdio.h"    

int main()
{
    int N,i;
    FILE* BE = fopen("bemenet.txt", "r");
    fscanf(BE, "%d", &N);

    int T[1000][3];
    for(i=0; i<N; i++)
    {               
        fscanf(BE, "%d %d %d", &T[i][0], &T[i][1], &T[i][2]);       
        printf("%d %d %d\n", T[i][0], T[i][1], T[i][2]);      
    }

    fclose(BE);
    return 0;
}

Megjegyzések:

  • A fscanf függvény a sorvégéket is "fehér szóközként" (whitespace) kezeli, ezért a sortörések nem számítanak, de ha valamelyik sorban nem passzol a számok darabszáma, akkor onnantól az egész beolvasás elcsúszik.
  • A szöveg -> szám átalakítást az fscanf függvény végzi.

C++

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int N,i;
   
    ifstream BE("bemenet.txt");
    BE >> N;
    int T[N][3];
   
    for (i = 0; i< N; i++){
        BE >> T[i][0];
        BE >> T[i][1];
        BE >> T[i][2];
        cout <<T[i][0]<<" "<<T[i][1]<<" "<<T[i][2]<<"\n";
    }
    BE.close();
    return 0;
}

Megjegyzések:
  • A  << operátor a sorvégéket is "fehér szóközként" (whitespace) kezeli, ezért a sortörések nem számítanak, de ha valamelyik sorban nem passzol a számok darabszáma, akkor onnantól az egész beolvasás elcsúszik.
  • A szöveg -> szám átalakítást a << operátor végzi. (Implicit típuskonverzió.)