+1 Daumen
2,7k Aufrufe

Aufgabe:
Es geht um ein Programm in dem ich 

1. Schritt.
v für Vektor eingebe
m für Matrix eingebe

2. Schritt (Je nach Wahl aus Schritt eins) 
dimenson von v eingebe, zb 2 (also v hat zwei Elemente) 
oder dimension von m eingebe, zb 2x2. 

3. Schritt (Je nach Wahl aus Schritt 1 und Schritt 2) 
die Elemente einlese. 

Dann wiederholt sich der Schritt und ich kann ein Zweites Element "kreieren"
Und je nach dem was ich insgesamt (Also welche zwei ich) gewählt habe gibt das Programm mir raus :

(i) für Vektorprodukt: s "Zahl".  Wobei s für scalar steht und Zahl das Vektorprodukt ist. 
(ii) Matrixvektorprodukt: v "Zahlen" , wobei v für Vektor steht und Zahlen die Einträge dieses Vektors sind. 
(iii) Matrixprodukt: m "Zahlen, wobei m für Matrix steht und Zahlen für Einträge stehen.  

Was hat bisher geklappt ? 
Bis vorgestern hatte ich 
Vektoren einlesen können, und es gab mir korrekterweise das Richtige heraus. 

Was klappt seit gestern nicht ?

Gestern konnte ich eine Matrix m "kreieren", indem ich zuerst ein m eintippte, dann die dimension zb 2 2 (für 2x2) dann 
konnte ich alle Einträge eingeben (zb 100 010 001)  und es gab mir das heraus. !! 

Was klappt seit gestern nicht ? 

Ich wollte mich dem Matrix-Vektor-Produkt widmen, dann konnte ich das Programm starten, und 
dann konnte ich mittels m eine Matrix wählen, bestimme die Dimension und auch kann ich sie füllen mit einträgen. 
Im zweiten Schritt wähle ich v für Vektor und kann die dimension wählen, wenn ich aber Einträge eintippe kann ich das zwar tun aber nachdem ich den letzten Eintrag eintippe und mit Enter bestätige kommt mir eine Fehlermeldung: 

Fehlermeldung: program terminated by signal: Segmentation fault

In einem anderen Compiler der selbe fehler: exited, segmentation fault


Frage: 
Kann mir jemand weiterhelfen ? 

Der Code ist auf repl.it zu sehen: https://repl.it/@limonade1234/Vector-and-Matrix-operations
Ein Video meines Fehlers habe ich auf youtube geladen: https://www.youtube.com/watch?v=k8Hrr3n-l7o
Beschreibung des Programms und Auftrag ist auch in replit unter description.md als file hinterlegt. 

Achtung: Wir dürfen für dieses Programm keine Klassen verwenden, auch dürfen wir matrix library nicht includen, 
es geht darum dass man genau diese Operationen in Funktionen aufteilt und so zum laufen bringt.
Weiter ist alles was in diesem Code steht meine Arbeit, also ich habe mit einem leeren Dok angefangen und zuerst mal in Kommentaren geschrieben, was ich eigentlich tun will. 

Code hier gepostet:

#include <iostream>
#include <vector>

//Create a Vector with this Method
void vector(std::vector<int>& vec){
   
    int size_vec; // creates the variable for the size of a vector.
    //std::cout << "Enter the Size of the Vector ? " << std::endl; // How many elements should the vectore have ?
    std::cin >> size_vec; // store the number of elements (size) in the variable size_vec.
    vec.resize(size_vec); // resize the vector with the resize method.
   
    //std::cout << "Enter the " << size_vec << " Elements of the Vector ? " << std::endl; // Enter the elements into the vector.
    for(int i = 0 ; i < size_vec ; ++i){ //Use a for loop for that.
        std::cin >> vec[i];
    }
   
    /*
    std::cout << "v " << vec.size() << std::endl; //Output the Vectors elements.
    for(unsigned int k = 0 ; k < vec.size(); ++k){ // Use a for loop for that.
        std::cout << vec[k] << " "; // Output the elements separated by an space.
    }
    */
   
}

//TODO: Write method to create, size and fill Matrix.
void matrix(std::vector<std::vector<int>>& mat){
    int m;
    int n;
   
    //std::cout << "Enter number of rows: " << std::endl;
    std::cin >> m;
   
    //std::cout << "Enter number of columns: " << std::endl;
    std::cin >> n;
   
    mat.resize(m, std::vector<int>(n)); // resize the matrix.

    for(int i=0  ; i<m ; ++i){
        for(int j=0; j<n ; ++j){
      //std::cout << "Enter Elemnts of Matrix: " << std::endl;
          std::cin>>mat[i][j];}
      std::cout<<std::endl;}
   
    /*
    std::cout<<"m"<< m << n << std::endl;
    for(int q=0;q<m;++q){
      for(int w=0;w<n;++w){
        std::cout<<mat[q][w]<<" ";}
      std::cout<<std::endl;
    }
    */
 
 
}



//------------------ Operation Methods ------------------//
//------------------------ below ------------------------//

//PRE: a and b are the same length.
//POST: Returns the dot product of a and b.
int dot_product(std::vector<int>& a, std::vector<int>& b){
    int product = 0;
    for(unsigned int k=0 ; k < b.size() ; ++k){
        product += a[k]*b[k];
    }
    return product;
}

//TODO: Write function for Matrix vector product
//PRE: input is m and v.
//POST:
void mvp(std::vector<std::vector<int>>& c, std::vector<int>& d){
  std::vector<int> mv_product;
  for(unsigned int h = 0 ; h < d.size() ; ++h){
    for(unsigned int g = 0 ; g < d.size() ; ++g){
      mv_product[h] += c[h][g]*d[g];
    }
  }
}



//TODO: Write function for MATRIXPRODUCT
//PRE: input is m and m.
//POST:
//code here:

   



int main() {
    char x1;
    //std::cout << " Press m for matrix and v for vector: " << std::endl;
    std::cin >> x1;
    std::vector<int> a1;
    std::vector<std::vector<int>> b1;
 
   
   
   
   
    if(x1=='v'){
        vector(a1);}
    if(x1=='m'){
        matrix(b1);}
   
   
    char x2;
    //std::cout << " Again, Press m for matrix and v for vector: " << std::endl;
    std::cin >> x2;
    std::vector<int> a2;
    std::vector<std::vector<int>> b2;
   
   
   
    if(x2=='v')
        vector(a2);
    if(x2=='m')
        matrix(b2);
       
     
     
   
   
   
   
    //std::cout << "\n" << "s" << dot_product(a,b) << std::endl;
   

    //TODO: If vector vector check dimensoins, then call dot product function. And output letter and return value.
    if(x1=='v' || x2 == 'v')
        std::cout << "s " << dot_product(a1,a2) << std::endl;
       
    //TODO: If matrix vector check dimensoins, call Matrix-vector product. And output letter and return value.
    if(x1=='m' || x2 == 'v')
      mvp(b1, a2);
   
   
       
    //TODO: If matrix matrix call Matrix product. And output letter and return value.

    //TODO: If vector matrix output error.
   
   
 
    return 0;
}



Avatar von

2 Antworten

+2 Daumen
 
Beste Antwort
void mvp(std::vector<std::vector<int>>& c, std::vector<int>& d) {
std::vector<int> mv_product;
for (unsigned int h = 0; h < d.size(); ++h) {
for (unsigned int g = 0; g < d.size(); ++g) {
mv_product[h] += c[h][g] * d[g];
}
}
}

Da fehlt

        mv_product.resize(c.size());

oder vergleichbares.

Außerdem bekommst du ein Problem, wenn die Matrix nicht quadratisch ist. Die äußere for-Schleife sollte bis c.size() laufen, weil der Ergebnissvektor so viele Zeilen hat, wie die Matrix, und nicht so viele wie der Vektor mit dem multipliziert wird, .

Drittens, du berechnest zwar das Matrix-Vektor-Produkt, machst aber nichts mit dem Ergebnis. Ich würde es per return zurückgeben. Dazu musst du natürlich auch die Signatur der Funktion anpassen.

Du kannst übrigens die innere for-Schleife ersetzen durch

        mv_product[h] = dot_product(c[h], d);

Avatar von 5,7 k

Vielen Dank, 

Ich habe alles geändert, wobei ich aber die innere for-Schleife beibelassen habe. Und die Fehlermeldung ist weg. 

Das Resultat  ist ein Vektor, also der returnwert muss ein Vektor werden. 

Frage:
Wie gebe ich einen Vektor zurück, und was schreibe ich für einen Vector als Funktionentyp hin (jetzt ist er void).

Denn dann möchte ich in der  Zeile 136 so vorgehen: 

    //TODO: If matrix vector check dimensoins, call Matrix-vector product. And output letter and return value. 
    if(x1=='m' && x2 == 'v')
        std::cout << "v " << mvp(b1, a2)<< std::endl;

Weiter kriege ich zwar die Fehlermeldung nicht,

aber wenn ich das matrix-vektorprodukt machen will, mittlerweile habe ich die innere for-Schleife mit 

mv_product[h] = dot_product(c[h], d);

ersetzt.,

erhalte ich eine falsche Lösung. 

Mene Einglabe:

Compilation successful

2
2
1
0

0
1

v
2
1
0
v 0 // <--- Das ist das ERgebnis, es sollte allerdings v 1 0 sein.


Zeig mal die aktuelle Version der Funktion mvp.

Wie gebe ich einen Vektor zurück

Genau so wie du auch ein int zurückgibst.

und was schreibe ich für einen Vector als Funktionentyp hin

std::vector<int> mvp(const std::vector<std::vector<int>>& c, const std::vector<int>& d)

Jetzt habe ich ein drucheinander. Habe einiges an Code geändert. 

in Zeile 134
steht nach wie vor: 

//TODO: If matrix vector check dimensoins, call Matrix-vector product. And output letter and return value. 
    if(x1=='m' && x2 == 'v')
        mvp(b1,a2);

Sinn:
So rufe ich die Funktion mvp() auf, falls vom Bediener m(und dann dim von m dann elemente eignelesen) und  v (und dim v dann dessen elemente eingelesen) eingegeben wurde. 

Zeile 75 :
 Die Funktion mvp: 
//TODO: Write function for Matrix vector product
//PRE: input is m and v.
//POST:
std::vector<int> mvp(const std::vector<std::vector<int>>& c, const std::vector<int>& d){
  std::vector<int> mv_product;
  mv_product.resize(c.size());
  for(unsigned int h = 0 ; h < c.size() ; ++h){
    //for(unsigned int g = 0 ; g < c.size() ; ++g){
      //mv_product[h] += c[h][g]*d[g];
      mv_product[h] = dot_product(c[h], d);
    }
    return mv_product;
  }

Das Problem hier ist nun, wenn ich mv_product ausgeben will kommt wieder eine Fehlermeldung, die ich nicht verstehe. Sie hat mit dem Funktionsaufruf, also caller mvp(b1,a2); zu tun und es zeigt einen Fehler an auf der schliessenden klammer mvp(b1,a2)
eine Fehlermeldung, die ich nicht verstehe.

Wie lautet sie? Vielleicht versteht jemand anders sie.

In der Aufgabenstellung steht "Use references with proper constness to access c++|std::vectors from functions.". Dehalb habe ich als Signatur für mvp

    std::vector<int> mvp(const std::vector<std::vector<int>>&, const std::vector<int>&)

angegeben. Da diese Funktion jetzt dot_product aufruft, muss natürlich auch in dieser Funktion die Parameter const-Referenzen sein.

+1 Daumen

Hallo limonade,

geht man bei der Eingabe in der Reihenfolge 'm', 'v' vor, so wird der vector a1 gar nicht gefüllt, In Zeile 143 fragst Du ab

    if (x1 == 'v' || x2 == 'v')

d.h. es reicht aus, dass x2 == 'v' ist, um die nächste Zeile aufzurufen. Dort wird nun das innere (dot) Produkt von a1 und und a2 gerufen. a1 ist aber nicht beschreiben worden und hat demnach die Länge 0. Das führt dann zu dem von Dir geschilderten Fehler.

Richtig wäre hier wohl

    if (x1 == 'v' && x2 == 'v')

und weiter unten

if (x1 == 'm' && x2 == 'v')

Logik-Fehler mit || und && sind die Klassiker unter den Fehlern, die man lange nicht sieht ;-)
Avatar von

Vielen Dank !

Stimmt.

Habs geändert,

aber diese Meldung bleibt trotzdem bestehen. :-/

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community