void createArray(int a, int b, int c, int d, int array[3][3]){
int state[3][3];
for(int x=0;x<3;x++){
for(int y=0;y<3;y++){
if(x == a && y == b){
state[x][y] = array[c][d];
}
else if(x == c && y == d){
state[x][y] = array[a][b];
}
else{
state[x][y] = array[x][y];
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout << state[i][j] << " ";
}
cout << endl;
}
}
I have basically got this function which clones the multidimensional array that is inputed but swaps the values of the two co-ordinates (a,b) and (c,d) around. This is then outputted out to the console.
However what I would really like is for this to be returned as a multidimensional array, but I don't think this can be done?
I have looked at vectors and pointers but don't really understand them and if I use them, I will then have to change all the previous code I have written.
There are multiple options.
Option 1 - pass the array to the function
void createArray(int a, int b, int c, int d, const int array[3][3], int outArray[3][3]){
...
}
Option 2 - return a reference to an array - just make sure the array does not live on the stack of the function it's returned from.
typedef int My3Times3Array[3][3];
const My3Times3Array& createArray(int a, int b, int c, int d, const int array[3][3]){
...
}
Option 3 - return a class that contains an array
struct Array
{
int array[3][3];
};
...
Array createArray(int a, int b, int c, int d, const int array[3][3]){
...
}
There's also std::vector, std::array, or boost::matrix, but since you mentioned you aren't comfortable with pointers yet, I'd save template classes for later.
When you want to return a non conventional data type (int, char etc), the best way of doing it is by making your very own one.
struct mat3
{
int myArray[3][3];
};
mat3 createArray(int a, int b, int c, int d, int array[3][3]){
mat3 state;
for(int x=0;x<3;x++){
for(int y=0;y<3;y++){
if(x == a && y == b){
state.myArray[x][y] = array[c][d];
}
else if(x == c && y == d){
state.myArray[x][y] = array[a][b];
}
else{
state.myArray[x][y] = array[x][y];
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout << state.myArray[i][j] << " ";
}
cout << endl;
return state;
}
}
I have looked at vectors and pointers but don't really understand them and if I use them, I will then have to change all the previous code I have written
I suggest you study pointers further, they are so essential that you are already using them without knowing it.
You can dynamically allocate a two-dimensional array and return pointer to it. For example
typedef int ( *STATE )[3];
STATE createArray(int a, int b, int c, int d, int array[3][3]){
STATE state = new int[3][3];
//...
return state;
}
Or
int ( *createArray(int a, int b, int c, int d, int array[3][3] ) )[3]{
int ( * state )[3] = new int[3][3];
//...
return state;
}
In fact the same result you can get if you will use vectors. For example
#include <vector>
#include <array>
//...
std::vector<std::array<int, 3>> createArray(int a, int b, int c, int d, int array[3][3]){
std::vector<std::array<int, 3>> state( 3 );
//...
return state;
}
Related
the statement below the function calling is not executed. i am at a loss, why this is so? could someone please clarify. Please consider the code below :
#include<iostream>
#include<cmath>
using namespace std;
class Matrix
{
private:
int row,col;
double *values;
public:
Matrix();
Matrix(int r, int c, double* x);
void setdim(int m, int n){row=m;col=n;}
int getrowdim() const {return row;}
int getcoldim() const {return col;}
void set_values(int i, double x);
double get_value(int i) const;
friend Matrix operator+(const Matrix &A, const Matrix &B);
};
Matrix::Matrix()
{
this->row = 0;
this->col = 0;
this->values = NULL;
}
Matrix::Matrix(int r, int c, double* x)
{
this->row = r;
this->col = c;
this->values = new double[r*c];
for (int i =0;i<r*c;i++)
{
cout<<"Enter value ["<<i<<"] ";
cin>>this->values[i];
}
}
void Matrix::set_values(int k, double x)
{
this->values[k] = x;
}
Matrix operator+(const Matrix &A, const Matrix &B)
{
int rowa = A.getrowdim();
int cola = A.getcoldim();
int rowb = B.getrowdim();
int colb = B.getcoldim();
if(rowa == rowb && cola == colb)
{
Matrix C;
C.setdim(rowa, colb);
for(int i =0; i< rowa*cola ; i++)
{
cout<<"i = "<<i<<", A.get_value = "<<A.get_value(i)<<", B.get_value = "<<B.get_value(i)<<endl;
double m = A.get_value(i) + B.get_value(i);
cout<<m<<endl;
C.set_values(i, m );
cout<<"Returned from C.set_values()"<<endl;
// THIS STATEMENT DOES NOT GET PRINTED. PLEASE TELL THE REASON // WHY. I SUSPECT THE ERROR IS HERE
}
return C;
}
else
{
cout<<"Invalid Operation";
return A;
}
}
double Matrix::get_value(int i) const
{
return this->values[i];
}
int main()
{
Matrix A(2,2,NULL);
Matrix B(2,2,NULL);
Matrix C;
C = A+B;
return 0;
}
The statement - Returned from C.set_values() does not get printed at all .
Could someone help clarify why this is the case? Thanks a lot for the help!
Here:
Matrix C; // (1)
C.setdim(rowa, colb); // (2)
for(int i =0; i< rowa*cola ; i++)
{
cout<<"i = "<<i<<", A.get_value = "<<A.get_value(i)<<", B.get_value = "<<B.get_value(i)<<endl;
double m = A.get_value(i) + B.get_value(i);
cout<<m<<endl;
C.set_values(i, m ); // (3)
You default construct a Matrix (1). The default constructor just sets the member values to NULL. Then you adjust the size members in (2), but values is still NULL. Then, in (3) you call set_values which tries to access array elements, but there is no array.
The problem is that your Matrix has a raw owning pointer as member. When a class manages a resource you must follow the rule of 3/5. If you don't, the class is broken. Managing a resource is not trivial, and following the rule of 3/5 is just the bare minimum.
The simpler alternative that you should strive for is the rule of 0. For a class that does not manage a resource, the compiler generated special members are just right. If you replace the raw pointer member with a std::vector<double> then you do not need to worry about copying, assignment or destruction, because the compiler will generate the required methods for you.
I am trying to write a merge sort algorithm in C++.
If i try to compile the following code, i get the error:
mergeSort.cpp:9:19: error: no matching function for call to 'merge(std::vector&, int&, int&, int&)'
I tried everything in my knowledge to fix this problem and find similar ones online, but I can't figure it out on my own. Please help!
#include <bits/stdc++.h>
void sort(std::vector<int> v, int a, int b) {
//if a == b the length of the subarray is one
if (a != b) {
int k = (a + b) / 2;
sort(v, a, k);
sort(v, k+1, b);
merge(v, a, k, b); //this line gives out the error
}
}
void merge(std::vector<int> &v, int &a, int &k, int &b) {
std::vector<int> tempv;
int tmpa = a;
int tmpk = k;
for (int i = 0; i < b-a; i++) {
if (tmpa >= k-1) {
tempv.push_back(v[tmpk]);
tmpk++;
}
else if (tmpk >= b) {
tempv.push_back(v[tmpk]);
tmpk++;
}
else if (v[tmpa] < v[tmpk]) {
tempv.push_back(v[tmpk]);
tmpk++;
}
else {
tempv.push_back(v[tmpk]);
tmpk++;
}
}
for (int i = a; i < b; i++) {
v[i] = tempv[i-a];
}
}
int main() {
std::vector<int> v = {2, 7, 1, 3, 4, 4};
sort(v, 0, v.size()-1);
for (int i: v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
You are calling the merge() function before the definition of that, so just shift your merge() function before the sort() function.
Put this line before the sort function:
void merge(std::vector<int> &v, int &a, int &k, int &b);
The declaration of merge is not visible at the point of usage. Declare the function before using it.
// Declare the function.
void merge(std::vector<int> &v, int &a, int &k, int &b);
void sort(std::vector<int> v, int a, int b) {
//if a == b the length of the subarray is one
if (a != b) {
int k = (a + b) / 2;
sort(v, a, k);
sort(v, k+1, b);
// Now you can use it.
merge(v, a, k, b); //this line gives out the error
}
}
On a more imporant note...
sort needs to accepts the vector by reference, not by value. Otherwise, the sorted object won't be visible in the calling function.
void sort(std::vector<int>& v, int a, int b) { ... }
// ^^^
As a matter of good coding practice, I recommend declaring all functions before defining and using them.
// Declare the functions.
void sort(std::vector<int>& v, int a, int b);
void merge(std::vector<int> &v, int &a, int &k, int &b);
// Define the functions.
void sort(std::vector<int>& v, int a, int b)
{
...
}
void merge(std::vector<int> &v, int &a, int &k, int &b)
{
...
}
In C++ you need to make sure the function declaration before it's used.
In your case, you used merge before any declaration and so the error.
To fix that, put this declaration at the front, before it is used in your sort function:
void merge(std::vector<int> &v, int &a, int &k, int &b);
Alternatively, you could move the whole merge function definition up front.
Btw, this code could overflow with the intermediate calculation (a + b)
int k = (a + b) / 2; // could overflow
which could be improved by:
int k = a - (a - b) / 2; // fine
This function should initialize arrays C[m+1][n+1] and B[m][n] and fill
the first row and first column of C with zeros. Note: int*** C refers to a pointer points to the 2D integer array. Please correct the error.
void initLCSTable(int*** C, char*** B, int m, int n)
{
C[m + 1][n + 1] = {{0}};
B[m][n];
}
void printLengthTable(int** C, int m, int n);
void printArrowTable(char** B, int m, int n);
main {
int** C;
char** B;
initLCSTable(&C, &B, m, n);
cout << "\nTable C" << endl;
printLengthTable(C, m, n);
cout << "\nTable B" << endl;
printArrowTable(B, m, n);
return 0;
}
Output should look like this (ignore the non-zeros since that is a different Longest Subsequence question all together):
https://i.stack.imgur.com/ElWMY.png
In my code I input the sizes of both dimensions and then declare a two-dimensional array. My question is, how do I use that array as a function parameter? I know that I need to write the number of columns in the function specification but how do I pass the number of columns?
void gameDisplay(gameCell p[][int &col],int a,int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i][j].getStat()==closed)cout<<"C ";
if(p[i][j].getStat()==secure)cout<<"S ";
if(p[i][j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i][j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i][j].getNum()==0)cout<<"0 ";
else cout<<p[i][j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[][col],row,col);
}
I tried this way but it doesn't work.
Thank you.
In C++, you cannot have variable length arrays. That is, you can't take an input integer and use it as the size of an array, like so:
std::cin >> x;
int array[x];
(This will work in gcc but it is a non-portable extension)
But of course, it is possible to do something similar. The language feature that allows you to have dynamically sized arrays is dynamic allocation with new[]. You can do this:
std::cin >> x;
int* array = new int[x];
But note, array here is not an array type. It is a pointer type. If you want to dynamically allocate a two dimensional array, you have to do something like so:
std::cin >> x >> y;
int** array = new int*[x]; // First allocate an array of pointers
for (int i = 0; i < x; i++) {
array[i] = new int[y]; // Allocate each row of the 2D array
}
But again, this is still not an array type. It is now an int**, or a "pointer to pointer to int". If you want to pass this to a function, you will need the argument of the function to be int**. For example:
void func(int**);
func(array);
That will be fine. However, you almost always need to know the dimensions of the array inside the function. How can you do that? Just pass them as extra arguments!
void func(int**, int, int);
func(array, x, y);
This is of course one way to do it, but it's certainly not the idiomatic C++ way to do it. It has problems with safety, because its very easy to forget to delete everything. You have to manually manage the memory allocation. You will have to do this to avoid a memory leak:
for (int i = 0; i < x; i++) {
delete[] array[i];
}
delete[] array;
So forget everything I just told you. Make use of the standard library containers. You can easily use std::vector and have no concern for passing the dimensions:
void func(std::vector<std::vector<int>>);
std::cin >> x >> y;
std::vector<std::vector<int>> vec(x, std::vector<int>(y));
func(vec);
If you do end up dealing with array types instead of dynamically allocating your arrays, then you can get the dimensions of your array by defining a template function that takes a reference to an array:
template <int N, int M>
void func(int (&array)[N][M]);
The function will be instantiated for all different sizes of array that are passed to it. The template parameters (dimensions of the array) must be known at compile time.
I made a little program:
#include <iostream>
using namespace std;
void fun(int tab[][6], int first)
{}
int main(int argc, char *argv[])
{
int tab[5][6];
fun(tab, 5);
return 0;
}
In function definition you must put size of second index. Number of column is passed as argument.
I'm guessing from Problems with 'int' that you have followed the advices of the validated question and that you are using std::vector
Here is a function that returns the number of columns of an "array" (and 0 if there is a problem).
int num_column(const std::vector<std::vector<int> > & data){
if(data.size() == 0){
std::cout << "There is no row" << std::endl;
return 0;
}
int first_col_size = data[0].size();
for(auto row : data) {
if(row.size() != first_col_size){
std::cout << "All the columns don't have the same size" << std::endl;
return 0;
}
}
return first_col_size;
}
If you're using C-style arrays, you might want to make a reference in the parameter:
int (&array)[2][2]; // reference to 2-dimensional array
is this what you're looking for?
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
example . . .
#include <iostream>
#include <stdio.h>
int* generate2DArray(int rowSize, int colSize);
int random(int min, int max);
int main()
{
using namespace std;
int row, col;
cout << "Enter row, then colums:";
cin >> row >> col;
//fill array and display
int *ptr = generate2DArray(row, col);
for(int i=0; i<row; ++i)
for(int j=0; j<col; ++j)
{
ptr[i,j] = random(-50,50);
printf("[%i][%i]: %i\n", i, j, ptr[i,j]);
}
return 0;
}
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
int random(int min, int max)
{
return (rand() % (max+1)) + min;
}
instead of accessing p[i][j] you should access p[i*b + j] - this is actually what the compiler do for you since int[a][b] is flattened in the memory to an array in size of a*b
Also, you can change the prototype of the function to "void gameDisplay(gameCell p[],int a,int b)"
The fixed code:
void gameDisplay(gameCell p[],int a, int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i*a +j].getStat()==closed)cout<<"C ";
if(p[i*a +j].getStat()==secure)cout<<"S ";
if(p[i*a +j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i*a +j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i*a +j].getNum()==0)cout<<"0 ";
else cout<<p[i*a +j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[],row,col);
}
using namespace std;
int addition (int a, int b)
{
return (a+b);
}
int subtraction (int a, int b)
{
return (a-b);
}
int operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return(g);
}
int main()
{
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7,5,addition);
n = operation (20,m,minus);
cout << n;
return 0;
}
Can anybody explain this line for me
int (*minus)(int,int) = subtraction;
Thanks a lot!
int (*minus)(int,int) = subtraction; is creating a variable called minus and assigning it a pointer to the function called subtraction. if the code is valid then the function subtraction would be declared int subtraction(int a, int b);.
the best way to deal with function pointers is to make them readable using typedef.
example:
typedef int (*math_op)(int,int); // new types is math_op
int subtraction (int a, int b)
{
return (a-b);
}
math_op minus = subtraction;
later on these can be called like they are normal functions.
example:
int result = minus(10, 2); // result is now set to 8
your code rewritten:
using namespace std;
typedef int (*math_op)(int,int); // new types is math_op
int addition (int a, int b)
{
return (a+b);
}
int subtraction (int a, int b)
{
return (a-b);
}
int operation (int x, int y, math_op functocall)
{
int g;
g = functocall(x,y);
return(g);
}
int main()
{
int m,n;
math_op minus = subtraction;
m = operation (7,5,addition);
n = operation (20,m,minus);
cout << n;
return 0;
}
"minus" is a name of a variable which is a pointer to a function taking two int arguments and returning another int.
The function called "operation" takes 3 arguments: 2 ints and a pointer to a function which operates on 2 ints and return another one. When invoked, the operation function applies argument 3 to the arguments 1 and 2.
int (*minus)(int,int)
says
A pointer to a function taking two ints as arguments returning an int.
The parentheses around (*minus) are there to make sure that the asterisk binds to the name of the typedef and not the return type (i.e., the function does not return an int*).