Algorithmen

Um einen ersten Eindruck vom Aufbau eines Programms zu erhalten, wollen wir an einem Beispiel den Weg „Vom Problem zum Programm“ einmal verfolgen.

Problem:

Die Parkgebühr in einem Parkhaus soll vom Computer berechnet werden. Dabei nehmen wir an, dass jede angefangene halbe Stunde 0,50 DM kostet und das Parkhaus um 24 Uhr schließt.

 

Lösung 1. Schritt:

Ankunfts- und Abfahrtszeit erfragen

Parkdauer berechnen

Parkgebühr berechnen

 

Lösung 2. Schritt:        „Verfeinerung“

Ankunfts- und Abfahrtszeit erfragen:

Erfrage die vollen Stunden der Ankunftszeit (AnStd)

Erfrage die Minuten der Ankunftszeit (AnMin)

Erfrage die vollen Stunden der Abfahrtszeit (AbStd)

Erfrage die Minuten der Abfahrtszeit (AbMin)

 

Parkdauer berechnen:

Ersetze AnMin durch AnStd * 60 + AnMin (Min seit Mitternacht)

Ersetze AbMin durch AbStd * 60 + AbMin (Min seit Mitternacht)

Berechne Parkdauer: AbMin - AnMin

 


Parkgebühr berechnen:

Setze Zeit = Parkdauer (Parkdauer wird später noch gebraucht)

Setze Parkgebühr = 0

Wiederhole solange Zeit > 0 :

 

Vermindere Zeit um 30

 

Erhöhe Parkgebühr um 0.50

 

Berechnete Daten ausgeben:

Das zugehörige JS-Programm hat folgende Form:

var AnStd, AnMin, AbStd, AbMin, Parkdauer, Parkgebuehr;

// EINGABE

function Ankunfts_und_Abfahrtszeit_erfragen()

{

  AnStd = eval(prompt('Einfahrt:\nBitte Stunde eingeben:',0));

  AnMin = eval(prompt('Einfahrt:\nBitte Minute eingeben:',0));

  AbStd = eval(prompt('Ausfahrt:\nBitte Stunde eingeben:',0));

  AbMin = eval(prompt('Ausfahrt:\nBitte Minute eingeben:',0));

}

// VERARBEITUNG

function Parkdauer_berechnen()

{

 AnMin = 60*AnStd + AnMin;

 AbMin = 60*AbStd + AbMin;

 Parkdauer = AbMin - AnMin;

}

 

function Parkgebuehr_berechnen()

{ var Zeit;

  Zeit = Parkdauer;

  Parkgebuehr = 0;

  while(Zeit > 0)

       {

 Zeit = Zeit - 30;

        Parkgebuehr = Parkgebuehr + 0.50;

}

}

 


// AUSGABE

function berechnete_Daten_ausgeben()

{

 if(Parkdauer >= 0)

      { 

alert('Sie haben '+Parkdauer+' Minuten geparkt. \nDie Parkgebühr beträgt '+Parkgebuehr+' DM. ') ;

       }

       else alert('Betrugsversuch! ');

}

 

// ---------- Hauptprogramm ----------

document.open();

document.write('P a r k a u t o m a t');

document.write('<br>=====================') ;

document.close();

Ankunfts_und_Abfahrtszeit_erfragen();

Parkdauer_berechnen();

Parkgebuehr_berechnen();

berechnete_Daten_ausgeben();

 

Ein Algorithmus ist eine endliche Folge von eindeutigen und ausführbaren Anweisungen zur Lösung eines allgemeinen Problems.
Ein Programm ist ein in einer Computersprache formulierter Algorithmus.

 

Aufbau eines Programms

Es gibt keine prinzipiell vorgeschriebene Struktur, wie z.B. bei Turbo-Pascal. Man sollte allerdings um ein übersichtliches Programmieren zu pflegen das Programm prozedural (s.o.) aufbauen. Auch die Deklaration der Variablen und die Verwendung von Kommentaren dient dieser "Kultur".

Die einzelnen Prozeduren werden hier als Funktionen deklariert.

function <Bezeichner>()

{

  Anweisung;

  Anweisung;

  ...;

}

 

Das obige Programm muss in einer HTML-Datei zwischen

<script language=JavaScript>

...

</script>

eingebetet sein oder in einer Datei (z.B. parkhaus.js) abgelegt sein und in HTML mit

<script language=JavaScript src="<pfad>/parkhaus.js" type=text/javascript></script>

aufgerufen werden.

 

Funktionen (also auch Prozeduren) müssen vor ihrem Aufruf deklariert sein. Sinnvoller Weise deklariert man globale Variablen am Anfang des Programms.

 

Der Anweisungsteil (sowohl in den functions als auch im Hauptteil) listet die Anweisungen (Umsetzung eines Algorithmus) auf, die ausgeführt werden, wenn das Programm gestartet wird.

 

Ein- und Ausgabeanweisungen; Wertzuweisungen

alert('<Text>');

Bildschirmausgabe der Zeichenfolge <Text> ohne Zeilenvorschub.
Beispiel:
alert('Sie haben '+Parkdauer+' Minuten geparkt. \nDie Parkgebühr beträgt '+Parkgebuehr+' DM. ')
Für Parkdauer und Parkgebuehr wird der jeweilige Wert der Variable ausgegeben \n erzeugt einen Zeilenvorschub.

<script language=JavaScript>

document.open();

document.write('Sie haben '+Parkdauer+' Minuten geparkt. <br>Die Parkgeb&uuml;hr betr&auml;gt '+Parkgebuehr+' DM. ');

document.close();

</script>

Bildschirmausgabe der Zeichenfolge mit Zeilenvorschub direkt im aktuellen Dokument im Browserfenster.

 

confirm('<Text>');

Bildschirmausgabe ohne Zeilenvorschub mit Entscheidungsmöglichkeit.

 

 

<variable> = prompt('<Text>',<Wert>);

Eingabeanweisung, hierbei wird der <variable> der Wert <Wert> zugewiesen.

 

 

Andere Eingabemöglichkeit mit Hilfe eines Formulars in einer HTML-Datei. Als Beispiel betrachte parkhaus_2.htm!

 


Mathematische Werte (Eigenschaften des Objekts Math) und Standardfunktionen (Methoden des Objekts Math)

Funktion

Bedeutung

Beispiel

Math.sin(x)

Sinus des numerischen Arguments berechnen.

x im Bogenmaß

Math.sin(Math.PI/6) ergibt 0.5

Math.asin(x)

Arkussinus des numerischen Arguments berechnen.

 

Math.cos(x)

Cosinus des numerischen Arguments berechnen.

x im Bogenmaß

Math.cos(Math.PI/3) ergibt 0.5

Math.acos(x)

Arkuscosinus des numerischen Arguments berechnen.

 

Math.tan(x)

Tangens des numerischen Arguments berechnen.

 

Math.atan(x)

Arkustangens des numerischen Arguments berechnen.

 

Math.exp(x)

Exponentialwert auf der Basis der Eulersche Konstanten des numerischen Arguments berechnen.

ex

Math.exp(0) = 1.00

Math.log(x)

Natürlichen Logarithmus des numerischen Ausdrucks berechnen.

ln x

Math.log(Math.exp(2)) ergibt 2

Math.sqrt(x)

Quadratwurzel des numerischen Arguments berechnen.

Math.sqrt(4) ergibt 2

Math.abs(x)

Absolutbetrag des numerischen Arguments berechnen.

Math.abs(-3) ergibt 3

Math.floor(x)

Größte Ganzzahl kleiner oder gleich dem numerischen Argument berechnen.

Math.floor(4.13) ergibt 4

Math.ceil(x)

Kleinste Ganzzahl berechnen, die größer oder gleich dem numerischen Argument ist.

Math.ceil(4.13) ergibt 5

Math.pow(b,e)

Aus den beiden Argumenten Basis und Exponent den um den angegebenen Exponenten potenzierten Wert der Basis berechnen.

Math.pow(2,3) ergibt 8

Math.round(x)

Den numerischen Ausdruck auf die nächste Ganzzahl runden.

Math.round(4.13) ergibt 4

Math.round(4.5) ergibt 5

Math.min(x,y)

Den kleineren Wert von zwei angegebenen numerischen Ausdrücken berechnen.

 

Math.max(x,y)

Den größeren Wert von zwei angegebenen numerischen Ausdrücken berechnen.

 

Math.random()

Eine Zufallszahl zwischen 0 und 1 berechnen.

 

Daneben stehen natürlich auch die üblichen Operatoren +, -, *, /  und % (Division modulo z.B.
7 % 3 = 1) zur Verfügung.

Eigenschaften des Objekts Math.

Math.E

Eulersche Konstante.

Math.LN2

Natürlicher Logarithmus von 2.

Math.LN10

Natürlicher Logarithmus von 10.

Math.LOG2E

Logarithmus der Eulerschen Konstanten zur Basis 2.

Math.LOG10E

Logarithmus der Eulerschen Konstanten zur Basis 10.

Math.PI

Konstante PI.

Math.SQRT1_2

Quadratwurzel von 0,5.

Math.SQRT2

Quadratwurzel von 2.

 

Die Sequenz

Mit den Hilsmitteln aus vorangehenden Abschnitten lassen sich nun einfache Programme erstellen. Arbeitet man ein Programm Schritt für Schritt in der vorgegebenen Reihenfolge ab so spricht man von einer Sequenz. Die ersten programmgesteuerten Rechenautomaten (Z3 von Zuse 1941 oder ENIAC von Eckert/Mauchly 1946) konnten ausschließlich Sequenzen bearbeiten.

Programmbeispiele:

 

Programm 1:


// Quadrat
var zahl;
zahl = prompt('Bitte geben Sie eine Integerzahl ein : ',0);

alert('Das Quadrat der Zahl '+zahl+' beträgt '
+Math.pow(zahl,2));

 

Programm 2:


// Wurzel

var zahl,wurzel;
zahl = prompt('Bitte geben Sie eine Integerzahl ein : ',0);
wurzel = Math.sqrt(zahl);
alert('Die Wurzel aus '+zahl+' ist '+wurzel+'.');

 

Programm 3:

// Division
var zaehler, nenner, quotient;
zaehler = prompt('Bitte geben Sie den Zähler ein: ',0);
nenner = prompt('und nun den Nenner: ',1);
alert(zaehler+' : '+nenner+' = '+(zaehler-zaehler%nenner)/nenner+' Rest '+zaehler % nenner+'.');

 

Programm 4:

// Mehrwertsteuer;
mwst = 0.16;
var betrag, aufschlag;
betrag = prompt('Geben Sie einen Nettobetrag ein : ',0);
aufschlag = betrag*mwst;
alert('Mehrwertsteuer : '+aufschlag+' DM');

 

PROGRAMMPROBLEME

Schreiben Sie ein vollständiges JS-Programm für jedes der folgenden Pro­bleme.

a)  Drucken Sie "Hallo!" in der Mitte der 7-ten Zeile.

b) Geben Sie Ihren Vornamen in den Computer ein und lassen Sie den Computer "Willkommen <Name>" ausdrucken.

c)  Wandeln Sie eine Temperatur, die in Fahrenheit eingelesen wird, mit der Formel C = (5/9)*(F-32) in Grad Celsius um.

d) Berechnen Sie das Volumen V und die Oberfläche S einer Kugel mit den Formeln:

 

Algorithmen mit Verzweigungen

Struktogramm einer Verzweigung:

Umsetzung in die JS-Syntax:

zweiseitige Auswahl:             if(< Bedingung >) < Anweisungsfolge_1>
else < Anweisungsfolge_2>

Beachte:                                 Steht else in der selben Zeile wie if, muss davor ein Strichpunkt stehen!

einseitige Auswahl:               if(< Bedingung >) {<Anweisungsfolge>}

Bedingung:                            < Ausdruck > < Vergleichsoperator > < Ausdruck >
oder: < Boolescher Term > (= Boolesche Variable bzw. Boolescher Ausdruck)

Anweisungsfolge:                   < leere Anweisung >              oder
< Anweisung >                       oder
{  < Anweisung 1 > ; < Anweisung 2 > ; ... ; }

Vergleichsoperatoren:

<

<=

=

!=

>=

>

kleiner

kleiner oder gleich

gleich

ungleich

größer oder gleich

größer

 

 

Programm 5: Es wird überprüft, ob die eingegebene Jahreszahl ein Schaltjahr ist.

// Schaltjahr

wahl1 = 'Kein Schaltjahr';
wahl2 = 'Ein Schaltjahr';

var jahr;

     jahr = eval(prompt ('Bitte Jahreszahl eingeben : ',0));
     if (jahr > 1582)
      {
       if (jahr % 4 == 0)
        {
         if (jahr % 100 == 0)
          {
           if (jahr % 400 == 0) alert (wahl2);
            else alert (wahl1);
          }
          else alert (wahl2);
        }
        else alert (wahl1);
      }
      else alert ('Eingabe ungültig, Jahr < 1583');


Struktogramm einer mehrseitigen Verzweigung:




mögl. Wert 1




mögl. Wert 2




...

< Selektor >


mögl. Wert n




sonst

Anweisung 1

Anweisung 2

Anweisung ...

Anweisung n

Anweisung

·     Selektor = Auswahlvariable

Umsetzung in die JavaScript-Syntax:

               switch ( < Selektor > )
{

         case < mögl. Wert 1 >  :             < Anweisungsfolge 1 >;

                                      break;

         case < mögl. Wert 2 >  :             < Anweisungsfolge 2 >;

                                      break;

         . . .

         case < mögl. Wert n >   :             < Anweisungsfolge n >;

                                      break;

         default                          :             < Anweisungsfolge >;
}

-   Für die logischen Operatoren UND, Oder und Nicht verwendet JavaScript die Symbole &&, || und !.

-   switch ist beim Vergleich im case auf Gleichheit beschränkt.

PROGRAMMPROBLEME

Schreiben Sie ein vollständiges JavaScriptProgramm für jedes der folgenden Pro­bleme.

1) Jede Eingabezahl soll auf ihr Vorzeichen geprüft werden.

2) Das sog. Idealgewicht soll berechnet werden. Das Idealgewicht beträgt bei Männern 90%, bei Frauen 85% des Normalgewichts (Körpergröße minus 100). Nach Eingabe von Körpergröße und Geschlecht soll das Idealgewicht ausgedruckt werden.

3) Drei Zahlen sollen aufsteigend sortiert werden.

4) Gegeben sind die Längen a,b,c eines Dreiecks. Es soll entschieden werden, ob mit die­sen Sei­ten ein Dreieck gebildet werden kann, ob das Dreieck gleich­schenklig und/oder rechtwinklig ist.

5) Überlege, was das Programm tut, und ergänze die beiden write-Anweisungen in sinnvoller Weise.

var bstb

 

bstb = prompt("Buchstabe eingeben:\n(Keine Umlaute)","x")

if(bstb < "A" || bstb > "z" || bstb > "Z" && bstb < "a")

   document.write("<BR>Das ist kein Buchstabe !")

else if(bstb >= "A" && bstb <= "Z")

   document.write("<BR>Sie haben ... eingegeben.")

else

   document.write("<BR>Sie haben ... eingegeben.")

 

 

6. Algorithmen mit Wiederholungen

(1)  Wiederholung mit Endbedingung:
Struktogramm

 

< Anweisungsfolge >

solange    < Bedingung >

 

Umsetzung in die JavaScript-Syntax:
do
  {
     < Anweisungsfolge >
  } while ( < Bedingung > )

(2)  Wiederholung mit Anfangsbedingung:
Struktogramm

solange    < Bedingung >

 

< Anweisungsfolge >

 

Umsetzung in die JavaScript -Syntax:
while ( < Bedingung > )
      
{
        
< Anweisungsfolge >
       }

(3)  Wiederholung mit Zähler:
Struktogramm

Wiederhole für Zählvariable von Anfangswert bis Endwert

 

< Anweisungsfolge >

 

Umsetzung in die Pascal-Syntax:
for ( < Zählvariable > = < Anfangswert >; < Ausführungsbedingung >;
      
< Zählvariable > = < Zählvariable > ± < Schrittweite >)
      
{
      
       < Anweisungsfolge >
       }

 

Hinweis:

-   Die for-Schleife wird nur ausgeführt, falls die < Ausführungsbedingung > wahr ist.

-   Die Schleife kann durch die break Anweisung abgebrochen werden.

-   Nach for (...) darf kein Semikolon stehen, da sonst in der Schleife eine "Leeranweisung" ausgeführt wird.

 

 

PROGRAMMPROBLEME

Schreibe ein vollständiges JavaScriptProgramm (bzw. function) für jedes der folgenden Pro­bleme.

1) Schreibe je ein Programm, das alle ungeraden Zahlen von 1 bis n addiert.
- verwende dazu eine for-Schleife
- verwende dazu eine while Schleife

2) Schreibe eine Funktion, die einen numerischen Wert potenziert. Die Definition der Funktion soll so beginnen:
function potenz (basis, exponent) { ... }
Wird als Exponent 0 angegeben, soll die Potenz 1, wird als Exponent ein negativer Wert angegeben, soll der Fehlerwert -1 zurückgegeben werden. Ansonsten wird nach der Formel Rückgabewert = basis hoch exponent gerechnet.

3) Es sollen die ersten n Primzahlen ermittelt und ausgegeben werden.

4) Das folgende Programm gibt eine Anzahl von Sternen (*) in Form eines Dreiecks auf dem Bildschirm aus. Ändere das Programm so, dass dieses Dreieck auf dem Kopf steht.

var zeile,spalte;

 

for(zeile=1; zeile <= 20; zeile++) {

   for(spalte=1; spalte <= zeile; spalte++)

        document.write("*");

   document.write("<BR>");

}

Entwickle Programme für andere Sternchenmuster!

5) In einem Programm muss bei der Eingabe einer Zahl dafür gesorgt werden, dass nur Zahlen kleiner als null eingegeben werden können. Benütze zur Programmierung dieser Eingabe eine do-Schleife!

6) Was ist an folgendem Programm falsch?

var wert,wertminderung,restwert

var jahr

 

document.write("Berechnung der Wertminderung<BR>")

wert = prompt("Wert:",0)

document.write("<BR>Wert: ",wert)

wertminderung = prompt("%-Wertminderung:",0)

document.write("<BR>%-Wertminderung: ",wertminderung)

restwert = prompt("Restwert:",0)

document.write("<BR>Restwert: ",restwert)

jahr=1

while(parseFloat(wert) != parseFloat(restwert)) {

   wert=wert*((100-wertminderung)/100)

   document.write("<BR>Wert nach ",jahr,

             " Jahren ",wert)

   jahr++

}

parseFloat()

Wandelt eine zu übergebende Zeichenkette in eine Zahl um und gibt diese als numerischen Wert zurück. Wenn sich die Zahl als Kommazahl interpretieren läßt, wird dies berücksichtigt. Als Dezimalzeichen wird jedoch nur der Punkt interpretiert. Sinnvoll, um z.B. Anwendereingaben in Zahlen umzuwandeln, mit denen man anschließend rechnen kann.
Gibt NaN (Not a Number) zurück, wenn die Zeichenkette mit Zeichen beginnt, die sich nicht als Teil einer Zahl interpretieren lassen.
Wenn die Zeichenkette weiter hinten ungültige Zeichen enthält, wird die Zahl bis zum ersten ungültigen Zeichen interpretiert und der interpretierte Teil zurückgegeben.

Teste ParseFloat.js im JavaScript Tester.