Gyakorlati alapok II.

A 4 alapművelet

 

Az egyik előző, a Számkétszerezés című fejezet már bevezette azt az implementációs megoldást, amellyel közelíthetünk egy közepes bonyolultságú, konzolos "számolgatógép" elkészítéséhez. Ebben a fejezetben nézzük meg a 4 alapművelet egyre bonyolultabb implementációját, természetesen már külön függvényekben.

 

Az 1. körös megoldásban a 4 alapművelet kapcsolgatását nem Smith, hanem Switch bácsi, a többszörös elágazások szakértője végzi el nekünk. Sőt, rossz bemeneti műveleti jel esetén (char muveletiJel) még hibaüzenetet is biztosít:

 

default: System.out.prdoubleln("Rossz műveleti jel!"); break;

 

A külső alapmuveletek függvény egyetlen kimeneti értéke természetesen double típusú eredmeny lesz, de ne felejtsük el, hogy ezt nemcsak átadnunk, hanem át is kell vennünk. E célból egy ugyanilyen funkciójú és lehetőleg típusú változót kell deklarálnunk a main()-ben, illetve ajánlott, hogy vele a függvény bemeneti értékei is azonos típusúak legyenek (double elsoSzam, double masodikSzam). Ezután már képesek vagyunk átvenni a függvény kimeneti értékét:

 

double eredmeny = alapmuveletek(2, 10, '-');

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    static double alapmuveletek(double elsoSzam, double masodikSzam, char muveletiJel){
    double eredmeny = 0;
    switch(muveletiJel){
        case('+'): eredmeny = elsoSzam + masodikSzam; break;
        case('-'): eredmeny = elsoSzam - masodikSzam; break;
        case('*'): eredmeny = elsoSzam * masodikSzam; break;
        case('/'): eredmeny = elsoSzam / masodikSzam; break;
        default: System.out.println("Rossz műveleti jel!"); break;
        }


    return eredmeny;
    }


    public static void main(String[] args) {
        double eredmeny = alapmuveletek(2, 10, '-');
        System.out.println(eredmeny);
    }
}

 

Végeredmény:

-8.0

 

Természetesen a Javán belül jócskán vannak olyan függvények, amelyek automatikusan képesek átvenni más függvények kimeneti értékeit (ezt nevezzük függvény-túlterhelésnek - method overloading, overloaded methods); talán a legtipikusabb ilyen függvény a System.out.println(), amelynek bemeneti paramétermezőjébe pakolva függvényünket meg tudja jeleníteni annak kimeneti értékét:

 

System.out.println(alapmuveletek(2, 10, '-'));

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    static double alapmuveletek(double elsoSzam, double masodikSzam, char muveletiJel){
    double eredmeny = 0;
    switch(muveletiJel){
        case('+'): eredmeny = elsoSzam + masodikSzam; break;
        case('-'): eredmeny = elsoSzam - masodikSzam; break;
        case('*'): eredmeny = elsoSzam * masodikSzam; break;
        case('/'): eredmeny = elsoSzam / masodikSzam; break;
        default: System.out.println("Rossz műveleti jel!"); break;
        }
    return eredmeny;
    }


    public static void main(String[] args) {
        System.out.println(alapmuveletek(2, 10, '-'));
    }
}

 

Végeredmény:

-8.0

 

Az objektumorientált szemlélet következő lépéseként tovább bonthatjuk szét a funkcionalitást. Ekkor (majdnem) minden művelet külön metódust kap:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    static double osszeadas(double elsoSzam, double masodikSzam){
        return elsoSzam + masodikSzam;
        }

    static double kivonas(double elsoSzam, double masodikSzam){
        return elsoSzam - masodikSzam;
        }

    static double szorzas(double elsoSzam, double masodikSzam){
        return elsoSzam * masodikSzam;
        }

    static double osztas(double elsoSzam, double masodikSzam){
        return elsoSzam / masodikSzam;
        }

    public static void main(String[] args) {
        double elsoSzam = 2;
        double masodikSzam = 10;
        double eredmeny = 0;
        char muveletiJel = '+';
        switch(muveletiJel){
            case('+'): eredmeny = osszeadas(elsoSzam, masodikSzam); break;
            case('-'): eredmeny = kivonas(elsoSzam, masodikSzam); break;
            case('*'): eredmeny = szorzas(elsoSzam, masodikSzam); break;
            case('/'): eredmeny = osztas(elsoSzam, masodikSzam); break;
            default: System.out.println("Rossz műveleti jel!"); break;
            }
    System.out.println(eredmeny);
    }
}

 

Végeredmény:

12.0

 

Még mindig nagyon fapados a kódunk, de alapszemléletét tekintve már egészen objektumorientált-közeli (aminek persze vannak további, itt még nem alkalmazott kritériumai is). Az elvet továbbpörgetve a switch részt is bele tudjuk illeszteni egy külön metódusba, mondjuk kiertekeles néven:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    static double osszeadas(double elsoSzam, double masodikSzam){
        return elsoSzam + masodikSzam;
        }

    static double kivonas(double elsoSzam, double masodikSzam){
        return elsoSzam - masodikSzam;
        }

    static double szorzas(double elsoSzam, double masodikSzam){
        return elsoSzam * masodikSzam;
        }

    static double osztas(double elsoSzam, double masodikSzam){
        return elsoSzam / masodikSzam;
        }

    static double kiertekeles(double elsoSzam, double masodikSzam, char muveletiJel){
        double eredmeny = 0;
        switch(muveletiJel){
            case('+'): eredmeny = osszeadas(elsoSzam, masodikSzam); break;
            case('-'): eredmeny = kivonas(elsoSzam, masodikSzam); break;
            case('*'): eredmeny = szorzas(elsoSzam, masodikSzam); break;
            case('/'): eredmeny = osztas(elsoSzam, masodikSzam); break;
            default: System.out.println("Rossz műveleti jel!"); break;
            }
        return eredmeny;
        }

    public static void main(String[] args) {
        double elsoSzam = 2;
        double masodikSzam = 10;
        char muveletiJel = '-';
        System.out.println(kiertekeles(elsoSzam, masodikSzam, muveletiJel));
        }
    }

 

Végeredmény:

-8.0

 

A program eddigi leggyengébb pontja az adatbevitel. Adatbekéréssel már több helyen foglalkoztunk: már csak olyan függvényeket kell implementálnunk, amelyek a bemeneti adatok bevitelét könnyítik meg, esetleg automatizálják, természetesen külön metódusként:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

import java.util.Scanner;

public class Main {
static double osszeadas(double elsoSzam, double masodikSzam){
    return elsoSzam + masodikSzam;
}

static double kivonas(double elsoSzam, double masodikSzam){
    return elsoSzam - masodikSzam;
}

static double szorzas(double elsoSzam, double masodikSzam){
    return elsoSzam * masodikSzam;
}

static double osztas(double elsoSzam, double masodikSzam){
    return elsoSzam / masodikSzam;
}

static String[] adatBekeres(){
    Scanner in = new Scanner (System.in);
    String[] bemenetiAdatTomb = new String[3];
    System.out.println ("Kérem adja meg az 1. számot!");
    bemenetiAdatTomb[0] = in.nextLine();
    double szam = Double.parseDouble(bemenetiAdatTomb[0]);
    while (szam <= 0){
        System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
        bemenetiAdatTomb[0] = in.nextLine();
        szam = Double.parseDouble(bemenetiAdatTomb[0]);
    }

    System.out.println ("Kérem adja meg a műveleti jelet!");
    bemenetiAdatTomb[1] = in.nextLine();
    while (!bemenetiAdatTomb[1].equals("+") && !bemenetiAdatTomb[1].equals("-")

             && !bemenetiAdatTomb[1].equals("*") && !bemenetiAdatTomb[1].equals("/")){
    System.out.println("Kérem, hogy csak + - * / jeleket adjon meg!");
    bemenetiAdatTomb[1] = in.nextLine();
    }

    System.out.println ("Kérem adja meg a 2. számot!");
    bemenetiAdatTomb[2] = in.nextLine();
    szam = Double.parseDouble(bemenetiAdatTomb[2]);
    while (szam <= 0){
        System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
        bemenetiAdatTomb[2] = in.nextLine();
        szam = Double.parseDouble(bemenetiAdatTomb[2]);
    }

    return bemenetiAdatTomb;
}

static double kiertekeles(double elsoSzam, double masodikSzam, String muveletiJel){
    double eredmeny = 0;
    switch(muveletiJel){
        case("+"): eredmeny = osszeadas(elsoSzam, masodikSzam); break;
        case("-"): eredmeny = kivonas(elsoSzam, masodikSzam); break;
        case("*"): eredmeny = szorzas(elsoSzam, masodikSzam); break;
        case("/"): eredmeny = osztas(elsoSzam, masodikSzam); break;

    }
    return eredmeny;
}

public static void main(String[] args) {
    String[] bemenetiAdatTomb = new String[3];
    bemenetiAdatTomb = adatBekeres();
    double elsoSzam = Double.parseDouble(bemenetiAdatTomb[0]);
    double masodikSzam = Double.parseDouble(bemenetiAdatTomb[2]);
    String muveletiJel = bemenetiAdatTomb[1];
    System.out.println(kiertekeles(elsoSzam, masodikSzam, muveletiJel));
    }
}

 

Végeredmény:

Kérem adja meg az 1. számot!
0
Kérem, hogy csak pozitív egész számot adjon meg!
120
Kérem adja meg a műveleti jelet!
g
Kérem, hogy csak + - * / jeleket adjon meg!
/
Kérem adja meg a 2. számot!
45
2.6666666666666665

 

Az adatbekérés ugyan első körben meg lett oldva...

 

static String[] adatBekeres(){
    Scanner in = new Scanner (System.in);
    String[] bemenetiAdatTomb = new String[3];
    System.out.println ("Kérem adja meg az 1. számot!");
    bemenetiAdatTomb[0] = in.nextLine();
    double szam = Double.parseDouble(bemenetiAdatTomb[0]);
    while (szam <= 0){
        System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
        bemenetiAdatTomb[0] = in.nextLine();
        szam = Double.parseDouble(bemenetiAdatTomb[0]);
    }

    System.out.println ("Kérem adja meg a műveleti jelet!");
    bemenetiAdatTomb[1] = in.nextLine();
    while (!bemenetiAdatTomb[1].equals("+") && !bemenetiAdatTomb[1].equals("-")

             && !bemenetiAdatTomb[1].equals("*") && !bemenetiAdatTomb[1].equals("/")){
    System.out.println("Kérem, hogy csak + - * / jeleket adjon meg!");
    bemenetiAdatTomb[1] = in.nextLine();
    }

    System.out.println ("Kérem adja meg a 2. számot!");
    bemenetiAdatTomb[2] = in.nextLine();
    szam = Double.parseDouble(bemenetiAdatTomb[2]);
    while (szam <= 0){
        System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
        bemenetiAdatTomb[2] = in.nextLine();
        szam = Double.parseDouble(bemenetiAdatTomb[2]);
    }

    return bemenetiAdatTomb;
}
 

...sőt működőképes, de több probléma is van vele:

A megoldás: mindent külön metódusba kell tennünk és tovább kell fejlesztünk a számellenőrzést.

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

import java.util.Scanner;

public class Main {
static double osszeadas(double elsoSzam, double masodikSzam){
    return elsoSzam + masodikSzam;
}

static double kivonas(double elsoSzam, double masodikSzam){
    return elsoSzam - masodikSzam;
}

static double szorzas(double elsoSzam, double masodikSzam){
    return elsoSzam * masodikSzam;
}

static double osztas(double elsoSzam, double masodikSzam){
    return elsoSzam / masodikSzam;
}

static String[] adatBekeres(){
    Scanner in = new Scanner (System.in);
    String[] bemenetiAdatTomb = new String[3];
    boolean rosszAdat = false;
    System.out.println ("Kérem adja meg az 1. számot!");
    do{
        bemenetiAdatTomb[0] = in.nextLine();
        rosszAdat = ellenorzesSzam(bemenetiAdatTomb[0]);
    }while (rosszAdat == true);

    rosszAdat = false;

    System.out.println ("Kérem adja meg a műveleti jelet!");
    bemenetiAdatTomb[1] = in.nextLine();
    while (!bemenetiAdatTomb[1].equals("+") && !bemenetiAdatTomb[1].equals("-")

            && !bemenetiAdatTomb[1].equals("*") && !bemenetiAdatTomb[1].equals("/")){
            System.out.println("Kérem, hogy csak + - * / jeleket adjon meg!");
            bemenetiAdatTomb[1] = in.nextLine();
    }

    System.out.println ("Kérem adja meg a 2. számot!");
    do{
        bemenetiAdatTomb[2] = in.nextLine();
        rosszAdat = ellenorzesSzam(bemenetiAdatTomb[2]);
    }while (rosszAdat == true);
    return bemenetiAdatTomb;
    }

static boolean ellenorzesSzam(String bemenetiAdat){
    boolean rosszAdat = false;
    char karakter = bemenetiAdat.charAt(0);
    if(karakter == '0'){
        rosszAdat = true;
    }
    for(int i = 0; i < bemenetiAdat.length(); i++){
        karakter = bemenetiAdat.charAt(i);
            if(karakter != '0'
                && karakter != '1'
                && karakter != '2'
                && karakter != '3'
                && karakter != '4'
                && karakter != '5'
                && karakter != '6'
                && karakter != '7'
                && karakter != '8'
                && karakter != '9'){
                rosszAdat = true;
                break;
                }
            }
        if(rosszAdat == true){
            System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
        }
    return rosszAdat;
}

static double kiertekeles(double elsoSzam, double masodikSzam, String muveletiJel){
    double eredmeny = 0;
    switch(muveletiJel){
        case("+"): eredmeny = osszeadas(elsoSzam, masodikSzam); break;
        case("-"): eredmeny = kivonas(elsoSzam, masodikSzam); break;
        case("*"): eredmeny = szorzas(elsoSzam, masodikSzam); break;
        case("/"): eredmeny = osztas(elsoSzam, masodikSzam); break;
    }
    return eredmeny;
}

public static void main(String[] args) {
    String[] bemenetiAdatTomb = new String[3];
    bemenetiAdatTomb = adatBekeres();
    double elsoSzam = Double.parseDouble(bemenetiAdatTomb[0]);
    double masodikSzam = Double.parseDouble(bemenetiAdatTomb[2]);
    String muveletiJel = bemenetiAdatTomb[1];
    System.out.println(kiertekeles(elsoSzam, masodikSzam, muveletiJel));
    }
}
 

Végeredmény:

Kérem adja meg az 1. számot!
w
Kérem, hogy csak pozitív egész számot adjon meg!
q
Kérem, hogy csak pozitív egész számot adjon meg!
0
Kérem, hogy csak pozitív egész számot adjon meg!
120
Kérem adja meg a műveleti jelet!
s
Kérem, hogy csak + - * / jeleket adjon meg!
-
Kérem adja meg a 2. számot!
0
Kérem, hogy csak pozitív egész számot adjon meg!
a
Kérem, hogy csak pozitív egész számot adjon meg!
33
87.0

 

A különálló számellenőrző függvénynek...

 

static boolean ellenorzesSzam(String bemenetiAdat){
    boolean rosszAdat = false;
    char karakter = bemenetiAdat.charAt(0);
    if(karakter == '0'){
        rosszAdat = true;
    }
    for(int i = 0; i < bemenetiAdat.length(); i++){
        karakter = bemenetiAdat.charAt(i);
            if(karakter != '0'
                && karakter != '1'
                && karakter != '2'
                && karakter != '3'
                && karakter != '4'
                && karakter != '5'
                && karakter != '6'
                && karakter != '7'
                && karakter != '8'
                && karakter != '9'){
                rosszAdat = true;
                break;
                }
            }
        if(rosszAdat == true){
            System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
        }
    return rosszAdat;
}

 

...a következő feltételeket kell teljesítenie:

A sikeres implementáció után ugyanezt megtehetjük a műveleti jel ellenőrzésével is, persze műveleti jel-specifikusan:

 

static boolean ellenorzesMuveletiJel(String bemenetiAdat){
    boolean rosszAdat = false;
    char karakter = bemenetiAdat.charAt(0);
        if((karakter != '+' && karakter != '-' && karakter != '*' && karakter != '/')){
        rosszAdat = true;
        }
    if(rosszAdat == true){
        System.out.println("Kérem, hogy csak + - * / jeleket adjon meg!");
    }
    return rosszAdat;
}

 

Zárásképpen nézzük meg a teljes kódot. Egyúttal az eredménykiírást egy kissé megszépítjük, hogy jobban olvashatóvá váljon:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

import java.util.Scanner;

public class Main {
static double osszeadas(double elsoSzam, double masodikSzam){
    return elsoSzam + masodikSzam;
}

static double kivonas(double elsoSzam, double masodikSzam){
    return elsoSzam - masodikSzam;
}

static double szorzas(double elsoSzam, double masodikSzam){
    return elsoSzam * masodikSzam;
}

static double osztas(double elsoSzam, double masodikSzam){
    return elsoSzam / masodikSzam;
}

static String[] adatBekeres(){
    Scanner in = new Scanner (System.in);
    String[] bemenetiAdatTomb = new String[3];
    boolean rosszAdat = false;
    System.out.println ("Kérem adja meg az 1. számot!");
    do{
        bemenetiAdatTomb[0] = in.nextLine();
        rosszAdat = ellenorzesSzam(bemenetiAdatTomb[0]);
    }while (rosszAdat == true);
    rosszAdat = false;

    System.out.println ("Kérem adja meg a műveleti jelet!");
    do{
        bemenetiAdatTomb[1] = in.nextLine();
        rosszAdat = ellenorzesMuveletiJel(bemenetiAdatTomb[1]);
        }while (rosszAdat == true);
    rosszAdat = false;

    System.out.println ("Kérem adja meg a 2. számot!");
    do{
        bemenetiAdatTomb[2] = in.nextLine();
        rosszAdat = ellenorzesSzam(bemenetiAdatTomb[2]);
    }while (rosszAdat == true);

    return bemenetiAdatTomb;
}

static boolean ellenorzesSzam(String bemenetiAdat){
    boolean rosszAdat = false;
    char karakter = bemenetiAdat.charAt(0);
    if(karakter == '0'){
        rosszAdat = true;
    }
    for(int i = 0; i < bemenetiAdat.length(); i++){
        karakter = bemenetiAdat.charAt(i);
        if(karakter != '0'
            && karakter != '1'
            && karakter != '2'
            && karakter != '3'
            && karakter != '4'
            && karakter != '5'
            && karakter != '6'
            && karakter != '7'
            && karakter != '8'
            && karakter != '9'){
            rosszAdat = true;
            break;
            }
        }
    if(rosszAdat == true){
        System.out.println("Kérem, hogy csak pozitív egész számot adjon meg!");
    }
    return rosszAdat;
}

static boolean ellenorzesMuveletiJel(String bemenetiAdat){
    boolean rosszAdat = false;
    char karakter = bemenetiAdat.charAt(0);
    if((karakter != '+' && karakter != '-' && karakter != '*' && karakter != '/')){
        rosszAdat = true;
    }
    if(rosszAdat == true){
        System.out.println("Kérem, hogy csak + - * / jeleket adjon meg!");
    }
    return rosszAdat;
}

static double kiertekeles(double elsoSzam, double masodikSzam, String muveletiJel){
    double eredmeny = 0;
    switch(muveletiJel){
        case("+"): eredmeny = osszeadas(elsoSzam, masodikSzam); break;
        case("-"): eredmeny = kivonas(elsoSzam, masodikSzam); break;
        case("*"): eredmeny = szorzas(elsoSzam, masodikSzam); break;
        case("/"): eredmeny = osztas(elsoSzam, masodikSzam); break;
    }
    return eredmeny;
}

public static void main(String[] args) {
    String[] bemenetiAdatTomb = new String[3];
    bemenetiAdatTomb = adatBekeres();
    double elsoSzam = Double.parseDouble(bemenetiAdatTomb[0]);
    double masodikSzam = Double.parseDouble(bemenetiAdatTomb[2]);
    String muveletiJel = bemenetiAdatTomb[1];
    System.out.println(elsoSzam + " " + muveletiJel + " " + masodikSzam + " = " +

                                kiertekeles(elsoSzam,     masodikSzam, muveletiJel));
    }
}

 

Végeredmény:

Kérem adja meg az 1. számot!
w
Kérem, hogy csak pozitív egész számot adjon meg!
qwert
Kérem, hogy csak pozitív egész számot adjon meg!
0
Kérem, hogy csak pozitív egész számot adjon meg!
120
Kérem adja meg a műveleti jelet!
sde
Kérem, hogy csak + - * / jeleket adjon meg!
b
Kérem, hogy csak + - * / jeleket adjon meg!
/
Kérem adja meg a 2. számot!
0
Kérem, hogy csak pozitív egész számot adjon meg!
hj
Kérem, hogy csak pozitív egész számot adjon meg!
23
120.0 / 23.0 = 5.217391304347826

 

Természetesen minél bonyolultabb egy programozás-technikai probléma, annál többféleképpen lehetséges megoldani. A fenti megoldás csak egy lehetőség a rengeteg további közül.