multi-dimensional array

T

Tom

Hi,

I am new in programming (and certainly in C++). I want to creat a
five-dimensional array. Two dimensions are numbers and other three are
variable.
One of the variables is an array whose dimension depends on one of the
remaing two variables. Can anyone give me some suggestion what I am
supposed to do?

What I did was the following:

.....
typedef struct {
int matrix[10][10];
} Name1;

....

main(){
...
int dim1; // variable dimension;
int* ar=new int[dim1];
int dim2; // variable dimension;

vector<vector<vector<Name1> > > aaa;

for(int i1=0;i1<dim2;i1++){
for(int i2=0;i2<dim1;i2++){
for(int i3=0;i3<ar[dim1];i3++){
for(int i4=0;i4<10;i4++){
for(int i5=0;i5<10;i5++){
aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
element;
}
}
}
}
}

delete[] ar;

}


However, when I compiled it always gave me a message Segmentation
fault (presumable this is an initialized issue, I am not sure as I
wrote before I am new in programming). My program compiles fine if I
remove the above segment.

Thanks in advance,
Tom
 
V

Victor Bazarov

Tom said:
Hi,

I am new in programming (and certainly in C++). I want to creat a
five-dimensional array. Two dimensions are numbers and other three are
variable.
One of the variables is an array whose dimension depends on one of the
remaing two variables. Can anyone give me some suggestion what I am
supposed to do?

What I did was the following:

....
typedef struct {
int matrix[10][10];
} Name1;

...

main(){

Should be

int main(){
...
int dim1; // variable dimension;
int* ar=new int[dim1];

What's that for? And how much are you allocating? What's the value
of 'dim1' here?
int dim2; // variable dimension;

vector<vector<vector<Name1> > > aaa;

How does the 'aaa' know how many elements should be in its vectors?
In order to fill it in, you have to allocate some first. Read about
'resize' member of 'vector' template.
for(int i1=0;i1<dim2;i1++){
for(int i2=0;i2<dim1;i2++){
for(int i3=0;i3<ar[dim1];i3++){
for(int i4=0;i4<10;i4++){
for(int i5=0;i5<10;i5++){
aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
element;
}
}
}
}
}

delete[] ar;

}


However, when I compiled it always gave me a message Segmentation
fault (presumable this is an initialized issue, I am not sure as I
wrote before I am new in programming). My program compiles fine if I
remove the above segment.

Of course you get a segmentation error. The 'aaa' vector does not
contain any elements, and you're trying to access them.

Victor
 
G

Guest

Hi,

I am new in programming (and certainly in C++). I want to creat a
five-dimensional array. Two dimensions are numbers and other three are
variable.
One of the variables is an array whose dimension depends on one of the
remaing two variables. Can anyone give me some suggestion what I am
supposed to do?

What I did was the following:

....
typedef struct {
int matrix[10][10];
} Name1;

And now :

template <class T> class m3 {
std::vector<T> data;
int dimx,dimy,dimz;
public:
m3(int sizex,int sizey,int sizez,const T& t) : data(i*j*k,t),dimx(sizex)
,dimy(sizey),dimz(sizez) {}
T& operator ()(int i,int j,int k) { return data[(i*dimy+j)*dimz+k]; }
};
m3 said:
...

main(){
...
int dim1; // variable dimension;
int* ar=new int[dim1];
int dim2; // variable dimension;

don't exactly undersand what's going on with this dimension , do you need
more of them ?
vector<vector<vector<Name1> > > aaa;

it may work too but it's more complicated - indirect and 3 dimensions have
resize capabilities - do you want them too ?
Right now 3 first dimensions are 0, no data (and memory space) in your
vector.
for(int i1=0;i1<dim2;i1++){
for(int i2=0;i2<dim1;i2++){
for(int i3=0;i3<ar[dim1];i3++){
for(int i4=0;i4<10;i4++){
for(int i5=0;i5<10;i5++){

that would mean dimensions are dim2,dim1,ar[dim1]

aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
element;
}
}
}
}
}

delete[] ar;

}


However, when I compiled it always gave me a message Segmentation
fault (presumable this is an initialized issue, I am not sure as I
wrote before I am new in programming). My program compiles fine if I
remove the above segment.

Thanks in advance,
Tom
 
J

Jonathan Mcdougall

I am new in programming (and certainly in C++). I want to creat a
five-dimensional array. Two dimensions are numbers and other three are
variable.

What about getting a good book? See www.accu.org
One of the variables is an array whose dimension depends on one of the
remaing two variables. Can anyone give me some suggestion what I am
supposed to do?

I think your program is the most undefined-behaviorial one I ever seen.
What I did was the following:

....
typedef struct {
int matrix[10][10];
} Name1;

C++ is not C :

struct Name1
{
int matrix[10][10];
};
...

main(){

Undefined behavior 1 : main() returns an int. Always.

int main()
{

What's that?
int dim1; // variable dimension;

Here, dim1 is not initialized, that is, it contains garbage. Accessing it
results in undefined behavior.
int* ar=new int[dim1];

Ugh. Undefined behavior 2 : you are using an uninitialized object (dim1) to
allocate an object. The best thing you could get is a crash.
int dim2; // variable dimension;

vector<vector<vector<Name1> > > aaa;

Here, 'aaa' is empty. You *cannot* put values in it other than with
push_back() or insert().
for(int i1=0;i1<dim2;i1++){
for(int i2=0;i2<dim1;i2++){
for(int i3=0;i3<ar[dim1];i3++){
for(int i4=0;i4<10;i4++){
for(int i5=0;i5<10;i5++){
aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
element;
}
}
}
}
}

Undefined behavior 3 and 4 : you are using 'dim1' and 'dim2', both of which
are not initialized. How long do you think that loop is going to last ?
Undefined behavior 5 : you are accessing non existent elements of 'aaa'.
delete[] ar;

}

For what I can see, you want something like

# include <vector>

using std::vector;

const int MATRIX_SIZE_X = 10;
const int MATRIX_SIZE_Y = 10;


struct Name1
{
int matrix[MATRIX_SIZE_X][MATRIX_SIZE_Y];
};


int main()
{
const int SIZE_1 = 10;
const int SIZE_2 = 10;
const int SIZE_3 = 10;

vector< vector< vector< Name1 > > > aaa;

for ( int i = 0; i < SIZE_1; ++i )
{
aaa.push_back(vector< vector< Name1> > () );

for ( int j = 0; j < SIZE_2; ++j )
{
aaa.push_back(vector< Name1 > () );

for ( int k = 0; k < SIZE_3; ++k )
{
Name1 name;

for ( int l = 0; l < MATRIX_SIZE_X; ++l )
{
for ( int m = 0; m < MATRIX_SIZE_Y; ++m )
{
name.matrix[l][m] = something;
}
}

aaa[j].push_back( name );
}
}
}
}

(untested)


Jonathan
 
T

Tom

Hi all,

Thanks for helping me. I guess I did not tell you exactly what I
wanted.
Jonathan's program is not what I wanted because Jonathan fixed all
three dimentions. Below is my naive program.


#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<set>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<algorithm>

#define FIX 20

using namespace std;

typedef struct { // I will change to C++ style as
int matrix[10][10]; // Jonathan suggested
} Name1;


int score(char x,char y){
if(((x=='A') && (y=='A')) || ((x=='B') && (y=='B')) ||
((x=='C') && (y=='C')) || ((x=='D') && (y=='D'))){
return 1;
}
else{
return 0;
}
}

//there are more lines here but it has nothing to do with our
discussion.
// That's why I put ....
int main(){ // Missing int was a typo.

ifstream input_file1("file1");
string line_file1,seq_prob;
vector<string> line1;

while(getline(input_file1, line_file1))
line1.push_back(line_file1);

vector<string> line1_string;
vector<string> title1_string;
int c0=0; int d0=0;

for(int j=0;j<line1.size();j++){
if(line1[j][0]=='>'){
title1_string.push_back(line1[j]);
c0++;
}
else{
line1_string.push_back(line1[j]);
d0++;
}
}

int dim1 = line1_string.size(); // or one can use int dim1 = c0;

ifstream input_file2("file2");
string line_file2;
vector<string> line2;
vector<string> line2_title;

while(getline(input_file2, line_file2))
line2.push_back(line_mir_target);

vector<string>* tartemp = new vector<string>[line2.size()];

int c1=0; int d1=0;

for(int j=0;j<line2.size();j++){
if(line2[j][0]=='>'){
line2_title.push_back(line2[j]);
c1++;
}
else{
tartemp[c1-1].push_back(line2[j]);
}
}

string pp="";

for(int ttt=0;ttt<tartemp[0].size();ttt++){
pp+=tartemp[0][ttt];
}

int dim2 = c1;

string* line2_string =new string[dim2];

for(int cc1=0; cc1<dim2;cc1++){
for(int fff=0; fff<tartemp[cc1].size();fff++){
line2_string[cc1] += tartemp[cc1][fff];
}
}


int* ar = new int[dim2];

for(int f2=0;f2<dim2;f2++){
ar[f2] = line2_string[f2].size() - FIX;
}

// No I want to make a five-dimensional array with dimension dim1,
dim2, ar, 10 and 10

vector<vector<vector<Name1> > > aaa;

// I tried to initialize aaa.

for(int p=0; p<dim1;p++){
for(int t=0;t<dim2;t++){
for(int s=0;s<ar[t];s++){
for(int row=0; row<10;row++){
for(int col=0;col<10;col++){
aaa[p][t].matrix[row][col]=-1;
}
}
}
}
}

//known[][][][][]

for(int p=0; p<dime1;p++){
for(int t=0;t<dim2;t++){
for(int s=0;s<ar[t];s++){
for(int c=0;c<10;c++){
for(int r=0;r<10;r++){
aaa[p][t].matrix[r][c] =
score((line2_string[t].substr(s,10))[c],(line1_string[p])[r]));
}

}
}
}
}


delete[] ar;
delete[] tartemp;

}



Many thanks,
Tom
 
V

Victor Bazarov

Tom said:
[...]
// No I want to make a five-dimensional array with dimension dim1,
dim2, ar, 10 and 10

vector<vector<vector<Name1> > > aaa;

// I tried to initialize aaa.


'aaa' is _empty_ here. That means it doesn't _have_ any elements
for you to initialise. You need to _resize_ it so it has something:

aaa.resize(dim1);
for(int p=0; p<dim1;p++){

Although 'aaa' now has 'dim1' elements, each 'aaa' is _empty_.
You need to resize them (every loop cycle would be OK) to give
it something to _initialise_:

aaa[p].resize(dim2);
for(int t=0;t<dim2;t++){

The same here:

aaa[p][t].resize(ar[t]);
for(int s=0;s<ar[t];s++){
for(int row=0; row<10;row++){
for(int col=0;col<10;col++){
aaa[p][t].matrix[row][col]=-1;
}
}
}
}
}

//known[][][][][]

for(int p=0; p<dime1;p++){


'dime1'? Typos again?
for(int t=0;t<dim2;t++){
for(int s=0;s<ar[t];s++){
for(int c=0;c<10;c++){
for(int r=0;r<10;r++){
aaa[p][t].matrix[r][c] =
score((line2_string[t].substr(s,10))[c],(line1_string[p])[r]));
}

}
}
}
}


delete[] ar;
delete[] tartemp;

}


HTH

Victor
 
T

Tom

Thanks Victor,

Your suggestion works fine. However, my program with your suggestion
run pretty slow. When I have an input file around 3MB, then it did not
run (Aborted). Do you have any suggestion about optimizing? What
should I do to optimize it?

Thanks again,
Tom
'dime1'? Typos again?

Yes. It's a typo.
 
V

Victor Bazarov

Tom said:
Thanks Victor,

Your suggestion works fine. However, my program with your suggestion
run pretty slow. When I have an input file around 3MB, then it did not
run (Aborted). Do you have any suggestion about optimizing? What
should I do to optimize it?

You should find the place in your program that holds everything up
(use a special program called "profiler"), then analyse that place
and see what you can do to speed it up.

WRT optimisations there are very few real generic recommendations.
They are, mostly, rules or laws. For example, the 80/20 rule: 80
percent of the time in your program is spent in 20 percent of the
code (so there is no sense trying to speed up the rest of the code,
it's not going to make any real difference). Or the "don't try
optimising before you know what to optimise" rule (that's where
a profiler should be of great help).

Good luck!

Victor
 
T

Tom

Hi Victor,

Thanks a lot. I want to load a file around 5MB into a buffer and do
some manipulation. My program could not run. It said Aborted. Would
you have any idea what wrong with my program below? I really
appreciate your comments.

Thanks,
Tom

#include<iostream>

#define tarlen 20

int main(){

ifstream input_target(TARGET_FILE);
string line_mir_target;
vector<string> target;
vector<string> input_ft;

while(getline(input_target, line_mir_target))
target.push_back(line_mir_target);

vector<string>* tartemp = new vector<string>[target.size()];

int c1=0; int d1=0;

for(int j=0;j<target.size();j++){
if(target[j][0]=='>'){
input_ft.push_back(target[j]);
c1++;
}
else{
tartemp[c1-1].push_back(target[j]);
}
}
int number_of_targets = c1;

string* input_ts =new string[number_of_targets];

for(int cc1=0; cc1<number_of_targets;cc1++){
for(int fff=0; fff<tartemp[cc1].size();fff++){
input_ts[cc1] += tartemp[cc1][fff];
}
//cout << input_ts[cc1] << endl;
}

int* n_targets = new int[number_of_targets];

for(int f2=0;f2<number_of_targets;f2++){
n_targets[f2] = input_target_seq[f2].size() - tarlen +1;
}



vector<vector<string> > ts;

ts.resize(number_of_targets);

for(int f33=0; f33<number_of_targets;f33++){
ts[f33].resize(n_targets[f33]);
}

for(int f4=0;f4<number_of_targets;f4++){
for(int kkk=0;kkk<n_targets[f4];kkk++){
ts[f4][kkk]= input_ts[f4].substr(kkk,tarlen);
cout << ts[f4][kkk] << endl;
}
}

}
 
V

Victor Bazarov

Tom said:
Hi Victor,

Thanks a lot. I want to load a file around 5MB into a buffer and do
some manipulation. My program could not run. It said Aborted. Would
you have any idea what wrong with my program below? I really
appreciate your comments.

Thanks,
Tom

#include<iostream>

#define tarlen 20

int main(){

ifstream input_target(TARGET_FILE);

'TARGET_FILE' is undefined here. 'ifstream' is undefined as well,
you might want to '#include said:
string line_mir_target;

'string' is undefined here. You forgot to '#include said:
vector<string> target;

'vector' is undefined. It can be cured by '#include <vector>'

(and all those includes should probably be followed by the 'using'
declaration)
vector<string> input_ft;

while(getline(input_target, line_mir_target))
target.push_back(line_mir_target);

vector<string>* tartemp = new vector<string>[target.size()];

int c1=0; int d1=0;

for(int j=0;j<target.size();j++){
if(target[j][0]=='>'){
input_ft.push_back(target[j]);
c1++;
}
else{
tartemp[c1-1].push_back(target[j]);
}
}
int number_of_targets = c1;

string* input_ts =new string[number_of_targets];

for(int cc1=0; cc1<number_of_targets;cc1++){
for(int fff=0; fff<tartemp[cc1].size();fff++){
input_ts[cc1] += tartemp[cc1][fff];
}
//cout << input_ts[cc1] << endl;
}

int* n_targets = new int[number_of_targets];

for(int f2=0;f2<number_of_targets;f2++){
n_targets[f2] = input_target_seq[f2].size() - tarlen +1;
}



vector<vector<string> > ts;

ts.resize(number_of_targets);

for(int f33=0; f33<number_of_targets;f33++){
ts[f33].resize(n_targets[f33]);
}

for(int f4=0;f4<number_of_targets;f4++){
for(int kkk=0;kkk<n_targets[f4];kkk++){
ts[f4][kkk]= input_ts[f4].substr(kkk,tarlen);
cout << ts[f4][kkk] << endl;
}
}

}

In this particular fragment:

int c1=0;
int d1=0;

for(int j=0;j<target.size();j++)
{
if(target[j][0]=='>')
{
input_ft.push_back(target[j]);
c1++;
}
else
{
tartemp[c1-1].push_back(target[j]);
}
}

What if the very first 'target' element does NOT have the '>'
character in the beginning? 'c1' is 0. 'tartemp[c1-1]' is
'tartemp[-1]'. That's "before the beginnig of the vector".
I doubt this should work.

I cannot give you any more advice without knowing what the file
is that you attempt to load. No, this is not an invitation to
post it here or send it to me. Please learn to debug your own
programs.

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top