Hi:

I never set up a 2D array in the past and I am trying to do it now. I have a program that reads a 1 line text file and after reading it makes some calculations. After this I made some changes to my code trying to make a 2D array so I a can more than one line at a time. I did my originbal code using pointers since I received help from one my TA's on this matter. I believe that I need to make some changes to the definition of my complexity but I am afraid if I make changes here I will mess up the equation I use to find sumc. For you to understand this you need to read the code. Of course when I run this code I get some errors. Here are my errors and my code.

G

g++ Complex.cpp 
Complex.cpp: In function ‘int main()’:
Complex.cpp:36: error: ‘i’ cannot appear in a constant-expression
Complex.cpp:52: error: invalid types ‘unsigned int[int]’ for array subscript
#include <iostream>
#include <fstream>
#include <cmath> // for log
using namespace std;

unsigned int complexity(const unsigned int* S, unsigned int T)
{
  unsigned int c = 1;
  unsigned int l = 1;
  do
    {
      int kmax =1;
      for (int i=0;i<l;i++)
	{
	  int k = 0;
	  while (S[i+k] == S[l+k])
	    {
	      ++k;
	      if (l+k >= T-1) return (++c);
	    }
	  if (k >= kmax) kmax = k+1;
	}
      ++c;
      l += kmax;
    }
  while (l < T);
  return c;
}

int main(void)
{
  unsigned T; // length of string
  cout << "Enter length of string: ";
  cin >> T;
  int i = 0;
  unsigned int* S = new unsigned int[T][i];
  ifstream K;
  unsigned int count = 0;
  K.open ("k.txt");
  if(K.fail())
    {
      cout << "What the fuck did you do with the file" << endl;
    }
  else
    {
      while(!K.eof())
	{
	  for (unsigned int t=0;t<=T;t++)
	    {
		{	
		  K >> S[t][i];
		  i++;
		}
	    }
	}
    }
  K.close();
  unsigned int sumc = complexity(S,T);
  cout << "sumc = " << sumc << endl;
  double cnorm;
  cnorm = sumc*log((double)T)/(log(2.0)*((double)T));
  cout << "cnorm = " << cnorm << endl;
  delete[] S;
  return 0;
}

If S is a 2-D array, it should have a type of unsigned int **, not unsgned int *. If it was a 3-D array it would be unsigned int***. A 4-D array would be unsigned int****.

You have to do the "new"command in stages. This won't work:

unsigned int* S = new unsigned int[T][i];

It doesn't work even if if you correct S's type and do this:

unsigned int** S = new unsigned int[T][i];

You need to do something like this:

int numRows, numCols;
    
    cout <<"Enter number of rows : ";
    cin >> numRows;
    cout <<"Enter number of columns : ";
    cin >> numCols;
    
    unsigned int** S;
    S = new unsigned int*[numRows];
    for (int i = 0; i < numRows; i++)
      S[i] = new unsigned int[numCols];

Unlike static arrays, you don't do one single new command with all of the dimensions. You have to define a dimension at a time and then loop.


This thread may be of interest. It deals with characters, not unsigned integers, but some of the concepts are the same.

http://www.daniweb.com/forums/post996879.html

Thanks for the help. I understand were was my mistake setting it up. I have another query though, I set up my code to take both columns but how can I get my code to do the calculations for each row. The way I set it up now it seems to read first column and do the calculation for it and that is it. I try setting up the code for the calculations inside the loop but it gives me a segmentation violation error. Any insight how can I correct error.

This is my updated code

#include <iostream>
#include <fstream>
#include <cmath> // for log
using namespace std;

unsigned int complexity(unsigned int** S, unsigned int T)
{
  unsigned int c = 1;
  unsigned int l = 1;
  do
    {
      int kmax =1;
      for (int i=0;i<l;i++)
	{
	  int k = 0;
	  while (S[i+k] == S[l+k])
	    {
	      ++k;
	      if (l+k >= T-1) return (++c);
	    }
	  if (k >= kmax) kmax = k+1;
	}
      ++c;
      l += kmax;
    }
  while (l < T);
  return c;
}

int main(void)
{
  unsigned T; // length of string
  cout << "Enter length of string: ";
  cin >> T;
  unsigned X; // length of columns
  cout << "Enter amount of colums to read :";
  cin >> X;
  unsigned int** S;
  S = new unsigned int* [T];
  ifstream K;
  K.open ("k.txt");
  if(K.fail())
    {
      cout << "What the fuck did you do with the file" << endl;
    }
  else
    {
      while(!K.eof())
	{
	  for (unsigned int t=0;t<=T;t++)
	    {
	      S[t] = new unsigned int [X];
	      for (unsigned int i=0;i<=X;i++)
		{
		  K >> S[t][i];
		}
	    }
	}
    }
  K.close();
  unsigned int sumc = complexity(S,T);
  cout << "sumc = " << sumc << endl;
  double cnorm;
  cnorm = sumc*log((double)T)/(log(2.0)*((double)T));
  cout << "cnorm = " << cnorm << endl;
  delete[] S;
  return 0;
}

Attached is a sample of the type of file I should read. If the file were to read the first line of this file it should get the following result

sumc = 6
cnorm = 1.5

Thanks

G

Looks like you have a 16 x 16 file of 0's and 1's. You ask for the string length. I see no strings, so the prompts are a bit confusing. What did you enter for this file for the values of T and X. 16 each?

Recall that if you have a 16 x 16 array, valid indexes are 0 through 15, not 1 through 16. You have loop control conditions that suggest that you are ranging from 0 to 16, not 0 to 15. If you are, at best it is a poor coding practice. At worst, it will be a seg fault. My guess is that your seg fault is from defining a 16 x 16 2-D array and trying to use an index of 16. Valid indexes range from 0 to 15.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.