Thread: Making an array with x and y

  1. #1
    Railgun God |Wiz|'s Avatar
    Join Date
    Sep 2005
    Posts
    23

    Making an array with x and y

    I want to create an array such as int array[x][y], where x and y are specified by the user beforehand. Is there a way to do it?

    I searched for array and dynamic array and came up with nothing.

  2. #2

  3. #3
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    You could do that, but it's ugly and error-prone (in other words, it's C code )

    a much nicer solution is to use a (no prizes for guessing what I'm going to suggest)boost multi_array. Which at least, is ugly and safe. It's also reuseable, generic and can be used with STL algorithms
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  4. #4
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    Quote Originally Posted by ChaosEngine
    It's also reuseable, generic and can be used with STL algorithms
    you failed to mention that boost is non-standard so it is not be supported by all compilers. Its not even shipped with or recommended by any compilers that I know of -- although it can be downloaded free. And, you almost need a Ph.D in computer science to read/use it

    There is another alternative -- use a vector of vectors, although to boost implementation is probably cleaner.
    Code:
    typedef vector<int> COLUMNS;
    vector<COLUMNS> rows;
    Last edited by Ancient Dragon; 03-05-2006 at 08:55 PM.

  5. #5
    Railgun God |Wiz|'s Avatar
    Join Date
    Sep 2005
    Posts
    23
    Ah, but can you access parts of it using array format?

    Yours certainly looks much nicer than the others.

    Do you substitute the variables in "COLUMNS" and "rows"? My VC++ 2005 doesn't seem to like it.
    Last edited by |Wiz|; 03-05-2006 at 09:12 PM.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Ancient Dragon
    you failed to mention that boost is non-standard so it is not be supported by all compilers.
    FWIW:

    http://boost.org/
    Boost provides free peer-reviewed portable C++ source libraries.

    We emphasize libraries that work well with the C++ Standard Library. Boost libraries are intended to be widely useful, and usable across a broad spectrum of applications. The Boost license encourages both commercial and non-commercial use.

    We aim to establish "existing practice" and provide reference implementations so that Boost libraries are suitable for eventual standardization. Ten Boost libraries are already included in the C++ Standards Committee's Library Technical Report ( TR1) as a step toward becoming part of a future C++ Standard. More Boost libraries are proposed for the upcoming TR2.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by Ancient Dragon
    you failed to mention that boost is non-standard so it is not be supported by all compilers. Its not even shipped with or recommended by any compilers that I know of -- although it can be downloaded free. And, you almost need a Ph.D in computer science to read/use it

    There is another alternative -- use a vector of vectors, although to boost implementation is probably cleaner.
    Code:
    typedef vector<int> COLUMNS;
    vector<COLUMNS> rows;
    it's tested on nearly every major compiler out there. They bend over backwards to make it work even on the steaming pile of dog excrement that is vc6. And if you think boost is too difficult to use, maybe C++ isn't the language for you

    as for a vector of vectors, the problem with that is you can easily end up with a jagged vector ala

    [0, 1, 0, 2, 3, 4]
    [0, 1, 3, 4]
    [2, 3, 4]
    [0, 0, 1, 0, 2, 3, 4]
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  8. #8
    Slave MadCow257's Avatar
    Join Date
    Jan 2005
    Posts
    735
    here's a double vector example

    Code:
    #include <vector>
    #include <iostream>
    using namespace std;
    int main ()
    {
    	typedef vector<int> COLUMNS;
    	vector<COLUMNS> rows;
    	COLUMNS ex;
    	ex.push_back(15);
    	ex.push_back(10);
    	rows.push_back(ex);
    	cout << rows[0][1];
    }
    EDIT
    Completely unrelated wiz, but I'm building a railgun and it appears you're the god of them. So if you're interested or can give me some tips PM me
    Last edited by MadCow257; 03-05-2006 at 09:21 PM.

  9. #9
    Railgun God |Wiz|'s Avatar
    Join Date
    Sep 2005
    Posts
    23
    ah, but compare

    Code:
    #include "boost/multi_array.hpp"
    #include <cassert>
    
    int 
    main () {
      // Create a 3D array that is 3 x 4 x 2
      typedef boost::multi_array<double, 3> array_type;
      typedef array_type::index index;
      array_type A(boost::extents[3][4][2]);
    
      // Assign values to the elements
      int values = 0;
      for(index i = 0; i != 3; ++i) 
        for(index j = 0; j != 4; ++j)
          for(index k = 0; k != 2; ++k)
            A[i][j][k] = values++;
    
      // Verify values
      int verify = 0;
      for(index i = 0; i != 3; ++i) 
        for(index j = 0; j != 4; ++j)
          for(index k = 0; k != 2; ++k)
            assert(A[i][j][k] == verify++);
    
      return 0;
    }
    to

    Code:
    #include <vector>
    #include <iostream>
    using namespace std;
    int main ()
    {
    	typedef vector<int> COLUMNS;
    	vector<COLUMNS> rows;
    	COLUMNS ex;
    	ex.push_back(15);
    	ex.push_back(10);
    	rows.push_back(ex);
    	cout << rows[0][1];
    }
    .

    It's like OpenGL vs. DirectX - they do the same thing, but would you rather write 13 lines of code or 26 lines of code?

    Think it over.

  10. #10
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597

    Angry

    They do not do the same thing.
    with the boost version you end up with a completely populated 3 dimensional array.

    with the vector of vectors you end up with
    [[15, 10]]

    to do the same as the boost version you need to write
    Code:
    	typedef vector<int> COLUMNS;
    	typedef vector<COLUMNS> Matrix2D;
    	typedef vector<Matrix2D> Matrix3D;
    
            Matrix3D mat3;
    	int values = 0;
    	for(index i = 0; i != 3; ++i) 
    	{
            	Matrix2D mat2;
    		for(index j = 0; j != 4; ++j)
    		{
    			COLUMNS ex;
    			for(index k = 0; k != 2; ++k)
    			{
    				ex.push_back(values++);
    			}
    			mat2.push_back(ex);
    		}
    		mat3.push_back(mat2);
    	}
    so let's see, it's also roughly 13 lines (not counting {}), but the vector of vector of vectors version does a huge amount of copying temporaries, not to mention it has a clumsy error prone interface.

    Think it over. I know which one I'd pick.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  11. #11
    Railgun God |Wiz|'s Avatar
    Join Date
    Sep 2005
    Posts
    23
    Hey - it still crashes.

    Ah well, code-posting time.

    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <time.h>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
    typedef vector <int> b;
    vector <b> a;
    b ex;
    ex.push_back(15);
    ex.push_back(9);
    a.push_back(ex);
    
    int x, y, cx, cy, high, low;
    
    cout << "X" << '\n';
    cin >> x;
    cin.ignore();
    cout << "Y" << '\n';
    cin >> y;
    cin.ignore();
    cout << "high" << '\n';
    cin >> high;
    cin.ignore();
    cout << "low" << '\n';
    cin >> low;
    cin.ignore();
    cx = 1;
    cy = 1;
    
    
    clock_t cur;
    
    while (cx + cy <= x + y)
    {
    cur = clock();
    srand ((unsigned int) cur);
    ex.push_back(cur % (high - low + 1) + low);
    if (cx == x)
    {
    cx = 1;
    cy = cy + 1;
    a.push_back(ex);
    }
    else
    {
    cx = cx + 1;
    }
    }
    cx = 1;
    cy = 1;
    ofstream newfile ( "list" );
    while (cx + cy <= x + y)
    {
    newfile << a [cx][cy];
    if (cx == x)
    {
    cx = 1;
    cy = cy + 1;
    }
    else
    {
    cx = cx + 1;
    }
    }
    newfile.close();
    }
    I can't find the bug.

  12. #12
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    Code:
    srand ((unsigned int) cur);
    the above is not supposed to be in a loop -- it should be called only once during the lifetime of the program. move that line somewhere close to the beginning of main().

  13. #13
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    not sure what your program is attempting to do, maybe something like this??? Below creates a 2d array of x rows and y columns, initializes rows and colums with a random number, then displays the numbers and writes them out to a file. I just hardcoded the x, y, high and low values to make running/debugging easier.

    Code:
    int main()
    {
    	typedef vector <int> b;
    	vector <b> a;
    	b ex;
    
    	int x, y, high, low;
    
    	srand ((unsigned int) time(0));
    	x = 2;
    	y = 3;
    	high = 100;	
    	low = 1;
    
    	ex.resize(y);
    	a.resize(x);
    	// initialize all rows of the vector with 
    	// columns.
    	for(int i = 0; i < x; i++)
    		a[i] = ex;
    
    	for(int i = 0; i < x; i++)
    	{
    		for(int j = 0; j < y; j++)
    		{
    			a[i][j]= rand() % (high - low + 1) + low;
    		}
    	}
    	ofstream newfile ( "list" );
    	for(int i = 0; i < x; i++)
    	{
    		for(int j = 0; j < y; j++)
    		{
    			int n = a [i][j];
    			cout << n << " ";
    			newfile << n << " ";
    		}
    		cout << endl;
    	}
    	newfile.close();
    	cin.ignore();
    }

  14. #14
    Tropical Coder Darryl's Avatar
    Join Date
    Mar 2005
    Location
    Cayman Islands
    Posts
    503
    I would roll my own multidimension object something on the lines of this:

    Code:
    #include <iostream>
    #include <ctime>
    
    template <typename T>
    class multiArray
    {
    public:
    	multiArray(int x, int y):mX(x),mY(y)
    	{
    		mpArray = new T[x*y];
    	}
    	T& operator()(int x, int y)
    	{
    		if(x>mX || y > mY || x<0 || y < 0) throw "out of bounds";//just for demonstration
    		return mpArray[y*mX+x];
    	}
    	~multiArray()
    	{
    		delete[] mpArray;
    	}
    
    private:
    	int mX;
    	int mY;
    	T* mpArray;
    
    };
    
    int main()
    {
    	srand(time(0));
    	multiArray<int> intArray(3,5);
    	for (int a = 0; a < 3; a++)
    		for (int b = 0;b < 5; b++)
    		{
    			intArray(a,b)=rand();
    			std::cout << intArray(a,b) << "\n";
    		}
    	return 0;
    }

  15. #15
    Railgun God |Wiz|'s Avatar
    Join Date
    Sep 2005
    Posts
    23

    About Vectors

    How do you go to a new line when using vectors?

Popular pages Recent additions subscribe to a feed