Printing an struct that includes an 2d array - c++

EDITED
What I am trying to do is (after reading from file and putting the information in 2d array defined in a struct,that part works) call a method that finds out if there is any zeroes in the array and if so change it and prints it again. I know I´m missing pointers but I don't know where. Thanks in advance.
struct matrix{
const static int N=9;
int Ar[N][N];
};
void iprint(matrix s){ //my method to print the array
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
cout << (s).Ar[i][j] << ' ';
}
cout << endl;
}
}
bool annotation(matrix s, int row, int column, int num){
if(s.Ar[row][column] == 0){
(s).Ar[row][column] = num;
return true;
}
else if(s.Ar[row][column] != 0){
cout << "NO" << endl;
return false;
} else {
cout << "No" << endl;
return false;
}
iprint(s);
}
The array in first place :
0 0 6 5 0 0 1 0 0
4 0 0 0 0 2 0 0 9
0 0 0 0 3 0 0 0 8
0 7 0 1 0 0 5 0 0
0 8 0 0 0 0 0 6 0
0 0 3 0 9 0 0 4 0
2 0 0 0 4 0 0 0 0
9 0 0 7 0 0 0 0 3
0 0 5 0 0 8 2 0 0
The output that I get after those methods (calling the method annotation(s,1,1,2); )
2686428 0 0 2686524 8989288 4733208 0 0 -17974607
1 0 4201360 4662484 0 8989288 8989340 9005760 0
.
.
.
Im reading the array from a file,and the method is
bool readMatrix(matrix s){
ifstream f;
f.open("nuMatrix.txt");
if (f.is_open()) {
while(!f.eof()){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
f>>(s).Ar[i][j];
}
}
}
f.close();
iprint(s);
return true;
}
else {
cerr << "NO";
return false;
}
}`

The matrix you're passing to readMatrix and annotation isn't modified by the functions.
You're passing the matrix by value, so you're only modifying a copy of it.
Change your functions to take a reference to a matrix:
bool annotation(matrix& s, int row, int column, int num)
bool readMatrix(matrix& s)

Related

How to make quadtree algorithm

i'm making an algorithm called Quadtree, so i've tried this code that i made but the output is incorrect
input
8 8
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 0 1 1 1 1 0 0
0 0 1 1 1 0 0 0
output
0
the code i've tried
#include <iostream>
#include <string>
using namespace std;
int m[128][128];
int nJawaban;
string jawaban[128*128];
bool homogen(int r, int c, int k) {
int val = m[r][c];
for (int i = r; i < r+k; i++) {
for (int j = c; j < c+k; j++) {
if (m[i][j] != val) {
return false;
}
}
}
return true;
}
// i think it's here
void quadtree(int r, int c, int k, string s){
if (m[r][c] == m[r-1][c-1]) {
if (m[r][c] == 1) {
jawaban[nJawaban] = "1" + s;
nJawaban++;
}
} else {
quadtree(r, c, k/2, s+"0");
quadtree(r, c+(k/2), k/2, s+"1");
quadtree(r, c, r+k-1, s+"0");
quadtree(r, c, r+k-1, s+"1");
}
}
int main(){
int r, c;
scanf("%d %d", &r, &c);
int maxRc = max(r, c);
int pow2 = 1;
while (pow2 < maxRc){
pow2 *= 2;
}
for (int i = 0; i < pow2; i++) {
for (int j = 0; j < pow2; j++) {
m[i][j] = 0;
}
}
for (int i = 0; i < r; i++){
for (int j = 0; j < c; j++){
scanf("%d", &m[i][j]);
}
}
nJawaban = 0;
quadtree(0, 0, pow2, "");
printf("%d\n", nJawaban);
for (int i = 0; i < nJawaban; i++) {
printf("%s\n", jawaban[i].c_str());
}
return 0;
}
input:
8 8
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 0 1 1 1 1 0 0
0 0 1 1 1 0 0 0
expected output:
11
112
113
1211
1212
1213
123
130
131
1320
1321
1322
note: some of the var name is written in indonesian language and i'm trying to make this code without (using namespace std) and also fix the code
i've watched youtube video and reading some stackoverflow answer
https://www.youtube.com/watch?v=xFcQaig5Z2A
Efficient (and well explained) implementation of a Quadtree for 2D collision detection
nevertheless i can't correct my mistake but i can point out where the mistake is. My question here is how to correct this mistake or even provide better algorithm
edit: it's still didn't work

Printing two-dimensional array

I have this two-dimensial array array[y][x] (where x is horizontal and y vertical):
3 2 0 0 0 0 0 0 0 0
1 4 3 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
1 3 0 0 0 0 0 0 0 0
4 2 5 1 0 0 0 0 0 0
1 3 0 0 0 0 0 0 0 0
2 3 0 0 0 0 0 0 0 0
2 3 0 0 0 0 0 0 0 0
And I need to print it like this:
3 1 2 2 1 4 1 2 2
2 4 4 4 3 2 3 3 3
3 5
1
How would I do this using c++?
Note that there are no empty lines. If the whole column only has zero's in them, there shouldn't be an endl
You need to iterate over and print out each element. You can flip the elements around by swapping the indices used to get the value out of the array.
#include<iostream>
#include<iomanip>
int gridWidth = 10;
int gridHeight = 10;
int cellWidth = 2;
for (int i = 0; i < gridHeight; i++){
bool anyVals = false;
for (int j = 0; j < gridWidth; j++){
int val = array[i][j]; //Swap i and j to change the orientation of the output
if(val == 0){
std::cout << std::setw(cellWidth) << " ";
}
else{
anyVals = true;
std::cout << std::setw(cellWidth) << val;
}
}
if(anyVals)
std::cout << std::endl;
}
Remember that if you swap i and j then you will need to swap gridWidth and gridHeight.
Just to avoid confusion std::setw(cellWidth) thing is a convenient way to print fixed-width text (like text that must always be two characters long). It takes whatever you print out and adds spaces to it to make it the right length.
Take the transpose of your matrix , make 2 loops(outer and inner ) and print only if the no is greater than zero and print space for every zero. when you go back again to the outer loop ,print new line .
Something like this should help you.
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
if (array[i][j] != 0)
cout << array[i][j];
else
cout << " ";
cout << endl;

Filling array from file won't work

I have made a 'Map' array and I am attempting to populate it from a 'map' file. On creation I assign the value '0' to each element of the array but the 'Map' file contains the following:
MAP:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I load the map using 'loadMap()'
loadMap():
void room::loadMap()
{
int x=0;
int y=0;
string line;
ifstream mapFile(NAME + "_MAP.txt");
while(!mapFile.eof())
{
for(int i=0; i<cellsY; i++)
{
getline(mapFile,line,'\n');
for(int j=0; j<cellsX; j++)
{
getline(mapFile,line,' ');
map[(cellsX*j) + cellsY] = atoi(line.c_str());
};
};
}
y = 10;
x = 15;
for(int i=0; i<y; i++)
{
cout << endl;
for(int j=0; j<x; j++)
{
cout << map[(x*j) + y];
};
};
}
In this example the elements are still assigned to '0', but I am trying to mimic the Map files layout.
For starters, you never test that any of the input works, nor
that the open succeeded. Then, in the outer loop, you read
a line from the file, and throw it away, before reading further
in the inner loop. And your calcule of the index is wrong.
What you're probably looking for is something like:
std::ifstream mapFile(...);
if ( !mapFile.is_open() ) {
// Error handling...
}
for ( int i = 0; mapFile && i != cellsY; ++ i ) {
std::string line;
if ( std::getline( mapFile, line ) ) {
std::istringstream text( line );
for ( int j = 0; j != cellsX && text >> map[cells X * i + j]; ++ j ) {
}
if ( j != cellsX ) {
// Error: missing elements in line
}
text >> std::ws;
if ( text && text.get() != EOF ) {
// Error: garbage at end of line
}
}
}
For the error handling, the simplest is just to output an
appropriate error message and continue, noting the error so you
can return some sort of error code at the end.
I think this is what you are looking for.
void room::loadMap()
{
int x=0;
int y=0;
ifstream mapFile(NAME + "_MAP.txt");
for(int i=0; i<cellsY; i++)
{
for(int j=0; j<cellsX; j++)
{
int v;
mapFile >> v;
if ( mapFile.eof() )
{
break;
}
map[(cellsX*j) + cellsY] = v;
}
}
y = 10;
x = 15;
for(int i=0; i<y; i++)
{
cout << endl;
for(int j=0; j<x; j++)
{
cout << map[(x*j) + y];
};
};
}

Is there a way to display a matrix of chars as an image?

I should open with the fact that I am very new to c++.
I am attempting to display a constantly updating 20x20 matrix of chars. Currently, I am displaying the the matrix using for loops as cout's (code below) but that is incredibly flickery- I'm looking for something smoother.
Is there a way to convert this char matrix into an image and display that?
This is my first question here, so I apologize if I did something wrong!
Code so far:
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
using namespace std;
int main()
{
int randInt;
//Initialize matrix and location
int matrix[20][20];
int location[2] = {0,0};
for (int i=0; i<20; i++)
{
for (int j=0; j<20; j++)
{
matrix[i][j] = 1;
}
}
//move the X around
for (int i=0; i<100; i++)
{
cout << string(50, '\n');
//Change the X's location
randInt = rand() % 4;
switch (randInt)
{
case 0:
if(location[1] > 0)
location[1] = location[1]-1;
break;
case 1:
if(location[0] < 20)
location[0] = location[0]+1;
break;
case 2:
if(location[1] < 20)
location[1] = location[1]+1;
break;
case 3:
if(location[0] > 0)
location[0] = location[0]-1;
break;
default:
cout << "Switch statement problem";
}
//Display the matrix
for (int x=0; x<20; x++)
{
for (int y=0; y<20; y++)
{
if(x==location[0] && y==location[1])
cout << "X";
else
cout << matrix[x][y];
}
cout << endl;
}
Sleep(100);
}
system ("pause");
return 0;
}
You should rename the location[2] to something like `struct { int x,y; } location for readability.
Then you can build an array of characters in RAM and put out it at once.
int _tmain(int argc, _TCHAR* argv[])
{
char matrix[20][20];
char image[21][21];
struct { int x, y; } location;
int x = 0;
int y = 0;
location.x = 7;
location.y = 3;
// fill the matrix
for (x = 0; x < 20; ++x)
{
for (y = 0; y < 20; ++y)
{
matrix[y][x] = 'a' + x + y;
}
}
// prepare the image
y = 0;
while (y < 20)
{
memcpy(image[y], matrix[y], 20);
image[y][20] = '\n';
++y;
}
// add the cross
image[location.y][location.x] = 'X';
image[20][0] = '\0';
// use the image
puts((char*)image);
}
Please add you random functionality as needed.
If you want to convert the char to a image and see the color means, write the char value as pixel in simple pgm format.
Write a file in this sample format
P2
# feep.pgm
24 7
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
check this link http://netpbm.sourceforge.net/doc/pgm.html for pgm format

Showing 2D array with one element at the time

I have a 2 dimensional array filled with 0s and 1s. I have to display that array in way that:
- 0s are always shown
- 1s are shown one at the time.
It suppose to look like a maze where 0 is a wall and 1 is a current position.
How can I do that in c++?
EDIT:
I came up with a solution but maybe there is simpler one. What if I'd create copy of my _array and copy 0s and blank spaces instead of 1s to it. Then in loop I'd assign one of _array "1" to second array then display whole array and then make swap 1 back with blank space?
EDIT2:
int _tmain(int argc, _TCHAR* argv[])
{
file();
int k=0,l=0;
for(int i=0;i<num_rows;i++)
{
for(int j=0;j<num_chars;j++)
{
if(_array[i][j] == 1)
{
k=i;
l=j;
break;
}
}
}
while(1)
{
for(int i=0;i<num_rows;i++)
{
for(int j=0;j<num_chars;j++)
{
if(_array[i][j] == 0) printf("%d",_array[i][j]);
else if(_array[i][j]==1)
{
if(k==i && l==j)
{
printf("1");
}
else printf(" ");
}
l++;
if(l>num_chars) break;
}
k++;
l=0;
printf("\n");
}
k=0;
system("cls");
}
return 0;
}
I wrote something like that but still i don't know how to clear screen in right moment. Function file() reads from file to 2D array.
Assuming you want something like that
000000
0 0
0000 0
0 1 0
0 0000
000000
You could print a 0 whenever it occurs and a blank space if not. To handle the current position you could use two additional variables like posX, posY. Now everytime you find a 1 in your array you check if (j == posX && i = posY) and print 1 if so...
As you just need to visualize the maze at different possible positions I'd propose a simple display function. DisplayMaze(int x, int y) is printing the maze in the required format to the screen. If _array[y][x] == 1 there is also printed a single 1...
void DisplayMaze(int x, int y)
{
for (int row = 0; row < num_rows; row++)
{
for (int col = 0; col < num_chars; col++)
{
if (_array[row][col] == 0)
std::cout << "0 ";
else if (row == y && col == x)
std::cout << "1 ";
else
std::cout << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
In order to display all possible positions you have to iterate over all of them and check if the current position is marked with 1 in the array (otherwise displaying would't make sense)
for (int y = 0; y < num_rows; y++)
{
for (int x = 0; x < num_chars; x++)
{
if (_array[y][x] == 1)
{
DisplayMaze(x, y);
}
}
}
The output should look like:
0 0 0 0 0 0
0 1 0
0 0 0 0 0
0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 1 0
0 0 0 0 0
0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 1 0
0 0 0 0 0
0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 1 0
0 0 0 0 0
0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0
0 0 0 0 1 0
0 0
0 0 0 0 0
0 0 0 0 0 0
...
However, i'd recommend a more C++ like approach as a maze could be implemented as a class. This class could bring it's own display-method and would encapsulate the internal data. It could basically look like:
class Maze
{
public:
// generate empty maze with given size
Maze(int width, int height);
// destructor
~Maze();
// print maze if the given position is marked with 1
void printPosition(int x, int y) const;
// takes a cstring as input to initialize the maze from
Maze& operator<<(const char* input);
// returns true if the given position is marked with 1
bool isValidPosition(int x, int y) const;
private:
// this is the actual representation of the maze
std::vector<std::vector<int> > grid_;
};
it would be used as followes:
Maze myMaze(num_chars, num_rows);
myMaze << "000000"
"011110"
"000010"
"011110"
"010000"
"000000";
for (int y = 0; y < num_rows; y++)
{
for (int x = 0; x < num_chars; x++)
{
if (myMaze.isValidPosition(x,y))
{
myMaze.printPosition(x,y);
}
}
}
hire you go*[solved]*
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
int x,y;
cin>>x>>y;
char map[x][y];
memset(map, 'a', sizeof(map));
int y_pos = 0;
for (int x_pos = 0; x_pos < x * y; x_pos++){
if (x_pos == x){
x_pos = 0;
y_pos = y_pos + 1;
cout<<endl;
}
if (y_pos == y){
system("pause");
return 0;
}
cout<<map[x_pos][y_pos];
}