lehrkraefte:blc:informatik:ffprg2-2024:arrays

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
lehrkraefte:blc:informatik:ffprg2-2024:arrays [2024/08/30 09:09] – [Initialiserung und Zugriff] Ivo Blöchligerlehrkraefte:blc:informatik:ffprg2-2024:arrays [2024/08/30 09:21] (current) – [Ausgabe] Ivo Blöchliger
Line 1: Line 1:
 +====== Arrays ======
 +===== Initialisierung und Zugriff =====
 +Eindimensionale Arrays, Grundlagen
 +<code javascript>
 +a = [7,11,13,42];  // Array mit 4 Elementen
 +console.log(a);  // Ganzes Array ausgeben
 +console.log(`Das erste Element ist a[0]=${a[0]}`);
 +console.log(`Das Array hat a.length=${a.length} Elemente`);
 +console.log(`Das letzte Element ist a[a.length-1]=${a[a.length-1]}`);
 +console.log("Zweites Element mit 1111 überschreiben: a[1] = 'Hallo';");
 +a[1] = 'Hallo';  // Zweites Element überschreiben
 +console.log(a);  // Ganzes Array ausgeben
 +</code>
 +
 +Initialisierung mit .push
 +<code javascript>
 +// Array befüllen mit push
 +a = [];  // Leeres Array
 +for (let i=0; i<10; i++) {
 +   a.push(i*i+i+1);   // Neuen Wert hinten anfügen
 +}
 +console.log(a);
 +</code>
 +
 +Initialisierung mit [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from|Array.from]]
 +
 +Das erste Argument ist ein Objekt, das die //property// ''length'' hat. 
 +
 +Das zweite Argument ist eine Funktion, die als zweiten Parameter den jeweiligen Index bekommt. Der erste Parameter wäre das i-te Element vom Objekt, das aber hier einfach ignoriert wird (und sowieso ''undefined'' wäre).
 +<code javascript>
 +a = Array.from({length:10}, (_,i)=>i*i+i+1);
 +console.log(a);
 +</code>
 +
 +===== Mehrdimensionale Arrays =====
 +<code javascript>
 +// Drei Punkte, gegeben als Array von 2 Koordinaten
 +dreieck = [[1,2], [5,3], [2,-1]];
 +console.log(dreieck);
 +console.log(`Zweiter Punkt dreieck[1]=${dreieck[1]}`);
 +console.log(`x-Koordinate vom 3. Punkt ist dreieck[2][0]=${dreieck[2][0]}`);
 +// Distanz zwischen den Punkten
 +for (let i=0; i<3; i++) {
 +  for (let j=(i+1); j<3; j++) {
 +    let l=0;
 +    for (let k=0; k<2; k++) {
 +      l+=(dreieck[i][k]-dreieck[j][k])**2;
 +    }
 +    l=l**0.5;  // Wurzel!
 +    console.log(`Distanz von Punkt ${i} zu Punkt ${j} ist ${l}`);
 +  }
 +}
 +</code>
 +
 +Initialisierung
 +<code javascript>
 +wuerfel = [];
 +for (let x=0; x<2; x++) {
 +  for (let y=0; y<2; y++) {
 +    for (let z=0; z<2; z++) {
 +       wuerfel.push([x,y,z]);
 +    }
 +  }
 +}
 +console.log(wuerfel);
 +
 +// Variante mit Bitoperationen und Array.from
 +// (i>>1) Verschiebt die Bits von i um eine Stelle nach rechts (niederwertigstes Bit fällt weg)
 +//  & 1 rechnet bitweise UND, d.h. alle ausser das niederwertigste Bit werden gelöscht.
 +wuerfel = Array.from({length:8}, (_,i) => [i & 1, (i >> 1) & 1, (i>>2) & 1]);
 +
 +// Variante für n Dimensionen
 +n = 4;
 +tesseract = Array.from({length:2**n}, (_,i) => Array.from({length:n}, (_,k) => (i>>k) & 1));
 +</code>
 +
 +
 +
 +===== Pascal-Dreieck =====
 +==== Erzeugung ====
 +
 +Erster Schritt: Aus einer Zeile die nächste generieren.
 +<code javascript>
 +zeile = [1,4,6,4,1];
 +neu = [1];  // Zeile startet mit 1
 +for (let i=0; i<zeile.length-1; i++) {
 +  neu.push(zeile[i]+zeile[i+1]);   // Elemente an Stellen i und i+1 zusammenzählen und hinzufügen
 +}
 +neu.push(1);  // 1 hinten anfügen
 +console.log(neu);
 +</code>
 +
 +Als Funktion verpacken und verwenden
 +<code javascript>
 +function nextline(zeile) {
 +  let neu = [1];  // Zeile startet mit 1
 +  for (let i=0; i<zeile.length-1; i++) {
 +    neu.push(zeile[i]+zeile[i+1]);   // Elemente an Stellen i und i+1 zusammenzählen und hinzufügen
 +  }
 +  neu.push(1);  // 1 hinten anfügen
 +  return neu;
 +}
 +pascal = [];
 +zeile = [1];
 +pascal.push(zeile);
 +for (let i=0; i<10; i++) {
 +   zeile = nextline(zeile);
 +   pascal.push(zeile);
 +}
 +console.log(pascal);
 +</code>
 +
 +==== Ausgabe ====
 +Hilfsfunktionen:
 +  * String mit einer gegebenen Anzahl Leerschlägen erzeugen
 +  * Zahl mit Leerschlägen auf gegebene Länge auffüllen.
 +
 +<code javascript>
 +function wiederholen(n, zeichen=" ") {
 +  let s = "";
 +  for (let i=0; i<n; i++) {
 +    s += zeichen
 +  }
 +  return s;
 +}
 +</code>
 +Oder very fancy:
 +<code javascript>
 +function wiederholen(n, zeichen=" ") {
 +  return Array.from({length:n}, ()=>zeichen).join("");
 +}
 +</code>
 +
 +
 +Zahlen mit nötigen Leerschlägen ausgeben:
 +<code javascript>
 +function fuellen(zahl, n) {
 +  let s = zahl.toString();
 +  s += wiederholen(n-s.length);
 +  return s;
 +}
 +</code>
 +
 +Oder zentriert:
 +<code javascript>
 +function fuellen(zahl, n) {
 +  zahl = zahl.toString();
 +  let fehlen = n-zahl.length;
 +  let vorne = Math.floor(fehlen/2);
 +  return wiederholen(vorne)+zahl+wiederholen(fehlen-vorne);
 +}
 +</code>
 +
 +Und jetzt die flexible Ausgabe:
 +<code javascript>
 +function ausgabe(pascal) {
 +  let n = pascal.length-1; // Index der letzten Zeile
 +  let space = pascal[n][Math.floor(n/2)].toString().length+1; // Grösster Koeffizient, Länge in Buchstaben+1
 +  let s = "";
 +  for (let i=0; i<=n; i++) {
 +     s += wiederholen(Math.floor((n-i)*space/2));
 +     s += pascal[i].map((e)=>fuellen(e,space)).join("")
 +     s += "\n";  // Zeilenumbruch
 +  }
 +  return s;
 +}
 +</code>
 +
 +
 +
 +==== Pascaldreieck direkt erzeugen ====
 +<code javascript>
 +// = n*(n-1)*(n-2)*...*(n-k+1) / (1*2*3*...*k)
 +function binomial(n,k) {
 +    if (k<0 || k>n) return 0;
 +    if (k==0 || k==n) return 1;
 +    if (k>n/2) return binomial(n,n-k);
 +    let r=n;
 +    for (let i=1; i<k; i++) {
 +        r*=(n-i);
 +        r/=i+1;
 +    }
 +    return r;
 +}
 +
 +d = Array.from({length:11}, (_,n)=>Array.from({length:n+1}, (_,k)=>binomial(n,k)));
 +</code>
 +
 +==== Screencast ====
 +
 +[[https://fginfo.ksbg.ch/~ivo/videos/informatik/ffprog24-2/02-pascal-dreieck.mp4|Weltöffentlich]] und für [[https://bldsg-my.sharepoint.com/:v:/g/personal/ivo_bloechliger_ksbg_ch/EVSGwxcSndZOhy7htMcPplgBHRko1oNh_e0PZQQINOQ-hw?nav=eyJyZWZlcnJhbEluZm8iOnsicmVmZXJyYWxBcHAiOiJPbmVEcml2ZUZvckJ1c2luZXNzIiwicmVmZXJyYWxBcHBQbGF0Zm9ybSI6IldlYiIsInJlZmVycmFsTW9kZSI6InZpZXciLCJyZWZlcnJhbFZpZXciOiJNeUZpbGVzTGlua0NvcHkifX0&e=iBDwEE|St. Gallen Microsofties]]
 +
 +<hidden Code vom Screencast>
 +<code javascript>
 +function nextLine(zeile) {
 +    let neu = [1];
 +    for (let i=0; i<zeile.length-1; i++) {
 +        neu.push(zeile[i]+zeile[i+1]);
 +    }
 +    neu.push(1);
 +    return neu;
 +}
 +
 +function dreieck(n) {
 +    pascal = [];
 +    zeile = [1];
 +    pascal.push(zeile);
 +    for (let i=0; i<n; i++) {
 +        zeile = nextLine(zeile);
 +        pascal.push(zeile);
 +    }
 +    return pascal;
 +}
 +
 +function wiederholen(n, zeichen=" ") {
 +    return Array.from({length:n}, ()=>zeichen).join("");
 +}
 +
 +function zahlfuellen(zahl, n) {
 +    zahl = zahl.toString();
 +    let fehlt = n-zahl.length;
 +    let vorne = Math.floor(fehlt/2);
 +    return wiederholen(vorne)+zahl+wiederholen(fehlt-vorne);
 +}
 +
 +function ausgabe(n) {
 +    let d = dreieck(n);
 +    let largest = d[n][Math.floor(n/2)];
 +    let space = largest.toString().length+1;
 +    let s = "";
 +    for (let i=0; i<=n; i++) {
 +        s += wiederholen(space*(n-i)/2);
 +        s += d[i].map((e)=>zahlfuellen(e,space)).join("");
 +        s += "\n";  // Zeilenumbruch
 +    }
 +    return s;
 +}
 +
 +console.log(ausgabe(10));
 +</code>
 +</hidden>