2D array as parameter in c++ - c++

I would like to pass a 2D array to another function. I have an example of my code that I have all in the main function. However, the assignment requires that we split the code into a total of three functions, the main, adjmatrix, and adjlist functions.
All in the main function
#include<iostream>
#include<fstream>
using namespace std;
int main(void)
{
ifstream in;
char infile[40];
int c, u, v;
cout << "Please enter the input data file name(NO SPACES): ";
cin >> infile;
in.open(infile);
while(in.fail()) {
cout << "Please enter a CORRECT input data file name(NO SPACES): ";
cin >> infile;
in.open(infile);
}
//adj matrix
cout << "Adjacency Matrix" << endl;
in >> c;
int array[c][c];
for(int i=0; i<c; i++) {
for(int j=0; j<c; j++) {
array[i][j] = 0;
}
}
while(in >> u >> v) {
array[u][v] = 1;
}
cout << c << endl;
for(int i=0;i<c;i++) {
cout << i << " ";
for(int j=0;j<c;j++){
cout << array[i][j] << " ";
}
cout << endl;
}
cout << endl;
//adj list
cout << "Adjacency List" << endl;
cout << c << endl;
for(int i=0;i<c;i++) {
cout << i << " --> ";
for(int j=0;j<c;j++) {
if(array[i][j] == 1) {
cout << j << " ";
}
}
cout << endl;
}
in.close();
return 0;
}
This program outputs an adjacency matrix and adjacency list from the following input file
9
2 8
0 6
8 5
2 4
3 1
2 3
4 1
6 1
2 6
7 5
1 7
The following is the output
Adjacency Matrix
9
0 0 0 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0 1 0
2 0 0 0 1 1 0 1 0 1
3 0 1 0 0 0 0 0 0 0
4 0 1 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0
6 0 1 0 0 0 0 0 0 0
7 0 0 0 0 0 1 0 0 0
8 0 0 0 0 0 1 0 0 0
Adjacency List
9
0 --> 6
1 --> 7
2 --> 3 4 6 8
3 --> 1
4 --> 1
5 -->
6 --> 1
7 --> 5
8 --> 5
I read somewhere that passing a 2D array requires the second dimension to be entered. I also read something about it having to be a global constant? So I may have gotten a little crazy and went off on the crazy path on trying some things so please excuse some of the stupidity. The problem I think I am having is the actual array size comes from the file so I dont really understand where to go for declaring an array's second dimension with an actual value when int c is initialized to the first value in the input file. The following is my failed attempt at passing a 2D array. Enjoy:
#include<iostream>
#include<fstream>
using namespace std;
const int c;
void adjmatrix(istream &in, int array[][c]);
int main(void)
{
ifstream in;
char infile[40];
cout << "Please enter the input data file name(NO SPACES): ";
cin >> infile;
in.open(infile);
while(in.fail()) {
cout << "Please enter a CORRECT input data file name(NO SPACES): ";
cin >> infile;
in.open(infile);
}
in >> c;
int array[c][c];
adjmatrix(in, array);
in.close();
return 0;
}
void adjmatrix(istream &in, int array[][c])
{
int u,v;
for(int i=0; i<c; i++) {
for(int j=0; j<c; j++) {
array[i][j] = 0;
}
}
while(in >> u >> v) {
array[u][v] = 1;
}
cout << c << endl;
for(int i=0; i<c; i++) {
cout << i << " ";
for(int j=0; j<c; j++) {
cout << array[i][j] << " ";
}
cout << endl;
}
cout << endl;
}

You can allocate the array dynamically instead of statically defining it.
int i;
int **array;
in >> c;
array = new int*[c];
for(i=0;i<c;i++)
array[i] = new int[c];
adjmatrix(in, array,c);
The declaration of the function adjmatrix will be adjmatrix(istream &in, int **array,int c);

Following may help:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
void print_adjacency_matrix(const std::vector<std::vector<int>>& mat)
{
std::cout << "Adjacency Matrix" << std::endl;
std::cout << mat.size() << std::endl;
for(std::size_t i = 0; i != mat.size(); ++i) {
std::cout << i << " ";
for(auto e : mat[i]) {
std::cout << e << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
void print_adjacency_list(const std::vector<std::vector<int>>& mat)
{
std::cout << "Adjacency List" << std::endl;
std::cout << mat.size() << std::endl;
for (std::size_t i = 0; i != mat.size(); ++i) {
std::cout << i << " --> ";
for(auto e : mat[i]) {
if (e == 1) {
std::cout << e << " ";
}
}
std::cout << std::endl;
}
}
int main()
{
std::ifstream in;
std::string infile;
std::cout << "Please enter the input data file name(NO SPACES): ";
std::cin >> infile;
in.open(infile);
while(in.fail()) {
std::cout << "Please enter a CORRECT input data file name(NO SPACES): ";
std::cin >> infile;
in.open(infile);
}
int c;
in >> c;
std::vector<std::vector<int> > array(c, std::vector<int>(c));
int u, v;
while(in >> u >> v) {
array[u][v] = 1;
}
in.close();
print_adjacency_matrix(array);
print_adjacency_list(array);
return 0;
}

Related

C++ array with random counts

I am stuck somewhere(have some problem with the random number) and I know it, but can't find where to fix...
Two void functions must be used; void randomNumbers(int numbers[][3], int rowSize), void randomCounts(int numbers[][3], int size, int counts[])
I can't put images to show how it should and does look like in .exe files as I just signed up today ...... Hope this works ;(
Expected Result:
//========================
// 7 6 5
// 2 1 1
// 6 7 2
// 9 3 3
// 8 1 1
//========================
//Ran. Number: 0 1 2 3 4 5 6 7 8 9
//Frequency(Counts): 0 4 2 2 0 1 2 2 1 1
What I DID:
//========================
// 0 0 0
// 0 0 0
// 0 0 0
// 0 0 0
// 0 0 0
// ========================
// Ran. Number: 0 1 2 3 4 5 6 7 8 9
// Frequency(Counts): 001A148D
Code:
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
const int COL = 3;
const int SIZE = 5;
void randomNumbers(int inumbers[][3], int rowSize) {
int num = 0;
for (int i = 0; i < 10; i++) {
num = rand() % 10;
}
}
void randomCounts(int inumbers[][3], int size, int counts[]) {
for (int i = 0; i < 10; i++) {
counts[i]++;
cout << setw(5) << counts[i];
}
}
int main(){
int random[SIZE][COL] = {};
srand((unsigned)time(NULL));
cout << endl;
cout << "==================" << endl;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < COL; j++) {
cout << setw(5) << random[i][j];
if (j == COL - 1) {
cout << endl;
}
}
}
cout << "==================" << endl;
cout << endl;
cout << "Ran. Number: " << setw(5) << "0" << setw(5) << "1" << setw(5) << "2" << setw(5) << "3" << setw(5) << "4" << setw(5) << "5" << setw(5) << "6" << setw(5) << "7" << setw(5) << "8" << setw(5) << "9" << endl;
cout << "Frequency(Counts): " << randomCounts << endl;
return 0;
}
Ok, so why are you getting 0, 0, 0.... Because you never actually call your functions. You initialize your array:
int random[SIZE][COL] = {};
Then you print it here:
cout << setw(5) << random[i][j];
And nowhere in between do you set anything into this array. When you do start calling your functions you will find they don't work, due to copying the input and doing some undefined behaviour. When you have debugged this a bit more, ask a new question.

Arrange the array of elements 0, 1, and 2 so that the array places all 0 in the first places, then all 1s and 2 as last

I need to Write a C ++ program that prompts the user to enter 10 integers in the array.
Input numbers are: 0, 1 or 2.
The program should extract the array that is entered on the screen Arrange the array of elements 0, 1, and 2 so that the array places all 0 in the first places, then all 1s
and all 2 as the last.
Arranged array displays on the screen.
Have been struggling over this for few hours now. Im stuck and dont know how to show Output .
Input should be for example 0 0 1 0 1 2 2 2 0 1
Output 0000111222
HOW?
int main ()
{
int t [N], i, ;
cout << "Enter 10 arrays from 0-2" << endl;
cout << "Original array:";
for (i = 0; i <N; i ++)
{
cin >> t [i];
}
if (t [i]> = 0 && t [i] <= 2)
{
cout << "Rearranging elements of array:" << ? << endl;
}
cout << "End of the program!"
return 0;
}
when you do
if (t [i]> = 0 && t [i] <= 2)
i equals N so you access out of the array, and of course that does not sort the array
You do not check if cin >> t[i] success so if the user enter something else than an int all the entries from the current will not be set (they will be 0 in case you use a std::vector)
A first way is to do without taking account the range 0..2, replace int t[n] by std::vector<int> t(N) and use sort(t.begin(), t.end()) to sort your array
The complexity is O(N*log(N)) (here N is 10)
For instance :
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 10
int main ()
{
vector<int> t(N);
size_t i; // size_t the right type for an index
cout << "Enter 10 values in range 0..2" << endl;
for (i = 0; i < N; ++i)
{
for (;;) {
cout << "value #" << i << ':';
if (!(cin >> t[i])) {
cerr << "not a number" << endl;
cin.clear(); // raz error
string s;
cin >> s; // skip bad input
}
else if ((t[i] < 0) || (t[i] > 2))
cerr << "value out of range" << endl;
else
break;
}
}
cout << "Original array:";
for (i = 0; i < N; ++i) cout << ' ' << t[i]; // old way to do
cout << endl;
sort(t.begin(), t.end());
cout << "Sorted array:";
for (auto v : t) cout << ' ' << v; // new way to do
cout << endl;
cout << "End of the program!" << endl;
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ -pedantic -Wextra -Wall s.cc
pi#raspberrypi:/tmp $ ./a.out
Enter 10 values in range 0..2
value #0:aze
not a number
value #0:-2
value out of range
value #0:3
value out of range
value #0:2
value #1:0
value #2:1
value #3:2
value #4:0
value #5:2
value #6:1
value #7:0
value #8:0
value #9:1
Original array: 2 0 1 2 0 2 1 0 0 1
Sorted array: 0 0 0 0 1 1 1 2 2 2
End of the program!
A second way considering a range [min .. max] not too large is to count the number of each value then fill the array to respect these counts
The complexity is O(2N) (here N is 10)
For instance :
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
#define MIN 0
#define MAX 2
#define N 10
int main ()
{
vector<int> t(N);
size_t i; // size_t the right type for an index
cout << "Enter 10 values in range " << MIN << ".." << MAX << endl;
for (i = 0; i < N; ++i)
{
for (;;) {
cout << "value #" << i << ':';
if (!(cin >> t[i])) {
cerr << "not a number" << endl;
cin.clear(); // raz error
string s;
cin >> s; // skip bad input
}
else if ((t[i] < MIN) || (t[i] > MAX))
cerr << "value out of range" << endl;
else
break;
}
}
cout << "Original array:";
for (auto v : t) cout << ' ' << v;
cout << endl;
// count numbers
vector<size_t> counts(MAX - MIN + 1);
for (auto v : t) counts[v - MIN] += 1;
// fill again
i = 0;
for (int r = MIN; r <= MAX; ++r) {
size_t n = counts[r - MIN];
while (n--) t[i++] = r;
}
cout << "Sorted array:";
for (auto v : t) cout << ' ' << v;
cout << endl;
cout << "End of the program!" << endl;
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ -pedantic -Wextra -Wall s2.cc
pi#raspberrypi:/tmp $ ./a.out
Enter 10 values in range 0..2
value #0:a
not a number
value #0:3
value out of range
value #0:0
value #1:2
value #2:1
value #3:1
value #4:2
value #5:2
value #6:2
value #7:0
value #8:1
value #9:2
Original array: 0 2 1 1 2 2 2 0 1 2
Sorted array: 0 0 1 1 1 2 2 2 2 2
End of the program!
Specifically for values between 0 and 2 (in fact for 3 possible values) as said in a remark by #PaulMcKenzie you can use the Dutch national flag problem and look at that question : R G B element array swap
The complexity is O(N) (here N is 10)
As a beginner, you may want to try this (this is the simplest solution I could think of without using other libraries):
int main () {
const int size = 10;
int arr[size], temp = 0;
for (int i = 0; i < size; i++) {
cin >> arr[i];
}
for (int j = 0; j < size - 1; j++) {
for (int k = 0; k < size - j - 1; k++) {
if(arr[k] > arr[k+1]) {
temp = arr[k];
arr[k] = arr[k+1];
arr[k+1] = temp;
}
else
continue;
}
}
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
return 0;
}
I hope this helps you.
1st answer is too difficult for me, im only beginner not knowing what im doing yet.
2nd answer is to that direction where it should be right but i need to put in that input cant be more than 2 or less than numeber 0, thats the problem now :D
Im sorry, i just cant get to that point where i understand that syntax.

How to make an output file of n*n matrix,by taking n from the user, with the numbers generated in pairs?

Currently I have a pre-made 6X6 matrix in a text file like this:
2 6 3 1 0 4
4 2 7 7 2 8
4 7 3 2 5 1
7 6 5 1 1 0
8 4 6 0 0 6
1 3 1 8 3 8
and I made a code that is reading from a file i have made. However I want to have user make a grid for themselves (i.e. 3X3 or 10X10). Which then writes to a text file automatically like in similar fashion and then have that read-in instead. It is a basic memory match card game, so I need to have rand() which generates equal pair so the game can be over when every pair in the grid has been found. Thank you so much for your time!
/*Here are the snippets of my code*/
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
#include <numeric>
#include <limits>
using namespace std;
//global 2d vectors that are associated with the game
vector<vector<int> > game_grid;
vector<vector<int> > hidden_grid;
vector <vector<int> > guessed;
void initialize_grid() {
ifstream input_file;
input_file.open("grid.txt");
int num;
if (input_file) {
for (int i = 0; i < 6; ++i) {
vector<int> row; // game grid
vector<int> row2; // hidden grid
vector<int> row3; // guessed grid
for (int j = 0; j < 6; ++j) {
if (input_file >> num)
row.push_back(num);
row2.push_back(-1);
row3.push_back(0);
}
game_grid.push_back(row);
hidden_grid.push_back(row2);
guessed.push_back(row3);
}
cout << "Get is ready, Challenger!" << endl << endl;
}
else {
cout << "Womp. File open failed!";
}
return;
}
void print_grid() {
cout << "Game grid" << endl;
cout << " -------------------------" << endl;
for (int i = 0; i < 6; ++i) {
cout << " | ";
for (int j = 0; j < 6; ++j) {
cout << game_grid[i][j] << " | ";
}
cout << endl << " -------------------------" << endl;
}
cout << endl;
}
void print_hidden_grid(int r1 = -1, int r2 = -1, int c1 = -1, int c2 = -1) {
cout << "Attempt:" << endl;
if (r1 != -1) {
hidden_grid[r1][c1] = game_grid[r1][c1];
}
if (r2 != -1) {
hidden_grid[r2][c2] = game_grid[r2][c2];
}
for (int i = 0; i < 6; ++i) {
cout << " | ";
for (int j = 0; j < 6; ++j) {
if (hidden_grid[i][j] > -1)
cout << hidden_grid[i][j] << " | ";
else
cout << " | ";
}
cout << endl << " -------------------------" << endl;
}
cout << endl;
if (r1 != -1) {
if (game_grid[r1][c1] == game_grid[r2][c2]) {
guessed[r1][c1] = 1;
guessed[r2][c2] = 1;
cout << "You have a match!" << endl << endl;
}
else {
hidden_grid[r1][c1] = -1;
hidden_grid[r2][c2] = -1;
}
}
cout << endl << endl;
}
void print_current_grid() {
cout << "Current Grid:" << endl;
cout << " -------------------------" << endl;
for (int i = 0; i < 6; ++i) {
cout << " | ";
for (int j = 0; j < 6; ++j) {
if (hidden_grid[i][j] > -1)
cout << hidden_grid[i][j] << " | ";
else
cout << " | ";
}
cout << endl << " -------------------------" << endl;
}
cout << endl << endl;
}
.......
If I well understand you want to auto detect the size of the matrix when you read it ? If yes you can do something like that in initialize_grid :
void initialize_grid() {
ifstream input_file;
input_file.open("grid.txt");
int num;
if (input_file) {
// detect size
int size = 0;
string line;
if (!getline(input_file, line))
return;
istringstream iss(line);
while (iss >> num)
size += 1;
input_file.clear();
input_file.seekg(0);
for (int i = 0; i < size; ++i) {
vector<int> row; // game grid
vector<int> row2; // hidden grid
vector<int> row3; // guessed grid
for (int j = 0; j < size; ++j) {
if (input_file >> num)
row.push_back(num);
row2.push_back(-1);
row3.push_back(0);
}
game_grid.push_back(row);
hidden_grid.push_back(row2);
guessed.push_back(row3);
}
cout << "Get is ready, Challenger!" << endl << endl;
}
else {
cout << "Womp. File open failed!";
}
}
and else where you replace 6 by game_grid.size() (using size_t rather than int to type the indexes)

Moving elements in an array by certain amount

So I have a program that reads in a certain number of keys. An example would be
5 1 10 21 9 6 21 11 13 16 20
The text file example would be
Java 2 linux 3 fear 0 pool 2 do 0 red 1 lock. 1 I 0 random 2
I want my program to start at Java and depending on first key, which in this case is 5, would move over 5 elements leading to "red". And so on and so on. However, I have managed to read in all the data and put them into arrays, I am just having trouble figuring out how to move the pointer in the array.
Code:
#include <iostream>
#include <fstream>
using namespace std;
struct pieces {
char word[5];
int jump;
} ;
// Main Function
int main ()
{
// declare variables
int wordCount[2];
int keyCount[2];
int numKeys, numKeys2;
int numWords;
int keyAmount = 1;
int wordAmount = 23;
int keyarr[11];
pieces cypher[wordAmount];
char filename[10];
ifstream inData;
int temp[10];
//prompt user for input file
cout << " Enter file name: ";
cin >> filename;
inData.open(filename);
if(inData.is_open());
{
// read in data
for ( numKeys = numWords = 0; numKeys < keyAmount; numKeys++){
// read in num of words and keys
inData >> wordCount[numKeys] >> keyCount[numKeys];
//read in words followed by jump key
for( numWords = 0; numWords < wordAmount; numWords++){
inData >> cypher[numWords].word >> cypher[numWords].jump;
}
// read in the actual keys
for( numKeys2 = 0; numKeys2 < wordCount[numKeys]; numKeys2++){
inData >> keyarr[numKeys2];
}
}
//print out data
for( int j = 0; j < numKeys; j++){
cout << wordCount[j] << "\n";
cout << keyCount[j] << "\n";
}
cout << "\n";
for ( int i = 0; i < wordAmount; ++i){
cout << cypher[i].word << " ";
cout << cypher[i].jump << " ";
}
cout << "\nKeys: " << "\n";
for(int k = 0; k < 11; k++){
cout << keyarr[k] << " ";
}
cout << "\n";
}
inData.close();
return 0;
}

storing data from .txt as column vectors in c++

My input .txt looks as follows:
6 3
0 1 5
0 2 1
0 5 53
From the second line onwards I want to store the columns in arrays, so I did the following:
main(int argc, char** argv)
{
std::ifstream infile("instance1.txt");
int NumOne, NumTwo;
if (infile.good()){
infile >> NumOne >> NumTwo;
}
int Array1[NumTwo];
int Array2[NumTwo];
int Array3[NumTwo];
for(int i = 1; i < NumTwo + 1; i++){
infile >> Array1[i-1] >> Array2[i-1] >> Array3[i-1];
}
infile.close();
cout<<"first number"<<NumOne<<endl;
cout<<"second number"<<NumTwo<<endl;
for (int i=0; i < sizeof(Array1); i++){
cout << Array1[i] << " " << Array2[i] << " " << Array3[i] << endl;
}
cout<<"first array"<<Array1<<endl;
cout<<"second array"<< Array2<<endl;
cout<<"third array"<< Array3<<endl;
}
My output is the following:
first number6
second number5
0 1606413088 0
0 1 5
0 2 1
0 5 53
6923 5 1606414340
1 0 32767
1606673872 0 1606413088
32767 0 1
1606594089 0 2
32767 0 5
0 1 4
65793 2 5
80256 6923 5
0 1 0
80256 1606673872 0
0 32767 0
17623816 1606594089 0
1 32767 0
first array10x7fff5fbfeb10
second array20x7fff5fbfeaf0
third array0x7fff5fbfead0
Does anyone know where these numbers come from? I'm new to C++ and appreciate any hints about what goes wrong here.
I am not sure how this code already compiled but:
Issue One:
cout<<"first array"<<Array1<<endl;
cout<<"second array"<< Array2<<endl;
cout<<"third array"<< Array3<<endl;
I think this will display the hexadecimal address of each array, since you didn't type which element Array[?] in every array you are tying to display.
Issue Two:
for(int i = 1; i < NumOne + 1; i++){
infile >> Array1[i-1] >> Array2[i-1] >> Array3[i-1];
This code will set junk data, since it's going to try reading NumOne + 1 means 6 + 1 = 7 lines as max while you only have 3 lines. So what are you trying to do here?
Issue Three:
you need to set a fixed size before declaring any array. So int Numone = ? or Array[?]
Try this part of using vectors if you need to set the size of your container during run time
#include <vectors>
#include <iostream>
int main(int argc, char** argv)
{
std::ifstream infile("instance1.txt");
int NumOne, NumTwo;
if (infile.good()){
infile >> NumOne >> NumTwo;
}
std::vector<int> MyVectorOne(NumTwo);
std::vector<int> MyVectorTwo(NumTwo);
std::vector<int> MyVectorThree(NumTwo);
for(int i = 1; i < NumTwo + 1; i++){ // again this is wrong. What do you want here??
infile >> MyVectorOne[i-1] >> MyVectorOne[i-1] >> MyVectorOne[i-1];
}
infile.close();
cout<<"first number"<<NumOne<<endl;
cout<<"second number"<<NumTwo<<endl;
for (int i=0; i < MyVectorOne.size(); i++){
cout << MyVectorOne[i] << " " << MyVectorTwo[i] << " " << MyVectorThree[i] << endl;
}
// and here? what are you trying to display? this is also wrong
cout<<"first array"<< MyVectorOne<<endl;
cout<<"second array"<< MyVectorTwo<<endl;
cout<<"third array"<< MyVectorThree<<endl;
return 0;
}