Informatik I - Ãœbung 7

Pascal Schärli

pascscha@student.ethz.ch

05.04.2019

Was gibts heute?

  • Feedback
  • Best-Of Vorlesung:
    • 2D Vektoren
    • Rekursive Funktionen
  • Vorbesprechung
  • Program of the Week

Pascal Schärli 05.04.2019

Feedback

Pascal Schärli 05.04.2019

Das Fach Informatik I ist für euch im Allgemeinen:

Pascal Schärli 05.04.2019

0
0
2
7
7
2
2
3
0
0
0
1
2
3
4
5
6
7
8
9
10
20

sehr schwierig

sehr einfach

0
0
1
2
17
2
1
0
0
0
0
1
2
3
4
5
6
7
8
9
10
20

Das Tempo der Übungsstunde ist für euch im Allgemeinen:

zu langsam

zu schnell

Pascal Schärli 05.04.2019

0
0
1
4
15
1
0
2
0
0
0
1
2
3
4
5
6
7
8
9
10
20

Das Niveau der Übungsstude ist für euch:

zu einfach

zu schwierig

Pascal Schärli 05.04.2019

1
0
0
0
21
1
0
0
0
0
0
1
2
3
4
5
6
7
8
9
10
20

Mein Übungsstil ist für euch:

zu angewant

zu theoretisch

Pascal Schärli 05.04.2019

0
0
0
2
1
4
7
7
0
7
0
1
2
3
4
5
6
7
8
9
10
20

Die Übungsstunden helfen euch so viel beim Lösen der Serien:

sehr schwierig

sehr einfach

Pascal Schärli 05.04.2019

Was soll ich ändern?

  • 1x Slides vorher hochladen
  • 1x Ãœbungsstunde zu "basic"
  • 1x Knappere Programme/ Pseudo Code

Pascal Schärli 05.04.2019

Was ist gut so?

  • 4x Slides
  • 4x Program of the Week
  • 3x Beispiele
  • 2x Motivation
  • 2x Memes
  • [...]

Pascal Schärli 05.04.2019

Vorlesung

Pascal Schärli 05.04.2019

Matrizen in C++

Wie kann man in C++ 2D Matrizen speichern?

  • Ein Vektor kann verschiedene Typen wie int, float oder double speichern.
  • Es ist also auch möglich in einem Vector eine Liste von anderen Vektoren zu speichern
\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\\ \end{bmatrix}

Pascal Schärli 05.04.2019

Recap

\begin{bmatrix} 0\\ 0\\ 0\\ \end{bmatrix}
std::vector<int> v(3, 0);

Typ: int

Länge: 3

Startwert: 0

Pascal Schärli 05.04.2019

2-D Vektor

std::vector< std::vector<int> > m(3, std::vector<int>(3, 0));

Typ: 1D Vektor

Länge: 3

Startwert: Vektor mit länge 3, startwert 0

\begin{bmatrix} 0&0&0\\ 0&0&0\\ 0&0&0\\ \end{bmatrix}
\begin{bmatrix} 0&0&0 \end{bmatrix}
std::vector<int> v(3, 0);

Pascal Schärli 05.04.2019

2-D Vektor

std::vector< std::vector<int> > vec(3, std::vector<int>(3, 0));
vec.at(0).at(0) = 1;
vec.at(2).at(1) = 2;
vec.at(0).at(2) = 3;
\begin{bmatrix} 1&0&0\\ 0&0&2\\ 3&0&0\\ \end{bmatrix}
std::vector< std::vector<int> > vec(3, std::vector<int>(3, 0));
vec[0][0] = 1;
vec[2][1] = 2;
vec[0][2] = 3;

Pascal Schärli 05.04.2019

Abkürzungen

std::vector< std::vector<int> > m(3, std::vector<int>(3, 0));

Pascal Schärli 05.04.2019

Damit unser Programm nicht zu unleserlich wird, kann man am Anfang vom Programm (nach den includes) Abkürzungen für Datentypen machen:

#include <iostream>
#include <vector>

using vec = std::vector<int>;
using mat = std::vector<vec>;

int main(){
    mat m(3, vec(3, 0));
}
\begin{bmatrix} 0&0&0\\ 0&0&0\\ 0&0&0\\ \end{bmatrix}

Abkürzungen

Pascal Schärli 05.04.2019

#include <iostream>
#include <vector>

using vec = std::vector<int>;
using mat = std::vector<vec>;

int main(){
    vec v(3, 0);
    mat m(2, vec(3, 1));

    m[1][2] = 5;
    v[2] = m[1].size();
    m[1][1] = v.empty();
    v[1] = '9';

    return 0;
}
v = \begin{bmatrix} 0&57&3\\ \end{bmatrix}
m = \begin{bmatrix} 1&1\\ 1&0\\ 1&5\\ \end{bmatrix}

"Printing" Matrices

Pascal Schärli 05.04.2019

#include <iostream>
#include <vector>
using vec = std::vector<int>;
using mat = std::vector<vec>;

// PRE:  Matrix with at leas one row
// POST: Writes the matrix into standard output.
void print_matrix(const mat &m) {
    unsigned int row, col;
    row = m.size();
    col = m[0].size();
    
    std::cout << row << " " << col << std::endl;
    for (unsigned int r = 0; r < row; r++) {
        for (unsigned int c = 0; c < col; c++) {
            std::cout << m[r][c] << " ";
        }
        std::cout << std::endl;
    }
}

int main(){
    mat m(2, vec(3,0));

    m[1][2] = 1;
    m[0][1] = 3;

    print_matrix(m);
    return 0;
}
2 3
0 3 0 
0 0 1

row

col

Reading Matrices

Pascal Schärli 05.04.2019

// POST: Returns a matrix that was read from the standard
// input.
mat read_matrix() {
    unsigned int row, col;
    std::cin >> row >> col;
    mat m(row, vec(col));
    for (unsigned int r = 0; r < row; r++) {
        for (unsigned int c = 0; c < col; c++) {
            std::cin >> m[r][c];
        }
    }
    return m;
}

Matrix Transpose

Pascal Schärli 05.04.2019

Skizziert ein Programm, welches eine Matrix als input nimmt und diese Transponiert:

2 3
1 2 3
4 5 6

Input:

3 2
1 4
2 5
3 6

Output:

// PRE:  Matrix with at leas one row
// POST: Return a matrix that is a transpose
//        of the input matrix.
mat transpose(const mat &m) {
    unsigned int row = m.size();
    unsigned int col = m[0].size();

    // TODO: Finish implementation.

}
int main () {
    mat m = read_matrix();
    mat m_transposed = transpose(m);
    print_matrix(m_transposed);
}

Matrix Transpose

Pascal Schärli 05.04.2019

// PRE:  Matrix with at least one row
// POST: Return a matrix that is a transpose
//        of the input matrix.
mat transpose(const mat &m) {
    unsigned int row = m.size();
    unsigned int col = m[0].size();

    mat transposed = mat(col, vec(row));

    for(unsigned int r = 0; r < row; r ++){
        for(unsigned int c = 0; c < col; c++){
            transposed[c][r] = m[r][c];
        }
    }

}

Rekursive Funktionen

int foo(double p, unsigned int e){
    if(e == 0){
        return 1;
    }
    else{
        return p * foo(p, e-1);
    }
}
4
8
25
10000
int main(){
    std::cout << foo(2,2) << std::endl;
    std::cout << foo(2,3) << std::endl;
    std::cout << foo(5,2) << std::endl;
    std::cout << foo(10,4) << std::endl;
    return 0;
}

Pascal Schärli 05.04.2019

Rekursive Funktionen

int foo(double p, unsigned int e){
    if(e == 0){
        return 1;
    }
    else{
        return p * foo(p, e-1);
    }
}

\( p = 2, e = 2\)

\( 2 * foo(2, 1)\)

\(foo(2, 2)\)

\( p = 2, e = 1\)

\( 2 * foo(2, 0)\)

\(foo(2, 1)\)

\( p = 2, e = 0\)

1

\(foo(2, 0)\)

\( = 2 * 1 = 2\)

\( = 2 * 2 = 4\)

\( p = 2, e = 3\)

\( 2 * foo(2, 2)\)

\(foo(2, 3)\)

\( = 2 * 4 = 8\)

Pascal Schärli 05.04.2019

Rekursive Funktionen

int foo(unsigned int l, unsigned int b){
    if(l == 1){
        return 0;
    }
    else{
        return 1 + foo(l / b, b);
    }
}
1
2
3
3
int main(){
    std::cout << foo(2,2) << std::endl;
    std::cout << foo(5,2) << std::endl;
    std::cout << foo(27,3) << std::endl;
    std::cout << foo(30,3) << std::endl;
    return 0;
}

Pascal Schärli 05.04.2019

Rekursive Funktionen

int foo(unsigned int l, unsigned int b){
    if(l == 1){
        return 0;
    }
    else{
        return 1 + foo(l / b, b);
    }
}

\( l = 10, b = 3\)

\( 1 + foo(3, 3)\)

\(foo(10, 3)\)

\( l = 3, b = 3\)

\( 1 + foo(1, 3)\)

\(foo(3, 3)\)

\( l = 1, b = 3\)

0

\(foo(1, 3)\)

\( = 1 + 0 = 1\)

\( = 1 + 1 = 2\)

\( l = 30, b = 3\)

\( 1 + foo(10, 3)\)

\(foo(30, 3)\)

\( = 1 + 2 = 3\)

Pascal Schärli 05.04.2019

Vorbesprechung

Pascal Schärli 05.04.2019

Pascal Schärli 05.04.2019

Schreibt ein Programm, welches Integer Vektoren und Matrizen miteinander multiplizieren kann.

Text Representationen:

m 2 3
 1  1 -5
-1  0  4
v 3
3 5 7
s 7

Matrix

Vektor

Skalar

Pascal Schärli 05.04.2019

Einlesen:

Lest zuerst den Charakter ein, welcher den Datentyp bestimmt (s, v oder m). Danach ruft ihr die entsprechende Funkion auf (Matrix einlesen)

Vektor(ll) Matrix(m2xn2)
Vektor(l) Skalar error
Matrix(m1xn1) n1 = l, Vektor(m1) n1 = m2, Matrix(m1xn2)

Y

X

Output for X * Y :

NZZ binary

Pascal Schärli 05.04.2019

Am 8.06.2012 war die Titelseite der NZZ in binär geschrieben. Wir werden nun diese Titelseite als Übung lesen!

01001110 01011010 01011010

78 90 90

NZZ

Pascal Schärli 05.04.2019

Euer Input kommt aus einem File. Um den Inhalt von diesem File zu bekommen könnt ihr einen sogenannten "Filestream" benutzen:

1101000 1101001 100001

hi.in

#include <iostream>
#include <string>
#include <fstream>

int main(){
    std::ifstream in("hi.in");

    std::string byte;

    in >> byte;

    std::cout << byte;
}

main.cpp

+

1101000
#include <iostream>
#include <string>
#include <fstream>

int main(){
    std::ifstream in("hi.in");

    std::string byte;

    while((bool)(in >> byte)) {
        std::cout << byte << " ";
    }
}
1101000 1101001 100001

Pascal Schärli 05.04.2019

Um einzelne "char" aus eurem byte herauszulesen könnt ihr einen Loop machen und die einzelnen Charakter mit [i] herauslesen.

std::string string = "01010000";

for(unsigned int i = 0; i < 8; i++){
    std::cout << string[i] << '\n';
}

Achtung! Diese sind vom typ "char", und nicht "int".

'0' -> 48

'1' -> 49

Siehe Slides vom letzten mal!

"double" quotes für string

'single' quote für char

Pascal Schärli 05.04.2019

Starthilfe (Nur für den Notfall)

#include <iostream>
#include <string>
#include <fstream>

// POST: Returns the character corresponding to the
//        input string value
char decode_to_char(const std::string & value){
    // TODO
}

int main () {
    // Read file name and open file input stream.
    std::string filename;
    std::cin >> filename;
    std::ifstream in(filename);
    if(!(bool)(in)) {
        std::cout << "File does not exists !\n";
        return 1;
    }
    
    std::string value;
    while((bool)(in >> value)) {
        std::cout << decode_to_char(value);
    }
    
    return 0;
}
bool f(const int n) {
  if (n == 0){
    return false;
  }
  else{
    return !f(n-1);
  }
}
void g(const int n) {
  if (n == 0) {
    std::cout << "*";
    return;
  }
  g(n-1);
  g(n-1);
}
  1. Pre-/Post Conditions
  2. Begründe warum die Programme terminieren
  3. Berechnet die Anzahl Funktionsaufrufe in Abhängigkeit von n

Tipps:

  • Ãœberlegt euch ein Beispiel falls ihr nicht weiter kommt.
  • Eventuell hilft es die Funktion in einem Programm zu testen

Pascal Schärli 05.04.2019

Program of the Week

Pascal Schärli 05.04.2019

Viel Spass!

Pascal Schärli 05.04.2019