printing a 2D array inside a function in c++ - c++

I have made the following program in c++. I just want to print an array elements. My code is as follows:
#include <iostream>
#include <cstdio>
using namespace std;
#define n 5
double dist[n][n];
void read_distances()
{
for(int i = 0; i < n ; i++)
{
for (int j = 0 ;j < n; j++)
{
cout<<dist[i][j]<<" ";
}
cout<<"\n";
}
}
main()
{
double dist[n][n] =
{
{0, 20, 30, 10, 11},
{15, 0, 16, 4, 2},
{3, 5, 0, 2, 4},
{19, 6, 18, 0, 3},
{16, 4, 7, 16, 0}
};
read_distances();
}
I just wanted to print the dist[][] array inside the read_distances() function. But here I am getting all the values 0 as output. what's the reason of this?

The reason is because you declared the dist array in main(), and you initialized its contents, but the function read_distances() prints the values of a global array called dist. It happens to have the same name as the dist array in main()'s scope, but is a completely different array, and it is never initialized.
EDIT: you asked how to make it work. The easiest way is to pass it as a parameter. After removing the global declaration:
void read_distances(double dist[n][n])
{
// ...
}
and then in your main():
read_distances(dist);
(technically, the parameter to read_distances() is actually double (*)[n], but that's going to be a topic for another day and I didn't want to make this too confusing).

How about this:
#include <iostream>
#include <cstdio>
using namespace std;
#define n 5
void read_distances(double dist[n][n])
{
for(int i = 0; i < n ; i++)
{
for (int j = 0 ;j < n; j++)
{
cout<<dist[i][j]<<" ";
}
cout<<"\n";
}
}
int main()
{
double dist[n][n] =
{
{0, 20, 30, 10, 11},
{15, 0, 16, 4, 2},
{3, 5, 0, 2, 4},
{19, 6, 18, 0, 3},
{16, 4, 7, 16, 0}
};
read_distances(dist);
}
Your code doesn't work because you overshadowed the global version of dist with the local one you created at main. So you either not use a global one, like I do here, and pass the one you create at main() to your printing function; or you fill that array without creating a new array in main().

Related

Find unique element in sorted array using c++

I am trying to find unique element from the array these is question
Input : arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5}
Output : arr[] = {1, 2, 3, 4, 5}
They give me correct output but why they give 0 at the end in output:
these is my output:
{1,2,3,4,5,0}
Code:
#include<iostream>
using namespace std;
int main(){
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0;j<=n;j++){
if(arr[j]!=arr[j+1]){
cout<<arr[j];
}
}
}
Except for std::cout, you code is much more C than ++.
std::unique of the C++ Standard Library does exactly what you want. There is no need to re-implement this.
Next there is the erase-remove idiom to delete the superfluous elements.
For the output, you can use std::for_each() or at least a range-based for loop.
And also, you don't want using namespace std;
A more modern solution looks like this:
#include <iostream>
#include <algorithm>
#include <vector>
int main(){
std::vector<int> arr {1, 2, 2, 3, 4, 4, 4, 5, 5};
auto last = std::unique(arr.begin(), arr.end());
arr.erase(last, arr.end());
std::for_each(arr.begin(), arr.end(), [](int n){std::cout << n << std::endl;} );
}
Try it on Godbolt.
problem is in for loop becouse you use less or equal to n.
you need to use just less then n becouse array starts from zero that means you asking for sixth element that do not have alocalizated in memory
now it should be correct
#include<iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0; j<n; j++) {
if (arr[j]!=arr[j+1]) {
cout<<arr[j];
}
}
}

set multiple array variables at the same time (c++)

I'm trying to make an ASCII art using C++, and having some problems in arrays.
Is there any way to set multiple array variables at the same time?
Let me be more specific.
When you initialize an array, you can do this way.
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
By the way shown above, you can set 10 array variables at the same time.
However, I want to (re) set some of the array variables like this?
a[1] = 3;
a[4] = 2;
a[5] = 2;
a[7] = 2;
Since there is NO rule in the variables, I can't do
for(int i=0; i<10; i++) a[i] = i+1;
fill(n);
I can't use an for statement or the fill, fill_n function, since there is no regularity.
To sum up,
Is there any way to set more than 1 array variables at the same time? (Like the second code snipplet above?
Given a index-value mapping list, and assign it one by one.
template<typename T, size_t N>
void Update(T(&arr)[N], const std::vector<std::pair<size_t, T>>& mappings)
{
for (const auto& mapping : mappings)
if(mapping.first < N)
arr[mapping.first] = arr[mapping.second];
}
int main()
{
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Update(arr, { {1, 3}, {4, 2}, {5, 2}, {7, 2} });
return 0;
}
As far as I'm aware without a pattern a control structure is kind of redundant, you might be better served reading from a file.
// for user input
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < 10; i++) {
cout << "Please input your value for array index " << i << endl;
cin >> arr[i];
}
// for manual input in initalization
int arr[10] = { 0, 3, 2, 2, 2, 5, 6, 7, 8, 9 };
However a better approach might be to read it from a file, http://www.cplusplus.com/forum/general/58945/ Read "TheMassiveChipmunk"'s post there for exactly how to do it.
Assuming you know which indices you will be changing upfront you can use a separate index array:
int ind[4]= {1,4,5,7};
..and an accompanying array with values
int new_val[4] = {3,2,2,2};
The you can use the following for loop to assign the values:
for (int i=0; i<4; i++)
arr[ind[i]] = new_val[i];
You should also use some variable signifying the number of indices to be changed like int val_num = 4 instead of plain number 4.
Changes that are defined in runtime to an array can be easily implemented by using a list to save tuples that represent the changes you want to make. As an example, we can write:
#include <tuple>
#include <list>
#include <iostream>
using namespace std;
typedef tuple <int, int> Change;
int main() {
int a[5] = {1,2,3,4,5};
list<Change> changes;
//represents changing the 2-th entry to 8.
Change change(2,8);
changes.push_back(change);
for(auto current_change: changes)
a[get<0>(current_change)] = get<1>(current_change);
cout << a[2] << '\n';
}
Prints 8.

How to make space between array values in printing?

I'm interested, how could i get same result in C++. For this C code:
for(i=0;i<n;i++)
printf("%4d",array[i]);
This will create 4 space gap between my values from array.
Is there something similar in C++?
The same code works in C++:
const int n = 10;
int array[n] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i=0;i<n;i++)
printf("%4d",array[i]);
But if you're looking for more a C++-esque way of doing things, you can use std::cout and std::setw:
#include <iostream> // cout
#include <iomanip> // setw
int main()
{
int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto n : array)
{
std::cout << std::setw(4) << n;
}
}

How do I pass an array to a constructor?

I want to pass an array to a constructor, but only the first value is passed--the rest looks like garbage.
Here's a simplified version of what I'm working on:
#include <iostream>
class board
{
public:
int state[64];
board(int arr[])
{
*state = *arr;
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << state[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
int test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
board b(test);
b.print();
std::cin.get();
return 0;
}
Can someone explain why this doesn't work and how to properly pass an array? Also, I don't want to copy the array. (And do I really have to indent every line by 4 spaces for code? That's pretty tedious.)
In this case it might be best to use a reference to the array:
class board
{
int (&state)[64];
public:
board(int (&arr)[64])
: state(arr)
{}
// initialize use a pointer to an array
board(int (*p)[64])
: state(*p)
{}
void print();
};
A couple of advantages - no copying of the array, and the compiler will enforce that the correct size array is passed in.
The drawbacks are that the array you initialize the board object with needs to live at least as long as the object and any changes made to the array outside of the object are 'reflected' into the object's state. but those drawbacks occur if you use a pointer to the original array as well (basically, only copying the array will eliminate those drawbacks).
One additional drawback is that you can't create the object using a pointer to an array element (which is what array function parameters 'decay' to if the array size isn't provided in the parameter's declaration). For example, if the array is passed through a function parameter that's really a pointer, and you want that function to be able to create a board object referring to that array.
Attempting to pass an array to a function results in passing a pointer to the first element of the array.
You can't assign arrays, and taking a parameter like T[] is the same as T*. So
*state = *arr;
Is dereferencing the pointers to state and arr and assigning the first element of arr to the first element of state.
If what you want to do is copy the values from one array to another, you can use std::copy:
std::copy(arr, arr + 64, state); // this assumes that the array size will
// ALWAYS be 64
Alternatively, you should look at std::array<int>, which behaves exactly like you were assuming arrays behave:
#include <array>
#include <algorithm>
#include <iostream>
class board
{
public:
std::array<int, 64> state;
board(const std::array<int, 64> arr) // or initialiser list : state(arr)
{
state = arr; // we can assign std::arrays
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << state[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
// using this array to initialise the std::array 'test' below
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
std::array<int, 64> test(std::begin(arr), std::end(arr));
board b(test);
b.print();
std::cin.get();
return 0;
}
#include <iostream>
class board
{
public:
int * state; //changed here, you can also use **state
board(int *arr) //changed here
{
state = arr;
}
void print();
};
void board::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << *(state + x + y*8) << " "; //changed here
std::cout << "\n";
}
}
int main()
{
int test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
board b(test);
b.print();
std::cin.get();
return 0;
}
or you can use it as:
class board
{
public:
int state[64];
board(int arr[])
{
for(int i=0;i<64;++i)
state[i] = arr[i];
}
void print();
};
EDIT 1:
stable solution
class board
{
public:
int * state; //changed here, you can also use **state
board(int *arr) //changed here
{
state = new int[64];
for(int i=0;i<64;++i)
state[i] = arr[i];
}
void print();
};
*arr gives the value that is stored at arr[0] . In c++ , the name of the array is a pointer to the first element in the array.
So when you do *state = *arr , you store the value at arr[0] in the variable state.
Now , if you want to pass the array without having to copy each element explicitly , I suggest that you make another array of the same size in the method which you are calling and then pass the name of the array from the caller , in essence :
methodWhereArrayisPassed(int *arrayName)
{
int arrCopy[64];
arrCopy = arrayName;
// Do more stuff here
}
methodWhichPassesArray()
{
// do stuff here
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
methodWhereArrayisPassed(arr);
// do stuff here
}
The name of an array is the address of the first element in it.
Hence the line *state = *arr will set state[0] to arr[0].
Since right now you have defined state as int state[64];, state is const pointer of type int whose address cannot be changed.
You can change it to int *state; and then state = arr will work.
*state = *arr; is using dereferencing, which returns the value at the address of the pointer.
This is the same as state[0] = *arr; because *arr is an int.
See this article for info on pointers. See the deference section.
To solve this problem you want to do this:
for (int i = 0; i < 64; i++) state[i] = arr[i]

recursive solution not working as intended/ running into errors

I'm looking for some help on a problem that I vaguely inquired about before, which is solving 15-peg solitaire recursively. I keep getting strange errors when I compile and run it, most of them say "stack overflow" or that I'm getting a seg fault. This is what I have so far, where "board[15]" represents the 15 peg board, and "moves[36]" represents all of the possible moves that can be made. The recursion is supposed to spot when there is only one peg left.
#include <iostream>
using namespace std;
void solveGame(int a[15], int b[36][3], int c[15][4]);
void chooseMove (int a[15], int b[36][3], int openSpace, int c[15][4]);
int findEmpty (int a[15]);
int pegCount (int a[15]);
bool isPeg (int peg, int a[15]);
int usedVals[15] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int d = 0;
int index = 0;
int main ()
{
int openSpace = 5;
int board[15]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
board[openSpace] = 0;
int alreadyMoved[15][4];
int moves[36][3] = {{0, 1, 3},
{0, 2, 5},
{1, 3, 6},
{1, 4, 8},
{2, 4, 7},
{2, 5, 9},
{3, 6, 10},
{3, 7, 12},
{3, 1, 0},
{3, 4, 5},
{4, 7, 11},
{4, 8, 13},
{5, 9, 14},
{5, 8, 12},
{5, 2, 0},
{5, 4, 3},
{6, 3, 1},
{6, 7, 8},
{7, 4, 2},
{7, 8, 9},
{8, 4, 1},
{8, 7, 6},
{9, 5, 2},
{9, 8, 7},
{10, 6, 3},
{10, 11, 12},
{11, 7, 4},
{11, 12, 13},
{12, 7, 3},
{12, 8, 5},
{12, 11, 10},
{12, 13, 14},
{13, 8, 4},
{13, 12, 11},
{14, 9, 5},
{14, 13, 12}};
solveGame(board, moves, alreadyMoved);
for (int i = 0; i < 13; i++)
cout << alreadyMoved[i][0] << " " << alreadyMoved[i][1] << " " < <alreadyMoved[i][2] << endl;
return 0;
}
// main recursive function
void solveGame (int a[15], int b[36][3], int c[15][4]
{
int empSpace;
int moveIndex;
if (pegCount(a) < 2) {
cout<<"game over"<<endl;
} else {
empSpace = findEmpty(a);
chooseMove(a, b, empSpace, c);
solveGame(a, b, c);
}
}
// supposed to pick a move that is applicable to the board otherwise it find a new move
void chooseMove (int a[15], int b[36][3], int openSpace, int c[15][4])
{
int i = 0;
while (1) {
if (i < 36 && b[i][2] == openSpace && isPeg(b[i][0],a) && isPeg(b[i][1],a)) {
a[b[i][0]] = 0;
a[b[i][1]] = 0;
a[b[i][2]] = 1;
c[d][0] = b[i][0];
c[d][1] = b[i][1];
c[d][2] = b[i][2];
c[d][3] = i;
d++;
index = 0;
for (int v = 0; v < 15; v++)
usedVals[v] = -1;
break;
} else if (i > 35) {
a[b[c[d-1][3]][0]] = 1;
a[b[c[d-1][3]][1]] = 1;
a[b[c[d-1][3]][2]] = 0;
c[d-1][0] = 0;
c[d-1][1] = 0;
c[d-1][2] = 0;
c[d-1][3] = 0;
usedVals[index] = openSpace;
index++;
int newOpen = findEmpty(a);
chooseMove(a, b, newOpen, c);
}
i++;
}
}
// counts the pegs on the board in order to cancel recursion
int pegCount (int a[15])
{
int count = 0;
for (int i = 0; i < 15; i++)
if (a[i] == 1)
count++;
return count;
}
// finds an empty space that hasn't already been found faulty
int findEmpty (int a[15])
{
for (int i = 0; i < 15; i++) {
for(int j = 0; j < 15; j++) {
if(a[i] == 0 && i != usedVals[j] && usedVals[j] > -1)
return i;
}
}
}
// tests if current index is a peg
bool isPeg (int peg, int a[15])
{
return a[peg] == 1;
}
A quick glance shows a lot of potential problems, but I think it probably boils down to the way you are passing arrays. Arrays are passed by reference and not by value, so the recursive function is working with a single copy of the array, which I don't think is what you want. Therefore you are never finding the ending move, which will get you a stackoverflow from unlimited recursion.
Try allocating a new copy of the arrays at each level of recursion. Some people will want you to use new or malloc for this, because they feel an introduction to C++ should be a trial by fire where you have to master memory management to do anything useful. Instead, I would advise you not to use arrays at all; use a collection class that will work properly when passed by value (I think std::vector of POD will do this) and the collection class will create copies of your arrays the way your code seems to expect.
You may also be having a problem of doing a depth-first search in chooseMove, when you really want a breadth-first search.
Stack overfow when using recursivity is pretty common. This is due to the fact that return values for function calls are stored into the stack, and the stack keeps filling as long as function does not return. If the recursivity goes too deep, you end up filling your whole stack and overflowing it, which also causes SEGV.
Usually you get a stack overflow when your exit condition does not work, but here you are also passing your parameters by value, which might overflow your stack even in normal operation.
I suggest you pass your arrays by reference or better in a std::vector. An std::vector is a small object that holds the real data in a heap allocated space. You can even return those.
I also suggest that you start your program in a debugger, that is the simplest and most effective way to find out what exactly is going wrong.