Home
Über mich
Veröffentlichungen

XML XML-Schema XPath XSL-T XSL-FO XQuery XProc SVG

XQuery / Rekursive Funktionsaufrufe in XQuery

Rekursive Funktionsaufrufe in XQuery

Rekursive Funktionsaufrufe in XQuery

➪ Rekursive Funktionsaufrufe ermöglichen in XQuery die Abbildung herkömmlicher while-Schleifen.

Auf dieser Seite:

Wie viele Eier waren im Korb?

Wohl die meisten Teilnehmer meiner Programmierseminare kennen das Eier-Beispiel: Kürzlich ging eine Bauerfrau mit einem Korb Eiern auf den Markt, um diese zu verkaufen. Plötzlich wird sie von einem Radfahrer angefahren. Sämtliche Eier sind zerbrochen. Der Radfahrer möchte den Schaden bezahlen und fragt: Wie viele Eier waren im Korb?

Das wußte die Frau nicht. Aber am Vorabend hatte sie die Eier sortiert: in 2er-Reihen, in 3er-Reihen, in 4er-, 5er- 6er-Reihen, jeweils blieb ein Ei übrig. Erst in der 7er-Reihe stimmte die Symmetrie, es war kein Ei zuviel oder zuwenig. Frage: Wie viele Eier waren mindestens im Korb?


declare function local:eierei($anzahl as xs:integer){
  if($anzahl mod 7 = 0) 
  then($anzahl) 
  else(
    local:eierei($anzahl+60)
  )
};
<ergebnis>Es waren {
  local:eierei(1)
} Eier im Korb.</ergebnis>

Viel Speß beim Aufruf!

Hunde, Katzen, Mäuse

Denselben Teilnehmern meiner Programmierseminare ist wohl auch das Beispiel mit Hunden, Katzen und Mäusen in Erinnerung. Es geht darum, zu einer gegebenen Zahl (im Beispiel 351) sämtliche sämtliche Kombinationen zu ermitteln, die in der Anzahl der Tiere und in der Summe der Preise jeweils 351 ergeben.

Beispiel: Sie haben 351 Euro und möchten für exakt diese Summe genau 351 Tiere kaufen. Ein Hund kostet 15 Euro, eine Katze ein Euro, eine Maus 25 Cent. Von jeder Tierart soll mindestens ein Exemplar gekauft werden. Wie viele Hunde, Katzen, Mäuse kaufen Sie (bitte alle Kombinationen)?

Die Lösung in XQuery:


declare function local:hkm($zahl as xs:integer, 
                           $h as xs:integer, 
                           $k as xs:integer, 
                           $m as xs:integer){    
  if ($k > 0) then (   
    element {'loesung'}{
      attribute {'hunde'}{$h},
      attribute {'katzen'}{$k},
      attribute {'maeuse'}{$m},
      attribute {'anzahlTiere'}{$m + $h + $k},
      attribute {'summePreise'}{$m*0.25 + $h*15 + $k}
   },      
    let $h2 as xs:integer := $h + 3
    let $m2 as xs:integer := $m + 56
    let $k2 as xs:integer := $zahl - $h2 - $m2   
    return local:hkm($zahl, $h2, $k2, $m2)
  ) else ()  
};
<e>{
  let $zahl as xs:integer := 351
  (: die erste Loesung steht bereits, da $m = 56/3*$h :)
  return local:hkm($zahl, 3, $zahl - 3 - 56, 56)
}</e>

Der Ratenkredit

Auch bei der Berechnung eines Ratenkredits (hier vereinfachte Version) lohnt sich der Einsatz rekursiver Funktionsaufrufe.


declare function local:ratenkredit(
       $Restkapital as xs:decimal, 
       $Zinssatz as xs:decimal, 
       $Rate as xs:decimal){
  element {'ratenkredit'}{
    attribute {'Anfangskapital'}{$Restkapital},
    attribute {'Zinsen'}{$Restkapital * $Zinssatz},
    attribute {'Rate'}{$Rate},
    attribute {'Gesamtlast'}{$Restkapital * $Zinssatz + $Rate},
    attribute {'Endkapital'}{$Restkapital - $Rate}
  },
  if (($Restkapital - $Rate) > 0) then (
    local:ratenkredit($Restkapital - $Rate, $Zinssatz, $Rate)
  ) else()
};
<ergebnis>{
  local:ratenkredit(100000, 0.05, xs:decimal(100000 div 10))
}</ergebnis>

Das Resultat gibt den Kreditverlauf gut wieder:


<ergebnis>
  <ratenkredit 
        Anfangskapital="100000" 
        Zinsen="5000" 
        Rate="10000" 
        Gesamtlast="15000" 
        Endkapital="90000"/>
  <ratenkredit 
        Anfangskapital="90000" 
        Zinsen="4500" 
        Rate="10000" 
        Gesamtlast="14500" 
        Endkapital="80000"/>
  <ratenkredit 
        Anfangskapital="80000" 
        Zinsen="4000" 
        Rate="10000" 
        Gesamtlast="14000" 
        Endkapital="70000"/>
  <ratenkredit 
        Anfangskapital="70000" 
        Zinsen="3500" 
        Rate="10000" 
        Gesamtlast="13500" 
        Endkapital="60000"/>
  <ratenkredit 
        Anfangskapital="60000" 
        Zinsen="3000" 
        Rate="10000" 
        Gesamtlast="13000" 
        Endkapital="50000"/>
  <ratenkredit 
        Anfangskapital="50000" 
        Zinsen="2500" 
        Rate="10000" 
        Gesamtlast="12500" 
        Endkapital="40000"/>
  <ratenkredit 
        Anfangskapital="40000" 
        Zinsen="2000" 
        Rate="10000" 
        Gesamtlast="12000" 
        Endkapital="30000"/>
  <ratenkredit 
        Anfangskapital="30000" 
        Zinsen="1500" 
        Rate="10000" 
        Gesamtlast="11500" 
        Endkapital="20000"/>
  <ratenkredit 
        Anfangskapital="20000" 
        Zinsen="1000" 
        Rate="10000" 
        Gesamtlast="11000" 
        Endkapital="10000"/>
  <ratenkredit 
        Anfangskapital="10000" 
        Zinsen="500" 
        Rate="10000" 
        Gesamtlast="10500" 
        Endkapital="0"/>
</ergebnis>

wg / 12. Dezember 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.



V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/XQuery_rekursive_Funktionsaufrufe.html