2016-04-17 13 views
1

I ein Programm mache, wo ich 2-Vektoren (clientvec und productslist) und ich brauche eine 2D Boolesche Matrix zu schaffen, wo die Spalten die Größe productslist Vektor ist und die Linien ist die Größe diesen Fehler von clientvec Vektor, aber es gibt mir:C++ Erstellen einer 2D Boolesche Matrix

"expression must have a constant value"

Hier ist der Code, den ich verwendet:

unsigned int lines = clientvec.size(); 
unsigned int columns = productslist.size(); 
bool matrixPublicity[lines][columns] = {false}; 

Pls mir helfen ..

Edit: Ich bin neu in C++, so gehe ich davon nichts xD

EDIT2 wissen: Ich habe bereits für die Antworten wissen, dass ich nicht ein Array mit nicht konstanten Werten initialisiert werden können, nun die Frage, wie kann ich sie nach initialisieren ...

+0

C++ hat keine [Arrays mit variabler Länge] (https://en.wikipedia.org/wiki/Variable-length_array), Sie müssen ['std :: vector'] verwenden (http: // en .cppreference.com/w/cpp/container/vector) (spezifischer ein Vektor von Vektoren). –

+0

Und selbst wenn der Compiler eine Erweiterung der Sprache hat, die VLAs erlaubt (und einige haben eine solche Erweiterung, aber ich empfehle nicht, sie zu benutzen), so initialisierst du ein Array nicht. Sie * wissen * wie man ein Array initialisiert? Sie wissen, geschweifte Klammern und all das? –

+0

Nun, ich habe gerade mit C++ begonnen, also weiß ich nicht viel von C++ ... aber ein Array kann mehrdimensional sein, oder? Und wie initialisiert man ein Array? –

Antwort

0

die Fehlermeldung ist klar:: expression einen konstanten Wert“

Es bedeutet die Array-Dimension sein kann, nicht von Variablentyp haben muß. Nur enum s oder vorprozessordefinierte Konstanten sind gültig.

für weitere Informationen siehe: Why can't I initialize a variable-sized array?

Edit: Da Sie erwähnt Sie neu in C++, hier ist ein Stück Code, den Sie helfen könnten:

#include <iostream> 
#include <vector> 
#include <bitset> 

int main() 
{ 
    unsigned int lines = 10; 
    const unsigned int columns = 5; 

    std::vector<std::bitset<columns>> matrixPublicity; 
    matrixPublicity.resize(lines); 

    for(int i=0; i < lines; i++) 
    { 
     for(int j=0; j < columns; j++) 
      std::cout << matrixPublicity[i][j] <<' '; 
     std::cout<<'\n'; 
    } 
} 

beachten Sie, dass in diesem Fall, columns muss konstant sein.

Edit 2: Und wenn die Größe der Linien nicht gleich sind, dann müssen Sie halten Sie sich an vector Typen:

typedef std::vector<bool> matrixLine; 
std::vector<matrixLine> matrixPublicity; 

jetzt Sie resize Methode für die i-te Zeile der Matrix verwenden können , z.B

matrixPublicity[1].resize(number_of_columns_in_line_2); 
+0

Was kann ich tun? Ich muss wirklich das verwenden .. –

+0

Verwenden Sie ein 'std :: vector >' und Größe ändern. Oder in diesem Fall kann auch 'std :: bitset' hilfreich sein. Siehe [Vektorreferenz] (http://en.cppreference.com/w/cpp/utility/bitset) und auch [Bitset] (http://en.cppreference.com/w/cpp/utility/bitset) –

+0

In meinem Programm ist die Größe der Vektoren nicht immer gleich, also wie kann ich die Anzahl der Spalten ändern? –

0

Was Sie versuchen, die gleiche wie dies zu tun wäre:

std::vector<unsigned int> v1 { 1, 2, 3, 4, 5 }; 
std::vector<unsigned int> v2 { 6, 7, 8, 9 }; 

bool mat[v1.size()][v2.size()] = false; 

Dies ist, wie der Compiler es ohne die Provisorien zu interpretieren und dies ist ungültig. Wenn Sie ein Array eines beliebigen Typs deklarieren, muss seine Größe zur Kompilierungszeit bekannt sein.

bool mat[2][3] = false; // still invalid  
bool mat[2][3] = { false }; // Okay 

const int x = 5; 
const int y = 7; 
bool mat[x][y] = false; // invalid 
bool mat[x][y] = { false }; // okay 

// Even this is invalid 
std::vector<int> v1{ 1, 2, 3 }; 
std::vector<int> v2{ 4, 5, 6, 7 }; 
const std::size_t x1 = v1.size(); 
const std::size_t y1 = v2.size(); 
bool mat2[x1][y1] = { false }; // Still won't compile. 

Der Wert zum Deklarieren eines Arrays muss ein konstanter Ausdruck sein.

+0

Thx, aber jetzt ist die Frage, wie kann ich die nicht konstanten Werte nach der Initialisierung setzen? –

+0

@ J.Seixas hast du dir die Antwort angesehen, die ich oben für dich erstellt habe, wo ich eine Klassenvorlage erstellt habe, die zwei Vektoren des gleichen Typs nimmt und einen Vektor (Matrix) eines anderen Typs konstruiert? –

0

Erstellen eines Arrays ist nicht so schwierig :) Eine Matrix (2D/3D/...- Array) ist leider ein bisschen anders, wenn Sie es auf Ihre Weise tun wollen!

But first of all you should know about the stack and the heap!

Lets bei diesen 2 einen Blick:

Stack:

Ein Stapel Variable/Array/Matrix/...ist nur gültig zwischen den nächsten 2 -> {} < - die Sie normalerweise einen "Codeblock" nennen. Die Größe wurde während der "Kompilierzeit" definiert (die Zeit, in der der Compiler Ihren Code in die Maschinensprache übersetzt). Das bedeutet, dass die Größe Ihres Arrays festgelegt werden muss.

Beispiel:

#include <iostream> 
#define MACRO 128 

int arraySize(int size){ 
    std::cin >> size; 
    return size; 
} 

int main() { 

    //this is valid 
    int intArray[128] = {}; //the size(here: 128) needs to be a number like 
          //or a macro like 'MACRO' which is 
          //compile-time-only as well 

    //this is valid 
    int intArray2[MACRO] = {}; 

    //this is not valid! 
    int intArray[size()] = {}; 

    return 0; 
} 

Heap:

Ein Haufen Variable/Array/Matrix/... ist gültig, bis Sie sie löschen. Das bedeutet auch, dass eine Heap-Variable während der Laufzeit erstellt wird (vom Starten Ihres Programms bis zum Schließen/Stoppen)! Dies ermöglicht Ihnen, seine Größe zu definieren.

Beispiel:

#include <iostream> 
#define MACRO 128 

int arraySize(int size){ 
    return size; 
} 

int main() { 

    //this is valid 
    int intArray[128] = {}; //the size(here: 128) needs to be a number like 
          //or a macro like 'MACRO' whic is 
          //compile-time-only as well 

    //this is valid 
    int intArray2[MACRO] = {}; 

    //creating an array with a non-static size 
    //works like this: 
    //int can also be a 'bool' 
    int* intArray = new int[arraySize()]; 
    //^the star means you are pointing to 
    //an adress inside of your memory which has 
    //the size of an int (per element) 
    //That's why they are called "pointers"! 
    //Right now it points to the beginning of the 
    //array. 

    //    ^the keyword "new" says that 
    //you are allocating memory on the heap. 

    //     ^
    //then you have to say which kind of array 
    //it is which is the same you gave the pointer 

    //      ^
    //now you give it the size of that array 
    //this time it can be return value or the size 
    //of a variable 

    //as I mentioned...you have to delete this array on your own 
    //if you dont do that your program will crash 
    //maybe not after starting but it will! 
    //SO NEVER NEVER NEVER... forget about it 
    delete intArray[]; 

    //^ write delete 

    //  ^
    //then the name of your array 

    //   ^
    //at the end of it write these 2 brackets 
    //thex say you wanna remove the whole array! 
    //why? because you can also create/delete 
    //heap variables not only arrays. 

    return 0; 
} 

eine Matrix auf dem Heap zu schaffen, ist leider nicht so einfach. Aber es ist wichtig zu wissen, wie ein 1D-Array funktioniert, bevor man zu weiteren Dimensionen geht! Deshalb habe ich dieses Tutorial gemacht!

Klick here to see how to create a matrix on the heap

Klick here to learn more about the heap

Klick here to choose the best result of this theme

Ich hoffe, ich könnte Ihnen helfen :)!

0

Anstatt ein Array so zu erstellen, wie Sie es versucht haben, können Sie eine Klassenvorlage erstellen, die ein matrixartiges Objekt für Sie erstellt. Hier ist, was ich mir ausgedacht habe, jetzt passt das gesamte Design oder Muster dieser Vorlage zu Ihrem Zustand, aber die tatsächliche Implementierung, um die interne Matrix zu generieren, wird von Ihren Daten und Ihrer Absicht abhängen.

#include <vector> 
#include <iostream> 
#include <conio.h> 

template <class T, class U> 
class Matrix { 
private: 
    std::vector<T> m_lines; 
    std::vector<T> m_cols; 
    std::vector<U> m_mat; 
    std::size_t  m_size; 
    std::size_t  m_lineCount; 
    std::size_t  m_colsCount; 

public: 
    Matrix() {}; 
    Matrix(const std::vector<T>& lines, const std::vector<T>& cols) : 
     m_lines(lines), 
     m_cols(cols), 
     m_lineCount(lines.size()), 
     m_colsCount(cols.size()) 
    { 
     addVectors(lines, cols); 
    } 

    void addVectors(const std::vector<T>& v1, const std::vector<T>& v2) { 
     m_lines = v1; 
     m_cols = v2; 
     m_lineCount = m_lines.size(); 
     m_colsCount = m_cols.size(); 
     for (unsigned int i = 0; i < m_lineCount; ++i) { 
      for (unsigned int j = 0; j < m_colsCount); j++) { 
       // This will depend on your implementation and how you 
       // construct this matrix based off of your existing containers 
       m_mat.push_back(m_lines[i] & m_cols[j]); 
      } 
     } 
     m_size = m_mat.size(); 
    } 

    std::size_t size() const { return m_size; } 
    std::size_t sizeRows() const { return m_lineCount; } 
    std::size_t sizelColumns() const { return m_colsCount; } 

    std::vector<U>&  getMatrix() const { return m_mat; } 
    std::vector<T>&  getLines() const { return m_lines; } 
    std::vector<T>&  getColumns() const { return m_columns; } 

    bool operator[](std::size_t idx) { return m_mat[idx]; } 
    const bool& operator[](std::size_t idx) const { return m_mat[idx]; } 
}; 

int main() { 
    std::vector<unsigned> v1{ 1, 0, 1, 1, 0 }; 
    std::vector<unsigned> v2{ 0, 1, 1, 1, 0 }; 

    Matrix<unsigned, bool> mat1(v1, v2); 
    int line = 0; 

    for (unsigned u = 0; u < mat1.size(); ++u) { 
     line++; 
     std::cout << mat1[u] << " "; 
     if (line == mat1.sizeRows()) { 
      std::cout << "\n"; 
      line = 0; 
     } 

    } 

    std::cout << "\nPress any key to quit.\n" << std::endl; 
    _getch(); 
    return 0; 
} 

Ausgabe

0 1 1 1 0 
0 0 0 0 0 
0 1 1 1 0 
0 1 1 1 0 
0 0 0 0 0 

Mit dieser Template-Klasse können Sie eine Matrix beliebigen Typs U, indem in zwei Vektoren für T Typen erstellen. Wie Sie die Matrix konstruieren, hängt von der Implementierung ab. Aber diese Klasse ist für verschiedene Typen wiederverwendbar.

Sie könnten zwei Vektoren vom Typ doubles haben und eine Matrix von unsignierten Zeichen konstruieren, oder Sie könnten zwei Vektoren von benutzerdefinierten Klassen- oder Strukturtypen haben und eine Matrix von vorzeichenlosen Werten erzeugen. Dies kann Ihnen in vielen Situationen helfen.

Hinweis: - Dies hat eine Compiler-Warnung generieren, wenn keine Fehler und er druckt und korrekt angezeigt, aber die Compiler-Warnung von MSVS 2015 erzeugt warnt C4800: unsigned int: forcing value to bool true or false (performance warning)

Dies ist für mich ein bisschen täte erzeugt wird weise & Operation auf vorzeichenlose Werte; Aber das ist der Grund, warum ich meine anfänglichen Vektoren so eingestellt habe, dass sie an den Konstruktor dieser Klassenvorlage übergeben werden, um alle 1s & 0s zu haben, da dies nur zur Demonstration gedacht ist.

EDIT - ich bearbeitet der Klasse gemacht, weil ich bemerkte ich einen Standardkonstruktor und hatte keine Möglichkeit, Vektoren, um es hinzuzufügen, so habe ich eine zusätzliche Membervariable und eine addVectors Funktion, und bewegt die Umsetzung vom definierten Konstruktor zur neuen Funktion und endete damit, dass diese Funktion im definierten Konstruktor aufgerufen wurde.