Unable to pass 2D character array to function(C++) - c++

I am trying to pass a 2-D character array to a function however vs code gives me the following error message:
cannot convert 'char ()[3]' to 'char ()[10]'gcc
Here is the code:
#include<string>
using namespace std;
void NodeDetect(char grid[][3], int height, int width)
{
cout << "\nThe grid output:\n";
for(int i = 0; i < height; ++i)
{
for(int j = 0; j < width; ++j)
if(grid[i][j] == '0')
{
cout << '\n' << i << '\t' << j << ", ";
if(grid[i][j + 1] == '0' && (j + 1) < width)//right neighbour
cout << i << '\t' << (j + 1) << ", ";
else if(grid[i][j + 1] == '.' || (j + 1) == width)
cout << "-1 -1, ";
if(grid[i + 1][j] == '0' && (i + 1) < height)//bottom neighbour
cout << (i + 1) << '\t' << j << ", ";
else if(grid[i + 1][j] == '.' || (i + 1) == height)
cout << "-1 -1";
}
cout << '\n';
}
}
int main()
{
string line;
char grid[3][3];
int height, width; //height = rows
cout << "Enter the height and the width:\t";//width = columns
cin >> height >> width;
cout << "\nEnter the strings:\n";
for(int i = 0; i < height; ++i)//initializing the grid
cin >> grid[i];
/*
cout << "\nThe grid:\n";
for(int i = 0; i < height; ++i) //displaying the grid
{
for(int j = 0; j < width; ++j)
cout << grid[i][j] << '\t';
cout << '\n';
}
*/
NodeDetect(grid, height, width);
return 0;
}
I am trying to pass the 2D array grid to the function NodeDetect

If you want to pass a plain old C-array to a function in C++, you have 2 possibilities.
Pass by reference
Pass by pointer
It seems that you want to pass by reference. But you are using the wrong syntax.
Please see:
void function1(int(&m)[3][4]) // For passing array by reference
{}
void function2(int(*m)[3][4]) // For passing array by pointer
{}
int main()
{
int matrix[3][4]; // Define 2 dimensional array
function1(matrix); // Call by reference
function2(&matrix); // Call via pointer
return 0;
}
What you pass to the function is a decayed pointer to array of char.
Simply correct the syntax and it will work.
Additional hint:
Do not use plain C-style arrays in C++. Never. Please use STL containers.

Related

Print 2D array in reverse (C++)

Write a program that reads 12 integers into a 2D integer array with 4 rows and 3 columns. The program then outputs the 2D array in reverse order according to both rows and columns.
Ex: If the input is:
5 7 3
6 4 3
5 6 9
5 2 8
then the output is:
8 2 5
9 6 5
3 4 6
3 7 5
For coding simplicity, output a space after every integer, including the last one on each row.
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
for(i = 0; i < ROWS; i++){
for(j = 0; j < COLS; j++){
cin>>arr[i][j];
}
}
cout << arr[3][2] << " " << arr[3][1] << " " << arr[3][0] << " " << endl;
cout << arr[2][2] << " " << arr[2][1] << " " << arr[2][0] << " "<< endl;
cout << arr[1][2] << " " << arr[1][1] << " " << arr[1][0] << " "<< endl;
cout << arr[0][2] << " " << arr[0][1] << " " << arr[0][0] << " "<< endl;
return 0;
}
I ended up having to hardcode this question because I couldnt find a way to reverse the 2D array with a loop and get it to be outputted in the form of a graph. Is there a way i could reverse the 2D array using for loops and would it be possible to be able to change the amount of rows and columns and still output the corresponding graph of values?
try this:
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
cin >> arr[i][j];
}
}
// output the reversed array
for (int i = ROWS - 1; i >= 0; i--) {
for (int j = COLS - 1; j >= 0; j--) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
You can reverse a 2D array using nested for loops, try
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
// Input the values into the 2D array
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++) {
cin >> arr[i][j];
}
}
// Reverse the rows and columns of the 2D array
for(i = ROWS - 1; i >= 0; i--) {
for(j = COLS - 1; j >= 0; j--) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
As mentioned in comments below if you don't know ROWS and COLS size at compile time dynamically allocate the memory for 2D array(arr) in C++ using new operator.
There is very little point reading the data into a 2D array for this program. A std::vector would do the trick, sized with ROWS * COLS values. You then have the benefit of being able to read those dimensions from the user, which addresses the second part of your question.
size_t size = ROWS * COLS;
// Read data
std::vector<int> data;
data.reserve(size);
for (int value; std::cin >> value; )
{
data.push_back(value);
}
// Validate data
if (data.size() != size)
{
std::cerr << "Unexpected end of input!\n";
return EXIT_FAILURE;
}
When outputting, you can use a reverse iterator through the vector, and simply write a newline every COLS values.
// Output in reverse
int col = 0;
for (auto it = data.rbegin(); it != data.rend(); it++)
{
std::cout << *it << " ";
if (++col == COLS)
{
std::cout << "\n";
col = 0;
}
}
You can even easily fix the "space at the end of the line" problem by adjusting your output loop as follows:
// Output in reverse
int col = 0;
for (auto it = data.rbegin(); it != data.rend(); it++)
{
std::cout << *it;
if (++col == COLS)
{
std::cout << "\n";
col = 0;
}
else
{
std::cout << " ";
}
}

Solving Knapsack using recursive algorithm

So, I am trying to implement this algorithm from our textbook.
I wrote this :
// Knapsack_memoryfunc.cpp : Defines the entry point for the console application.
//Solving Knapsack problem using dynamic programmig and Memory function
#include "stdafx.h"
#include "iostream"
#include "iomanip"
using namespace std;
int table[20][20] = { 0 };
int value, n, wt[20], val[20], max_wt;
// ---CONCERNED FUNCTION-----
int MNSack(int i, int j)
{
value = 0;
if (table[i][j] < 0)
if (j < wt[i])
value = MNSack(i - 1, j);
else
value = fmax(MNSack(i - 1, j), val[i] + MNSack(i - 1, j - wt[i]));
table[i][j] = value;
return table[i][j];
}
// --------------------------
void items_picked(int n, int max_wt)
{
cout << "\n Items picked : " << endl;
while (n > 0)
{
if (table[n][max_wt] == table[n - 1][max_wt]) // if value doesnot change in table column-wise, item isn't selected
n--; // n-- goes to next item
else // if it changes, it is selected
{
cout << " Item " << n << endl;
max_wt -= wt[n]; // removing weight from total available (max_wt)
n--; // next item
}
}
}
int main()
{
cout << " Enter the number of items : ";
cin >> n;
cout << " Enter the Maximum weight : ";
cin >> max_wt;
cout << endl;
for (int i = 1; i <= n; i++)
{
cout << " Enter weight and value of item " << i << " : ";
cin >> wt[i] >> val[i];
}
for (int i = 0; i <= n; i++)
for (int j = 0; j <= max_wt; j++)
table[i][j] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= max_wt; j++)
table[i][j] = -1;
cout << " Optimum value : " << MNSack(n, max_wt);
cout << " \n Table : \n";
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= max_wt; j++)
if (table[i][j] == -1)
cout << setw(5) << "-";
else
cout << setw(5) << table[i][j];
cout << endl;
}
items_picked(n, max_wt);
return 0;
}
Here is the question and output :
It seems like its correct on some places like optimum value, yet isn't fully acceptable.
I've tried to debug it, but its quite hard with recursive functions. Can someone please help?
int MNSack(int i, int j)
{
value = 0;
if (table[i][j] < 0)
{
if (j < wt[i])
value = MNSack(i - 1, j);
else
value = max(MNSack(i - 1, j), val[i] + MNSack(i - 1, j - wt[i]));
table[i][j] = value;
}
return table[i][j];
}
The problem comes in here. When your table item is greater or equal to 0, you will skip the recursion but still set the table item to 0, which won't be right if your table item is greater than 0.
You only need to update the table item when it needs to be change, so put it in the braces will correct this.
The bottom up solution.
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
int main()
{
int table[20][20] = { 0 };
int value, n, wt[20], val[20], max_wt;
cout << " Enter the number of items : ";
cin >> n;
cout << " Enter the Maximum weight : ";
cin >> max_wt;
cout << endl;
for (int i = 1; i <= n; i++)
{
cout << " Enter weight and value of item " << i << " : ";
cin >> wt[i] >> val[i];
}
// Initialization
for (int i = 0; i <= n; i++)
for (int j = 0; j <= max_wt; j++)
table[i][j] = 0;
// In practice, this can be skipped in a bottom up solution
for (int i = 1; i <= n; i++)
for (int j = 1; j <= max_wt; j++)
table[i][j] = -1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= max_wt; j++)
{
if (j < wt[i])
table[i][j] = table[i - 1][j];
else
table[i][j] = max(table[i - 1][j], val[i] + table[i - 1][j - wt[i]]);
}
}
cout << " Optimum value : " << table[n][max_wt] << endl;
cout << " \n Table : \n";
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= max_wt; j++)
if (table[i][j] == -1)
cout << setw(5) << "-";
else
cout << setw(5) << table[i][j];
cout << endl;
}
return 0;
}
You can see that this changes the recursion to a loop, and therefore avoids the global variables. It also makes the code simpler, so that you can avoid checking if the table item is valid (equal to -1 in your example).
The drawback of this solution is, it always traverses all the possible nodes. But it gains better coefficient per item because the recursion and double checking the table item costs more. Both top-down and bottom-up have the same order of complexity O(n^2), and it's hard to tell which one is faster.

Simple C++ Program with Multidimensional Array Errors?

When running the following code, I am attempting to update a Tic Tac Toe game board.
When you type in 3 as a column, it sets 2 X's or O's in the game board.
Here is an example of the output
* * *
* * *
* * *
X: Select a Row: 1
X: Select a Col: 3
* * X
X * *
* * *
Here is the desired output
* * *
* * *
* * *
X: Select a Row: 1
X: Select a Col: 3
* * X
* * *
* * *
Here is the code
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int rowSelect = 0;
int colSelect = 0;
char turn = 'X';
char rowcol[2][2];
for(int i=0; i < 3; i++)
{
for(int j=0; j < 3; j++)
{
rowcol[i][j] = '*';
}
}
for(int i=0; i < 3; i++)
{
for(int j=0; j < 3; j++)
{
cout << rowcol[i][j] << " ";
}
cout << endl;
}
cout << endl;
while (true)
{
cout << turn << ": Select a Row: ";
cin >> rowSelect;
while (rowSelect < 1 || rowSelect > 3)
{
cout << "I cannot accept that value, try again!" << endl;
cout << endl;
cout << turn << ": Select a Row: ";
cin >> rowSelect;
}
cout << turn << ": Select a Col: ";
cin >> colSelect;
while (colSelect < 1 || colSelect > 3)
{
cout << "I cannot accept that value, try again!" << endl;
cout << endl;
cout << turn << ": Select a Col: " << endl;
cin >> colSelect;
}
rowcol[rowSelect-1][colSelect-1] = turn;
if (turn == 'X')
{
turn = 'O';
}
else
{
turn = 'X';
}
for(int i=0; i < 3; i++)
{
for(int j=0; j < 3; j++)
{
cout << rowcol[i][j] << " ";
}
cout << endl;
}
}
system("PAUSE");
return 0;
}
Thanks!
-Mike
The problem is the array. Although arrays are accessed using zero based indices, the definition requires the actual number of elements for which to reserve space.
You defined rowcol as:
char rowcol[2][2]; // This defines a 2 x 2 array
You should have defined rowcol as:
char rowcol[3][3]; // This defines a 3 x 3 array
Hope this helps!
Keith
Your rowcol array needs to be 3x3:
char rowcol[3][3];
char rowcol[2][2];
In all the cases, i, j must iterate only until < 2 since it is a 2x2 array.
Your array only holds 2 elements per row, while your loop runs through three rows and three columns. You seem to be confused on how arrays are numbered, an array with 2 elements would be accessed using elements[0] and elements[1], because 0 is the first number in programming(not 1). you need to declare an array of THREE elements, and access them using [0] [1] and [2].
FIX: change to char Array[3][3];

Error on the result vector

My problem is that when I make the multiplication it only multiplies the the first row of the matrix with the first element of the vector and the next elements makes them zero so the result vector gives a wrong result.
using namespace std;
#define N 100
#define F 3
#define X 7
__global__ void matvec(int *MAT, int *VEC, int *SOL) {
int bx = blockIdx.x;
int tx = threadIdx.x;
int i = 32*bx+tx;
for (int j = 0; j < X; j++) {
SOL[i] = ((MAT[i * X + j] * VEC[j]) +SOL[i]) % 2;
}
}
int main () {
int i, j;
int MAT[N][N], VEC[N], SOL[N];
int *MAT_dev, *VEC_dev, *SOL_dev;
size_t nBytes = X * X * sizeof(int);
cout << "\t- - - - - MATRIX - - - - -\n\n";
for (i = 0; i < X; i++) {
for (j = 0; j < X; j++) {
cout << "Element [" << i << "][" << j << "]: ";
cin >> MAT[i][j];
}
}
cout << endl << endl;
for (i = 0; i < X; i++) {
for (j = 0; j < X; j++) {
cout << MAT[i][j] << " ";
if (j == (X - 1))
cout << endl;
}
}
cout << endl << endl;
cout << "\t- - - - - VECTOR - - - - -\n\n";
for (i = 0; i < X; i++) {
cout << "Element [" << i << "]: ";
cin >> VEC[i];
}
cout << endl << endl;
for (i = 0; i < X; i++) {
cout << VEC[i] << " ";
}
cout << endl << endl;
cudaMalloc((void**)&MAT_dev, nBytes);
cudaMalloc((void**)&VEC_dev, nBytes);
cudaMalloc((void**)&SOL_dev, nBytes);
cudaMemcpy(MAT_dev, MAT, nBytes, cudaMemcpyHostToDevice);
cudaMemcpy(VEC_dev, VEC, nBytes, cudaMemcpyHostToDevice);
dim3 dimBlock(X,X);
dim3 dimGrid(1,1);
matvec<<<dimGrid,dimBlock>>>(MAT_dev, VEC_dev, SOL_dev);
cudaMemcpy(SOL, SOL_dev, nBytes, cudaMemcpyDeviceToHost);
cout << "\t- - - - - RESULT - - - - -\n\n";
for (i = 0; i < X; i++)
{
cout << SOL[i] << " ";
}
cout << endl << endl;
cudaFree(MAT_dev);
cudaFree(VEC_dev);
cudaFree(SOL_dev);
system("PAUSE");
return 0;
}
Thanks for the help
This is because the size of MAT is much larger than it should be. Basically you need N == X, which shouldn't be a problem because both are known at compile time. Memory for a 2D array is laid out in a single contiguous block, row major for C--so in your case the first row corresponds to the first 400 (sizeof(int)*N) bytes, the second row to the second 400, etc. The length of the row is called the 'stride' However, cudaMemcpy has no idea what the stride is or which elements of MAT have been filled in, it just copies the first nBytes bytes from MAT into MAT_DEV. Since nBytes is sizeof(int)*X*X and X == 7 << N the second and subsequent rows of your matrix never get copied. Only the first 196 bytes from the MAT get copied, explaining why your second row is all zeros.

Print array 3 lines

I am trying to print this array of 9 elements out in 3 lines.
I want to print it out in 3 lines with 3 rows such as .
xxx
xxx
xxx
But i am not sure how to tackle that.
void ticTacToeBoard ()
{
for (int i = 0; i < 9; i++)
{
cout << ticTacBoard[i] << " ";
}
}
I like to be verbose with my loops, so try this:
void ticTacToeBoard ()
{
for (int y = 0; y < 3; y++)
{
for (int x = 0; i < 3; x++)
{
cout << ticTacBoard[3 * y + x] << " ";
}
cout << endl;
}
}
Basically, I iterate over your board in rows (y), and then in columns (x), allowing me to print each cell and control the flow.
I just print a newline (endl) after each row.
Change ticTacBoard to a two dimensional array and do
using namespace std;
int main()
{
int ticTacBoard[3][3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << ticTacBoard[i][j] << " ";
}
cout << endl;
}
return 0;
}
A two dimensional array will be easier to understand.
Use the modulo operator to detect every third iteration. Then print a newline.
void ticTacToeBoard ()
{
for (int i = 0; i < 9; i++)
{
cout << ticTacBoard[i] << " ";
if((i + 1) % 3 == 0) {
cout << endl;
}
}
}
You can switch frot the offset in a single-dimensional array (say i) to the offset in a bi-dimensional via this simple formula:
row = i div width
column = i mod width
So, basically:
for(int i = 0; i < 9; i++) {
cout << ticTacBoard[i];
if(i % 3 == 2)
cout << endl;
else
cout << ' ';
}