I have written a function to raise matrix to a certain power.
But when running the code the result is the memory location not the actual values. I think the problem is with the pointers.
My code:
#include <iostream>
using namespace std;
typedef int array2d [2][2];
array2d A,B,r;
void pow(array2d* r,array2d C);
int main(){
array2d resa,resb;
A[0][0]=2;
A[0][1]=2;
A[1][0]=2;
A[1][1]=2;
B[0][0]=3;
B[0][1]=3;
B[1][0]=3;
B[1][1]=3;
r[0][0]=1;
r[0][1]=0;
r[1][0]=0;
r[1][1]=1;
pow(&resa,A);
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
cout<<resa[i][j]<<" ";
}
cout<<endl;
}
pow(&resb,B);
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
cout<<resb[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
void pow(array2d* r, array2d C)
{
array2d temp;
for(int w=0;w<3;w++)
{
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
temp[i][j]=0;
for(int k=0;k<2;k++)
temp[i][j]+=(*r)[i][k]*C[k][j];
}}
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
(*r)[i][j]=temp[i][j];
}}
}
}
How can I solve this problem.
Thank You.
Your error has nothing to do with pointers or addresses, but your algorithms is erroneous:
pow(&resa, A);
multiplies the matrix A with the uninitialized matrix resa which can yield any number of possible results.
The quick and dirty fix would be to initialize resa and resb as identity matrices:
array2d resa = { { 1, 0 }, { 0, 1 } };
array2d resb = { { 1, 0 }, { 0, 1 } };
EDIT or slightly better: Initialize r inside of pow
//passing r by pointer is not actually necessary here,
//but I don't want to modify too much of the code
(r*)[0][0] = 1;
(r*)[1][0] = 0;
(r*)[0][1] = 0;
(r*)[1][1] = 1;
The more elegant solution would be to first multiply the parameter C with itself, store the result in r and then go on with your algorithm.
On a side note: don't use c-style arrays, if you don't need them (especially not in typedefs). Use std::array instead, which will get rid of most of the confusion regarding to parameter passing.
you really should avoid global when you can, and using the same name in global and local variables is even worse
also the name of your variables MATTERS, here i call the input matrix IN and output matrix OUT (ok "n" should be called power)
using namespace std;
typedef int array2d [2][2];
void display( array2d a ) ;
void pow(array2d IN ,array2d OUT , int n);
int main()
{
array2d A,B;
array2d resa,resb;
A[0][0]=2;
A[0][1]=2;
A[1][0]=2;
A[1][1]=2;
B[0][0]=3;
B[0][1]=1;
B[1][0]=2;
B[1][1]=1;
pow (A , resa , 5);
pow( B , resb, 2 ) ;
return 0;
}
and
void pow(array2d IN, array2d OUT , int n )
{
for( int i = 0 ; i < 2 ; ++ i )
for( int j = 0 ; j < 2 ; ++ j )
OUT[i][j] = ( i == j ) ;
display( OUT ) ;
array2d temp;
for(int w=0;w<n;w++)
{
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
temp[i][j]=0;
for(int k=0;k<2;k++)
{
temp[i][j]+=OUT[i][k]*IN[k][j];
}
}
}
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
OUT[i][j]=temp[i][j];
}
}
display( OUT ) ;
}
}
with
void display( array2d a )
{
cout << endl ;
for( int i = 0 ; i < 2 ; ++ i )
{
for( int j = 0 ; j < 2 ; ++ j )
cout << a[i][j] << " " ;
cout << endl ;
}
}
The first parameter of your pow function, change it to the pass by reference: void pow(array2d &r,array2d C);
Then where you call it, call it like so: pow(resa,A);
Finally, you don't need to deference r in your pow function now, so (*r)[i][j]=temp[i][j]; can be changed to r[i][j]=temp[i][j];
I think this is what you wanted to do. ( pass by reference )
( I am not in front of a pc where I can test this right now, will confirm as soon as I can, and maybe flesh out why this is better ( can read up about pointers, heap memory and pass by reference )
Related
I'm trying to add elements of two arrays and store them in a third array. I'm experimenting with pointers so I want to use them as arguments to the user defined function.
When, I run the code, I get the Error: exited, segmentation fault, as soon as I enter the first two values for the array.
I am painfully unaware of what I'm doing wrong.
#include<iostream>
using namespace std;
float addarrays(float ptra1[5], float ptra2[5], float ptra3[5])
{
for(int i=0; i<5; i++)
{
ptra3[i] = ptra1[i] + ptra2[i];
}
return *ptra3;
}
int main()
{
float A[5], B[5], C[5];
float *ptA[5], *ptB[5], *ptC[5];
cout<<"Enter Array A: \n";
for(int i=0; i<5; i++)
{
cout<<"Element A["<< i <<"] = ";
cin>>*ptA[i];
}
cout<<"\nEnter Array B: \n";
for(int i=0; i<5; i++)
{
cout<<"Element B["<< i <<"] = ";
cin>>*ptB[i];
}
addarrays(*ptA, *ptB, *ptC);
cout<<"Displaying result for C[i] = A[i] + B[i]: \n";
for(int i=0; i<5; i++)
{
cout<<"\nElement C["<< i <<"] = "<<*ptC[i];
}
return 0;
}
For starters these arrays of pointers
float *ptA[5], *ptB[5], *ptC[5];
are not initialized.
So this statement
cin>>*ptA[i];
invokes undefined behavior.
You could set elements of the array ptA for example in a loop like
size_t i = 0;
for ( auto &p : ptA ) p = A + i++;
Pay attention to that the function addarrays does not set elements of the array ptC. In fact it tries to ser elements of the array C provided that the array ptC was correctly initialized. Array ptC is still uninitialized. So this statement
cout<<"\nElement C["<< i <<"] = "<<*ptC[i];
again will invoke undefined bejavior.
Thus you need to initialize the arrays of pointers.
size_t i = 0;
for ( auto &p :ptA ) p = A + i++;
i = 0;
for ( auto &p :ptB ) p = B + i++;
i = 0;
for ( auto &p :ptC ) p = C + i++;
The function can be declared and defined the following way
void addarrays(float * ptra1[], float * ptra2[], float * ptra3[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
*ptra3[i] = *ptra1[i] + *ptra2[i];
}
}
and called like
addarrays( ptA, ptB, ptC, 5 );
need a better approach to pass address arr[0][2], given that is has to be received in a double pointer.
want to pass arr[0][2] without storing in any other variable.
#include <iostream>
using namespace std;
int help(int **arr)
{
cout<<**arr;
}
int main()
{
{
int n=3,m=3,k=0;
int **arr = new int*[n];
for(int i = 0; i < n; i++) {
arr[i] = new int[m];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
arr[i][j]=k;
k++;
}
}
int *g=*arr+2;
int **h=&g;
help(h);
}
}
There is no better way. Unfortunately C++ syntax x[y] can be used to mean two very different operations: if x is an array then is indexing, if x is a pointer they it's indirection and indexing.
If a caller expects a pointer to a pointer and you've a bidimensional matrix there's nothing you can do except actually creating the pointer that is not present in the matrix and pass its address.
The fact that with an array of pointers, with a pointer to a pointer and with a 2d array the syntax to reach an element is x[y][z] is irrelevant... they are three very different operations.
Why not just write
int *p = &arr[0][2];
help( &p );
If you want to get an access to the whole array using a pointer of the type int ** then you can use the following approach.
#include <iostream>
void help(int **arr, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
std::cout << ( *arr )[i] << ' ';
}
std::cout << '\n';
}
int main()
{
int arr[2][3]={{1,2,3},{4,5,6}};
int *p = reinterpret_cast<int *>( arr );
help( &p, 6 );
return 0;
}
The program output is
1 2 3 4 5 6
I am working on a C++ class that consists of a 2D Vector of Doubles. I am about to create the 2D Vector but when I try to edit the values inside of it, the program crashes. I have tried using the [][] operator and setting it equal to myDub and I have tried using a class like myMat.editSlot(i,j,myDub) and both have caused the program to crash.
//n == # of rows and cols (all matrices are square)
//infile opens the file properly
mat my_mat(n,n);
// Read input data
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(i,j,myDub);
}
}
and here is the class:
class mat
{
mat( int x , int y ) {
int row = x;
int col = y;
vector<vector<double>> A( row , vector<double>( row , 0 ) );
for ( int i = 0; i<row; i++ )
{
for ( int j = 0; j<col; j++ )
{
cout << setw( 6 ) << A[i][j];
}
cout << endl;
}
}
void editSlot( int x , int y , double val ) {
A[x][y] = val;
}
vector<vector<double>> A;
private:
int n;
};
It looks to me that the way you're initializing A is wrong. Try something like this:
A = vector<vector<double>>( row , vector<double>( row , 0 ) );
Another thing to consider both the constructor and the edit function aren't declared public.
Main problem that leads to crush is that you change size of a temporal vector A in your constructor while A vector that you declared as a field in your class object is not touched.
I suggest doing something like this:
mat(int x,int y) : A(y,vector<double>(x,0)) {
int row = x;
int col = y;
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
cout<<setw(6)<<A[i][j];
}
cout<<endl;
}
}
}
In this case you won't hide your A field in class with temporal A object in constructor function.
Also please pay attention not to swap x and y in your functions. For example, you have an error in your editSlot function:
void editSlot( int x , int y , double val ) {
A[x][y] = val;
}
, it should be:
A[y][x] = val;
according to constructor.
I have created a 3d array into main function because one of its size came from used input. I am using C++
std::cin >> size;
typedef int T[8][3];
T* tables = new T[size];
It is basically tables[size][8][3]
Now I have to use this 3d table in different functions and have to store values into it. The best way to do it by make this table as a global variable. But I am not sure that I can do it after main function. The other option I have, that I have to pass this table as a parameter and have to return that at the end of the function.
I have tried both the approach but I am having error. Please help me about this issue. I don't know which approach to choose and how to do it.
Thank you in advance.
**Example:**This an example what I really want to do. Here I create a 3d array in main function and through another function I gave some input into that array and again print that in main function.
#include <iostream>
#include <conio.h>
using namespace std;
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
int M:: pass(int (*table)[8][3],int s)
{
for (i=0;i<s;i++)
{
//int a = tables[i][2][1];
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
table[i][j][k]=i;
}
}
}
return (*table)[8][3]; // not sure about this
}
int main()
{
int size,i,j,k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx;
mx.pass(tables,size); // not sure
for (i=0;i<size;i++)
{
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
cout<<tables[i][j][k];
cout<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"..........." << i <<endl;
}
getch();
}
I don't know if I completely understand your problem. But you can definitely store the pointer locally in your object and reference it elsewhere. Something like this:
class M
{
public:
M(int(*tbl)[8][3]) : table(tbl) { }
int(*table)[8][3];
int i, j, k;
public:
void pass(int size);
};
void M::pass(int s)
{
for (i = 0; i<s; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
table[i][j][k] = i;
}
}
}
}
int main()
{
int size, i, j, k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx(tables);
mx.pass(size); // not sure
for (i = 0; i<size; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
cout << tables[i][j][k];
// or you can also:
// cout << mx.table[i][j][k];
cout << " ";
}
cout << endl;
}
cout << endl;
cout << "..........." << i << endl;
}
_getch();
}
Since you are creating a dynamic 3D array whose two dimensions are fixed, Use a std::array<std::array<int, 3>, 8> as your 2D array. Use a std::vector<__2D_ARRAY_TYPE> to create the 3D array.
#include <iostream>
#include <array>
#include <vector>
int main() {
std::array<std::array<int, 3>, 8> array_2d ;
std::vector<decltype(array_2d)> array_3d ;
int size = 4 ;
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < 8; ++j)
for(int k = 0; k < 3; ++k)
array_2d[j][k] = j + k ;
array_3d.push_back(array_2d);
}
return 0;
}
Something like this you can use easily which does the job more easily without any manual memory management.
You can pass it to a function. The signature would be :
return_type function_name(const std::vector<std::array<std::array<int, 3>, 8>>& array_3d)
{ .... }
In
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
you don't have to write public twice. You can simply put all of the public member data under the keyword public.
Also, you seem to be re-writing your function over again at the very end. Instead of
cout<<tables[i][j][k];
You can write
cout<<*tables
For an array A of arbitrary length n, I'd like to fill in a n x m array B with all combination of elements from A that includes all possible orders of those elements. For example, if A = {1, 2, 3} and m = 2, I'd like to get B as:
11
12
13
21
22
23
31
32
33
What is an efficient way to do this in C/C++? Thanks!
EDIT: Here is what I figured out to work (data is within the class combs which is basically a matrix class with some added tricks):
void combs::setCombs (int arr[], int n, int m) {
int z, tmp, repeat;
int max = (int (pow(double (n), double( m ))));
for (int i = 0; i < m; i++) {
z = 0;
repeat = int (pow( double (n), double (i)));
for (int j = 0; j < repeat; j++) {
for (int k = 0; k < n; k ++) {
for (int p = 0; p < max/(n*repeat); p ++) {
cout << arr[k] << endl;
data[z*ROWS + i] = arr[k];
z++;
}
}
}
}
}
As mentioned by #Joachim Pileborg your question lacks a lot in the way of parameters.But lets say you could guarantee that you were passing me a vector of SORTED UNIQUE ints. Then this brute force would be possible:
std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
std::vector< std::string > result( source.size() * m );
for( int i = 0; i < result.size(); i++ )
{
for( int j = 0; j < m; j++ )
{
result[i] += *(digits[j]);
}
for( int j = digits.size() - 1; j >= 0; j-- )
{
++digits[j];
if( digits[j] == source.cend() )
{
digits[j] = source.cbegin();
}
else
{
break;
}
}
}
return result;
}
What you are describing sounds like partial permutations, not combinations.
If you are using c++, then it is recommended to use vectors, because vectors can tell you their size, and they free their own memory. An implementation with vectors would be as follows:
vector<vector<int> > partialPermutations(vector<int> &A,int m){
int i,i2,t,n=A.size(),total=1;
for(i=0;i<m;i++) total*=n;
vector<vector<int> > result;
for(i=0;i<total;i++){
result.push_back(vector<int>());
t=i;
for(i2=0;i2<m;i2++){
result[i].push_back(A[t%n]);
t/=n;
}
}
return result;
}
int main() {
vector<int> A;
int total,i,i2;
for(i=1;i<=4;i++) A.push_back(i);
vector<vector<int> > re=partialPermutations(A,2);
for(i=0;i<re.size();i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
return 0;
}
If you still want to use arrays, then the code would be as follows:
int** partialPermutations(int*A,int n,int m,int &total){
int i,i2,t;
total=1;
for(i=0;i<m;i++) total*=n;
int **result=new int*[total];
for(i=0;i<total;i++){
t=i;
result[i]=new int[m];
for(i2=0;i2<m;i2++){
result[i][i2]=A[t%n];
t/=n;
}
}
return result;
}
int main() {
int A[]={1,2,3,4};
int total,i,i2;
int **re=partialPermutations(A,4,2,total);
for(i=0;i<total;i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
//Cleanup
for(i=0;i<total;i++) delete[] re[i];
delete[] re;
return 0;
}
Notice that by using arrays, we have to recover the size of the resulting array (passing total by reference), and we have to free the memory afterwards. None of this is needed with vectors.
#include<iostream>
using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
if(i==k)
{
cout<<"\nAnswer : "<<ans<<endl;
}
else
{
for(int x=0;x<s.size();++x)
{
ans[i]=s[x];
printStrRec(s,ans,k,i+1);
}
}
}
void printStrings(string s,int k)
{
string ans;
for(int p=0;p<k;++p)
{
ans+="x";
}
printStrRec(s,ans,k,0);
}
int main()
{
int k;
string s;
cout<<"Enter the set : ";
cin>>s;
cout<<"\nEnter k : ";
cin>>k;
printStrings(s,k);
return 0;
}
Hope that helps.