I've been struggling with a simple class representing a matrix in C++. Instead of using a multidimensional array, I've decided to use a flat array and access the values by calculating the index of the according cell by [row * x_dim + col]. I want to use 2D matrices only.
Ideally, I would also create getter and setter functions, but as I am already having troubles I skipped those for now.
The main problem is, that after setting values, those values seem to be corrupted somewhere along the way as when printing them out again, I'm reading different values then what I've actually stored.
Here's the (simplified) header MyMatrix.h:
class MyMatrix{
public:
int x_dim, y_dim;
float *my_matrix;
MyMatrix(int x, int y);
~MyMatrix();
};
Here is MyMatrix.cpp:
#include "MyMatrix.h"
MyMatrix::MyMatrix(int x, int y){
x_dim = x;
y_dim = y;
my_matrix = new float[x * y];
}
MyMatrix::~MyMatrix(){
delete[] my_matrix;
}
Now when creating a new instance of MyMatrix, filling the array with ascending numbers and then printing the values again, I am getting different values for some cells in the (flat) matrix. Here's what I did:
#include "MyMatrix.h"
#include <iostream>
int main(){
MyMatrix test(3, 4);
//filling the array in test with ascending numbers
for(int row = 0; row < test.x_dim; row++){
for(int col = 0; col < test.y_dim; col++){
test.my_matrix[row * test.x_dim + col] = col+1;
}
}
for(int row = 0; row < test.x_dim; row++){
std::cout << "Row " << row << ": ";
for(int col = 0; col < test.y_dim; col++){
std::cout << test.my_matrix[row * test.x_dim + col] << " ";
}
std::cout << std::endl;
}
}
So what my output should look like is this:
Row 0: 1 2 3 4
Row 1: 1 2 3 4
Row 2: 1 2 3 4
But instead, it looks like this:
Row 0: 1 2 3 1
Row 1: 1 2 3 1
Row 2: 1 2 3 4
As one can see, the first two rows have a 1 instead of a 4 in column 3.
I've really been struggling with identifying the underlying issue here and I can't figure it out so I would appreciate any help!
Thanks!
I am using clang version 13.0.0 on an M1 Pro and the g++ compiler.
This is the wrong index:
row * test.x_dim + col
Suppose you are in the last iteration of the outer loop then row == x_dim-1 and you get:
(x_dim-1) * x_dim + col
while it should be (supposed x is rows):
(y_dim-1) * x_dim + col
Tip: Your variable naming col vs x_dim and row vs y_dim can be made better. x, x_dim and y, y_dim or col, num_columns and row, num_rows would be less errorprone.
Related
I have a 2D array initialized to Storage[100][3].
I insert a group values to each row of the array and move on to the next row and do the same,
for example:
1 1 3
2 5 6
3 1 3
(keeps going on to 100 rows)
After completing the insertion of 1 entire row I want to check if the values in this current insertion's column's 2 and 3 match the values in all the previous row's, column's 2 and 3.
for example in the above data set I look at column's 2 and 3 in each row and see that rows 1 and 3 have the same values in those columns.
I wrote a program that can compare the current insertion to the previous insertion. But I want to compare the current insertion with all the insertions in the array.
const int col=0;
//inserting the values//
for (int row= 0; row < 100; row++) {
storage[row][col] = t;
storage[row][col += 1] = xi;
storage[row][col += 2] = yi;
}
//trying to check if the values are same. need help here//
for (int row = 0; row < 100; row++) {
if (storage[row][col + 1]==storage[row + 1][col + 1]
&& storage[row][col + 2] == storage[row + 1][col + 2]) {
}
}
for (int row = 1; row < 100; row++) {
for (int prevRow = 0; prevRow < row; prevRow++) {
if (storage[row][1] == storage[prevRow][1]
&& storage[row][2] == storage[prevRow][2]) {
// do something...
}
}
}
Outer loop starts from row = 1 becuase row 0 doesn't have previous rows to compare.
If you want to create an algorithm that scales nicely O(log2n) rather than O(n^2) try using a Hash table to keep track of encountered numbers. My example numbers for the first iteration are 4, 2, 3.
You can get a count of how many times you've encountered your duplicate numbers and most importantly you don't have to do the heavy lifting of loop-searching yourself!
int main(array<System::String ^> ^args)
{
std::map<int, int> twoColsCounts;
int storage[100][3];
int ordinal1 = 4;
int ordinal2 = 2;
int ordinal3 = 3;
for (int i = 0; i < 100; i++)
{
storage[i][0] = ordinal1;
storage[i][1] = ordinal2;
storage[i][2] = ordinal3;
int lastTwoDigits = ordinal2 * 10 + ordinal3;
auto inMapRecord = twoColsCounts.find(lastTwoDigits);
if (inMapRecord != twoColsCounts.end())
{
// Number Already Found. Increment count for posterity!
twoColsCounts[lastTwoDigits]++;
}
else
{
// Not already encountered - Add it to record with count of 1
twoColsCounts[lastTwoDigits] = 1;
}
}
Console::WriteLine(L"Done 'big data' style!");
return 0;
}
Good luck!
I have a 6 x 6 matrix, and I am storing its values in a one dimensional array of size 36. I want to rearrange it so that the rows are the columns and the columns are the rows. My method is trying to copy the values into another array, but sorted properly. I am trying a for loop:
for (int i = 0; i < 6; ++i){
copyArray[i]= array[i*6];
}
This works fine for the first new row made up of the first column, but how do I continue to do all of them? I have tried nested for loops but cannot come up with the proper algorithm using iterators. I could do this manually, but would like to have this done by code.
I am coding in C++, but if anyone can do it in a similar language that would be fine. I feel this is a math problem.
The Question: How do I solve for switching out the rows and columns?
(Example: if I am denoting the first rows and columns as 0, in a 6x6 matrix, then both rows and columns go from 0 to 5. Therefore, by switching rows and columns, the value in row 2, column 5 would be switched with the value in row 5, column 2.)
Couldn't you just use a nested for loop and do something like this?
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j)
copyArray[i*6+j]= array[j*6+i];
Here's a test program you can run to show it works:
#include <stdio.h>
int main()
{
int array[36] = {1,1,1,1,1,1,
2,2,2,2,2,2,
3,3,3,3,3,3,
4,4,4,4,4,4,
5,5,5,5,5,5,
6,6,6,6,6,6};
int copyarray[36];
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j)
copyarray[i*6+j]= array[j*6+i];
for (int i = 0; i < 36; ++i)
{
if (i % 6 == 0)
printf("\n");
printf("%d ", array[i]);
}
printf("\n");
printf("\n");
for (int i = 0; i < 36; ++i)
{
if (i % 6 == 0)
printf("\n");
printf("%d ", copyarray[i]);
}
return 0;
}
Output:
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
You should keep your one-D array inside a class.
Then you can swap the dimensionality of the data without actually moving it.
class MySwapableArray
{
bool normal;
int array[36];
public:
int& operator()(int x, int y)
{
int h = normal ? x : y;
int v = normal ? y : x;
return array[h*6+v];
}
void swapRowsAndColumns()
{
normal = ! normal;
}
};
If you want to use operator[] like A[x][y] then see: How to overload array index operator for wrapper class of 2D array?
A template for doing so.
template<class X> std::unique_ptr<typename std::pointer_traits<X>::element_type[]>
transpose(const X& p, int x, int y) {
using T = std::pointer_traits<X>::element_type;
std::unique_ptr<T[]> r = new T[x*y];
for(int a = 0; a < x; ++a)
for(int b = 0; b < y; ++b)
r[x*a+b] = p[y*b+a];
return r;
}
If you want to avoid a double-for loop, you should be able to do it mathematically with something like
for (int i = 0; i < 36; ++i) {
copyarray[6 * (i % 6) + i / 6] = array[i]
}
Basically, 6 * (i % 6) aligns you to the right row in the transposed matrix, and the i / 6 (ab)uses integer division to translate the column value into a row value. floor (i / 6.0) is more correct if you can live with the clutter.
for( int i=0;i<6;i++)
for( int j=0;j<6;j++)
{ }//You can do whatever you want on original matrix here
Let's say that you want "transpose of matrix" and do some processing .Basically switch i and j
for( int j=0;j<6;j++) // replaceed i with j
for( int i=0;i<6;i++)
{ }//You can do whatever you want on transpose matrix here
novice C++ programmer here (using Visual Studio 2013).
I'd like to write a function where I can insert a number, and it will check if that number has a zero directly above, below or beside it, and then return the position of the zero.
For example, if I want to check the surroundings of number 2 which is at (1, 1), I want it to return (if there is any) the position of 0 which is at (1, 2). How would I go about doing this? Should I use matrix field instead (int a[][] e.g.)?
The function will be used to determine if the number, say 2, is able to swap places with the another number (zero in my case), and it can only do so if the zero is directly above, below or beside it.
3 5 6 8
9 2 0 7
1 8 9 3
1 3 5 7
This is my code so far, it only creates a vector matrix (sorry if I'm using the incorrect terms), randomizes a number between 1 - 15 and places it at a (row, col), and then replaces a number in a chosen (row, col) with a zero with the function set_zero.
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <vector>
using namespace std;
void set_zero(int row, int column, vector<vector<int>>& v){
v[row][column] = 0;
}
void scan_zero(vector<vector<int>>& v){
}
int _tmain(int argc, _TCHAR* argv[])
{
const int x = 4;
vector<vector<int>> v(x, vector<int>(x));
for (int i = 0; i < x; i++){
for (int j = 0; j < x; j++){
v[i][j] = rand() % 15 + 1;
}
}
set_zero(1, 2, v);
for (int i = 0; i < x; i++){
for (int j = 0; j < x; j++){
cout << setw(3) << v[i][j] << " ";
}
cout << endl;
}
}
I've tried searching the web for something similiar but I haven't found it, I'm sure it's out there but I just don't know how to properly formulate the search question.
Yeah, let's try using a 2d array (which simulates a matrix, int a[][] is referred to a 2d matrix).
Following your example: You want to check if the adjacent entries are zero. Let's use your example of (1,1) being 2.
A series of if statements could be your solution.
Let matrix be an integer 2d matrix of some size.
if matrix[1][2] equals 0 then
return positionRight
if matrix[1][0] equals 0 then
return positionLeft
if matrix[0][1] equals 0 then
return positionUp
if matrix[2][1] equals 0 then
return positionDown
Since your you're only checking the indexes directly adjacent, 4 if statements isn't that bad of an idea to inspect for an adjacent zero.
I think this might be a solution, it feels a bit primitive though.
Because I couldn't figure out how to return two values I just made two functions, one returning the position of the row, one of the column for the zero.
I did also run into the problem when it extends out of bounds of the matrix, so because I had a 4x4 matrix, i instead made it 6x6 and surrounded it with a frame of -1s.
int scan_zero_r(int r, int c, vector<vector<int>>& v){
int l = r + 1, k = r - 1;
if (v[l][c] == 0)
return l;
if (v[k][c] == 0)
return k;
else
return r;
}
int scan_zero_c(int r, int c, vector<vector<int>>& v){
int l = c + 1, k = c - 1;
if (v[r][l] == 0)
return l;
if (v[r][k] == 0)
return k;
else
return c;
}
I have a table which consists of nonnegative integers that are layed out in this manner: Each element in the table is the minimum value that does not appear to its left or above it. Here's an example of a 6x6 grid:
0 1 2 3 4 5
1 0 3 2 5 4
2 3 0 1 6 7
3 2 1 0 7 6
4 5 6 7 0 1
5 4 7 6 1 0
The first row and column begin with 0 1 2 3 4 5... In coordinates (x,x) is always a 0, as you can see. On each tile after that, you have to place the smallest positive number that doesn't already exist on the same row or column. Much like in a sudoku-puzzle: There cannot be a number twice on the same row and column.
Now I have to print the number in the given coordinates (y,x). For example [2, 5] = 5
I came up with a working solution, but it takes way too much memory and time, and I just know there's another way of doing this. My time limit is 1 second, and the coordinates I have to find the number at can go up to (1000000, 1000000).
Here's my code at the moment:
#include <iostream>
#include <vector>
int main()
{
int y, x, grid_size;
std::vector< std::vector<int> > grid;
std::cin >> y >> x; // input the coordinates we're looking for
grid.resize(y, std::vector<int>(x, 0)); // resize the vector and initialize every tile to 0
for(int i = 0; i < y; i++)
for(int j = 0; j < x; j++)
{
int num = 1;
if(i != j) { // to keep the zero-diagonal
for(int h = 0; h < y; h++)
for(int k = 0; k < x; k++) { // scan the current row and column
if(grid[h][j] == num || grid[i][k] == num) { // if we encounter the current num
num++; // on the same row or column, increment num
h = -1; // scan the same row and column again
break;
}
}
grid[i][j] = num; // assign the smallest number possible to the current tile
}
}
/*for(int i = 0; i < y; i++) { // print the grid
for(int j = 0; j < x; j++) // for debugging
std::cout << grid[i][j] << " "; // reasons
std::cout << std::endl;
}*/
std::cout << grid[y-1][x-1] << std::endl; // print the tile number at the requested coordinates
//system("pause");
return 0;
}
So what should I do? Is this easier than I think it is?
To summarize your question: You have a table where each element is the minimum nonnegative integer that does not appear to its left or above. You need to find the element at position (x,y).
The result is surprisingly simple: If x and y are 0-based, then the element at (x,y) is x XOR y. This matches the table you have posted. I have verified it experimentally for a 200x200 table.
The proof:
It's easy to see that the same number won't appear twice on the same row or column, because if x1^y = x2^y then necessarily x1=x2.
To see that x^y is minimal: Let a be a number smaller than x^y. Let i be the index (from the right) of the leftmost bit where a differs from x^y. The ith bit of a must be 0 and the ith bit of x^y must be 1.
Therefore, either x or y must have 0 in the ith bit. Suppose WLOG it was x that had 0. Represent x and y as:
x = A0B
y = C1D
Where A,B,C,D are sequences of bits, and B and D are i bits long. Since the leftmost bits of a are the same as those in x^y:
a^x = C0E
Where E is a sequence of i bits. So we can see that a^x < y. The value that appered in the (a^x)th row on the same column was: (a^x)^x = a. So the value a must have already appeared in the same row (or column, if it was y that had 0 in the ith bit). This is true for any value smaller than x^y, so x^y is indeed the minimum possible value.
I'm trying to get a specific element inside of a vector.
For example,
Lets say I have a vector.
std::vector<Tile> TileList;
The Vector is of size MAP_HEIGHT = 30, MAP_WIDTH = 200
So its total size is MAP_HEIGHT * MAP_WIDTH = 6000.
I use a double nested for loop to iterate through and create a vector full of tiles.
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
for(int X = 0; X < MAP_WIDTH; X++)
{
Tile TempTile;
fscanf(FileHandle, "%d:%d ", &TempTile.TileID, &TempTile.TypeID);
TileList.push_back(TempTile);
}
}
Now my questions is lets say I iterate through
int ID = 0;
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
for(int X = 0; X < MAP_WIDTH; X++)
{
TileList[ID].do stuff with it
//Check for the tile above this tile
// Find a way to calculate the ID of the tile above this tile
int IDoftilabove = ID - do something;
if(TileList[IDoftilabove].variable == TILE_SOMETHING)
{
do stuff
}
ID++;
}
How do I calculate the ID of an element above(well technically before this ID) inside the vector based on the current element I'm on.
Illustration:
say i have a matrix 5x5,
Lets say my current ID is 8. so I am on the second row number 3.
1 2 *3* 4 5
1 2 (3) 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Now I want the ID of the element in vector that is directly above me which is the ID 3, first row number 3. and this is just assuming the the MAP_WIDTH = 5 and the MAP_HEIGHT = 5.
8 - 5 = 3
Current - MAP_WIDTH = Above
You can easily determine the (row,col) coordinates given the ID:
row = ID / MAP_WIDTH;
col = ID % MAP_WIDTH;
If you want to know what is the coordinate from the element above:
row--;
ID_above = row * MAP_WIDTH + col;
The same applies if you want to know what is the element below:
row++;
ID_below = row * MAP_WIDTH + col;
It seems like you want to map between linear and 2d indices. This is pretty straightforward.
int rect2lin(int w, int x, int y) { return y*w+x; }
void lin2rect(int w, int i, int * x, int * y) { *y = i/w; *x = i%w; }
So in your example, the ID of the element above (X,Y) would be rect2lin(MAP_WIDTH, X,Y-1), which is simply (Y-1)*MAP_WIDTH+X. This generalizes straightforwardly to higher numbers of dimension. For example, i=(z*h+y)*w+x for 3d, and so on.