C ++制作2D布尔矩阵

时间:2016-04-17 15:17:03

标签: c++ c++11 visual-c++ matrix c++14

我正在制作一个程序,我有2个向量(clientvecproductslist),我需要创建一个 2D布尔矩阵,其中列的大小为{ {1}}向量和行是productslist向量的大小,但它给了我这个错误:

  

"表达式必须具有常量值"

以下是我使用的代码:

clientvec

请帮帮我..

编辑:我是c ++的新手所以假设我什么都不知道xD

Edit2:我已经知道我无法用非常数值初始化数组的答案,现在的问题是如何在初始化之后将它们放入...

4 个答案:

答案 0 :(得分:0)

错误消息是明确的::表达式必须具有常量值"

这意味着数组维度不能是变量类型。只有enum或预处理器定义的常量才有效。

有关详情,请参阅: Why can't I initialize a variable-sized array?

编辑:由于您提到您不熟悉C ++,因此以下是一段可能对您有所帮助的代码:

#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';
    }
}

请注意,在这种情况下,columns必须保持不变。

编辑2:如果行的大小不一致,那么您必须坚持使用vector类型:

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

现在你可以使用resize方法作为矩阵的第i行,例如

matrixPublicity[1].resize(number_of_columns_in_line_2);

答案 1 :(得分:0)

您要做的事情与此相同:

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;

这是编译器在没有临时值的情况下解释它的方式,这是无效的。声明任何类型的数组时,必须在编译时知道其大小。

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.

声明数组的值必须是常量表达式。

答案 2 :(得分:0)

创建数组并不困难:) 不幸的是,如果你想按自己的方式去做,矩阵(2D / 3D / ......阵列)会有点不同!

  

但首先你应该知道堆栈和堆!

让我们看看这两个:

  

堆栈:

堆栈变量/数组/矩阵/ ...仅在最近的2 - >之间有效。 {}&lt; - 您通常称之为&#34; codeblock&#34;。它的大小是在'#34;编译时'#34; (编译器将代码转换为机器语言的时间)。这意味着需要设置数组的大小。

示例:

#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;
}
  

堆:

堆变量/ array / matrix / ...在删除之前有效。这也意味着在运行期间创建堆var(从启动程序到关闭/停止它)!这允许您定义它的大小。

示例:

#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;
}

遗憾的是,在堆上创建矩阵并不容易。 但是在了解更多尺寸之前,了解一维阵列的工作原理至关重要!这就是我做这个教程的原因!

  

Klick here,了解如何在堆上创建矩阵

     

点击here了解有关堆的更多信息

     

点击here选择此主题的最佳结果

我希望我可以帮助你:))

答案 3 :(得分:0)

您可以创建一个类模板,为您构建一个类似于对象的矩阵,而不是按照您的尝试制作数组。这是我提出的,现在这个模板的整体设计或模式将适合您的条件,但生成内部矩阵的实际实现将取决于您的数据和您的意图。

#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;
}

<强>输出

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

使用此模板类,您可以通过传入类型U的两个向量来创建任何类型T的矩阵。现在,如何构建矩阵将依赖于实现。但是这个类可以重用于不同的类型。

你可以有两个类型为双精度的向量,并构造一个无符号字符矩阵,或者你可以有两个用户定义类或结构类型的向量,并生成一个无符号值矩阵。这可能会在很多情况下帮助你。

注意: - 这确实会生成编译器警告,但没有错误,它会正确打印并显示,但MSVS 2015生成的编译器警告警告C4800: unsigned int: forcing value to bool true or false (performance warning)

这是因为我做得有点明智而且对无符号值的操作;但这就是为什么我将我的初始向量设置为传递给此类模板的构造函数以使所有1和&amp; 0s,因为这仅用于演示。

编辑 - 我对该类进行了编辑,因为我注意到我有一个默认构造函数,无法向其添加向量,所以我添加了一个额外的成员变量和一个addVectors函数,并将实现从定义的构造函数移动到新函数,最后在定义的构造函数中调用该函数。