Gyakorlati alapok
Programozzunk egy kis harcművészetet!
A Pénzes-féle Java-programozás még ezt is össze tudja hozni: a programozást és a harcművészeteket. A harcászaton belül sok, számításra való dolog várakozik minél gyorsabb processzorra, gondoljunk csak egy atomtöltetet hordozó rakéta optimális röppályaívének kiszámítására.
Ebben a fejezetben egy konkrét harci eszköz, a nunchaku egy speciális problémáját oldjuk meg egy apró, konzolos Java-alkalmazás segítségével.
Amint köztudott, nekem van egy nunchakuiskolám is, címe: www.nunchaku-nunchakuiskola.hu.
A nunchaku 2, általában fából készült, nagyjából 30 centiméter hosszú szár, középen kötéllel vagy lánccal összekötve:
A probléma az átkötési lánchosszúság pontos kiszámítása. Ez a mérés nyilvánvalóan könnyen megoldható, ha szerzünk hozzá egy pontos mérőeszközt, mondjuk egy tolómérőt:
Kis logikával azonban már 1 db láncszemből is meg tudjuk állapítani az átkötési lánchosszat, sőt részletes listát is tudunk készíteni belőle.
A számításokhoz 3 bemeneti adatra van szükségünk, közülük 2 adat tizedmilliméteres pontosságot igényel, ezért célszerű, ha tolómérőt használunk:
-
a láncszem külső hossza tizedmilliméterre pontosan - double lancSzemHossz;
-
a láncszem vastagsága tizedmilliméterre pontosan - double lancSzemVastagsag;
-
a láncszemek darabszáma, tehát hogy hány láncszemes lesz az átkötés - int lancSzemSzam.
Látható, hogy a tizedmilliméteres pontosság double típusú numerikus adatformátumot igényel (Numerikus lebegőpontos című fejezet).
Ha például van 3 db 40 milliméteres láncszemünk, akkor azt mondhatnánk, hogy 120 milliméteres lesz az átkötés. Jó elméleti megközelítés, de pontatlan, mert a láncszemek mindig belülről kapcsolódnak egymáshoz:
A fenti megközelítés kizárólag mágneses láncok esetében lenne működőképes, ahol a kapcsolódás mindig külső lesz.
Ám szeretném hangsúlyozni, hogy ilyen átkötési mód a jelen pillanatban nincs, mágneses láncokat manapság kizárólag gyógyászati és esztétikai célra gyártanak.
A fenti képről könnyen leolvasható, hogy 1 átkötéskor mennyit veszít a láncsor a hosszúságából: pontosan 2 * láncvastagságnyit. És hányszor veszíti ezt el? Ahány átkötés van a láncsorban: n láncszem esetén n - 1 lesz az átkötés mennyisége. Tapasztalt programozók szeme előtt ilyenkor már kezd lebegni egy olyan for ciklusos megoldás, amely a láncszemek darabszámának mértékéig adja össze a lánchosszat és vonja ki a kétszeres vastagságot.
Az ügy azonban kissé ennél bonyolultabb implementációt igényel, mert 1 láncszemes átkötés esetén nincs vastagság miatti méretcsökkenés. A 0-val való műveletek durva hibáját pedig úgy kerüljük ki, hogy bemeneti adatként nem engedünk 0-t vagy nála kisebb számot.
Figyelem! A program nem numerikus bemeneti adatok szűrésére nincs felkészítve! Ha ilyen adatot adunk meg, kivételt fog dobni (laikus megfogalmazásban megszakad a futása).
A program láncszemhossz és vastagság esetében tizedes törtes számokat is képes fogadni, ám ezeket ponttal (például 2.5) adjuk meg a vessző (például 2,5) helyett!
Kiindulópontként meghatározzuk (azaz egyszerűen tolómérővel tizedmilliméterre pontosan lemérjük) a Beke-féle nunchaku-láncszemek szabványos adatait:
-
a láncszem külső hossza - 22 mm;
-
a láncszem vastagsága - 2,5 mm;
Nézzük meg a futtatható Java-kódot!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
double lancSzemHossz = 0;
double lancSzemVastagsag = 0;
int lancSzemSzam = 0;
double lancHossz = 0;
Scanner scanner = new Scanner (System.in);
System.out. println("Kérem adja meg a láncszem hosszát!
(mm)");
String bekeres = scanner.nextLine();
lancSzemHossz = Double.parseDouble(bekeres);
while (lancSzemHossz <= 0){
System.out.println("Kérem, hogy
pozitív számot adjon meg!");
bekeres = scanner.nextLine();
lancSzemHossz =
Integer.parseInt(bekeres);
}
System.out. println("Kérem adja meg a láncszem vastagságát!
(mm)");
bekeres = scanner.nextLine();
lancSzemVastagsag = Double.parseDouble(bekeres);
while (lancSzemVastagsag <= 0){
System.out.println("Kérem, hogy
pozitív számot adjon meg!");
bekeres = scanner.nextLine();
lancSzemVastagsag =
Integer.parseInt(bekeres);
}
System.out. println("Kérem adja meg a láncszemek számát!
(db)");
bekeres = scanner.nextLine();
lancSzemSzam = Integer.parseInt(bekeres);
while (lancSzemSzam <= 0){
System.out.println("Kérem, hogy
pozitív számot adjon meg!");
bekeres = scanner.nextLine();
lancSzemSzam =
Integer.parseInt(bekeres);
}
for (int i = 1; i <= lancSzemSzam; i++){
if(lancSzemSzam == 1){
lancHossz =
lancSzemHossz;
System.out.println(i + " láncszem esetén a teljes lánchossz: " + lancHossz + "
mm");
break;
}
if(i == 1){
lancHossz =
lancSzemHossz;
System.out.println(i + " láncszem esetén a teljes lánchossz: " + lancHossz + "
mm");
continue;
}
lancHossz += lancSzemHossz - (2 * lancSzemVastagsag);
System.out.println(i + " láncszem esetén a teljes lánchossz:
" + lancHossz + " mm");
}
}
}
Végeredmény:
Kérem adja meg a láncszem hosszát! (mm)
22
Kérem adja meg a láncszem vastagságát! (mm)
2.5
Kérem adja meg a láncszemek számát! (db)
6
1 láncszem esetén a teljes lánchossz: 22.0 mm
2 láncszem esetén a teljes lánchossz: 39.0 mm
3 láncszem esetén a teljes lánchossz: 56.0 mm
4 láncszem esetén a teljes lánchossz: 73.0 mm
5 láncszem esetén a teljes lánchossz: 90.0 mm
6 láncszem esetén a teljes lánchossz: 107.0 mm
Ha tizedmilliméterre pontosan mértük le a bemeneti adatokat, akkor a
végeredmények milliméterre egyezni fognak; a fenti eredményeket a Beke-féle
nunchakuk szabványos láncszemein tolómérővel leellenőriztem.
Fontos hangsúlyozni, hogy a kapott teljes lánchossz a láncsor egyik végétől a másik végéig tart és nem foglal magába további, a rögzítésnél keletkező hosszúság-módosulásokat.
Az alábbi képen ezt jól szemügyre vehetjük. A láncrögzítés helye itt a 2 db csavar. A lánchosszból tehát még ki kell vonnunk a 2 csavar és a nunchaku forgó teteje közti néhány milliméteres távolság kétszeresét.