Debugging a histogram in C++ - c++

I want to build a histogram with ell intervals. The size of each interval is computed as k = ceil(m/ell) where m is the maximum number in the data set. That is, the interval i should be [(i - 1) * k, i * k). If a data set is given by the numbers 16 33 55 57 8 47 1 21 14 73 6 59 29 57 20 95 77 5 62 48 and the number of intervals is ell = 10, the histogram has to be textually represented as
0: 4
10: 2
20: 3
30: 1
40: 2
50: 4
60: 1
70: 2
80: 0
90: 1
I need to write a program, that reads in the following values (from the standard input cin) :
the number ell of intervals
the size n of the data set
n non-negative integers
Here is my code so far:
#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
int main() {
double ell;
int n; // size of the data set
double m = 0;
int * a;
int * x;
int * y;
cin >> ell;
cin >> n;
a = new int[n];
// finding max element in array a
for (int i = 0; i < n; i++) {
cin >> a[i];
if (a[i] > m) {
m = a[i];
}
}
int k = ceil(m/ell);
x = new int[(int)(ell)];
y = new int[(int)(ell)];
for (int i = 1; i <= ell; i++) {
x[i] = (i - 1) * k;
for (int j = 0; j < n; j++) {
if (a[j] >= (i - 1) * k && a[j] < i * k && x[i] != (ell - 1) * k) {
y[i] += 1;
} else if (a[j] >= (ell - 1) * k && x[i] == (ell - 1) * k) {
y[i] += 1;
} else {
y[i] += 0;
}
}
cout << x[i] << ": " << y[i] << endl;
}
delete [] a;
delete [] x;
delete [] y;
return 0;
}
If I input this:
10 20 16 33 55 57 8 47 1 21 14 73 6 59 29 57 20 95 77 5 62 48
I get
0: 4
10: 2
20: 3
30: 1
40: 2
50: 4
60: 1
70: 2
80: 0
90: 1
But if I input the same many times, I will get a weird output like
0: 4
10: 268501820
20: 1073741827
30: 112
40: 2
50: 4
60: 1
70: 2
80: 0
90: 6
Why is this happening and how can I fix my problem?

x = new int[(int)(ell)];
y = new int[(int)(ell)];
Creates objects on the heap, but unless the objects (i.e. int) have a constructor, then the memory is left uninitialized.
The array x is correctly initialized, but y is left (expected to be 0).
So the fix is ...
x = new int[(int)(ell)];
y = new int[(int)(ell)];
for( int i = 0; i < ell ; i++ ){
x[i] = 0; // tidier to do it obviously.
y[i] = 0; // essential to get y[i] += 1; to be meaningful.
}

You never initialise your memory. You create dynamic arrays with both x and y but you are not guaranteed that the memory is zeroed. You get lucky for the most part that but when there are values left in the memory your program uses you get the outliers that you see. Put something like this in and it should fix your issues.
for(int m = 0;m < (int)ell; m++) {
x[m] = 0;
y[m] = 0;
}

Related

Trying to solve Knights Tour on nested vector<vector<pair<int,int>> but is is not working

I have written a code for knights tour problem which work for 2D array but not for vector<vector<pair<int,int>>
WORKING CODE
#include <bits/stdc++.h>
#define N 8
using namespace std;
bool isPossible(int sol[N][N], int x, int y)
{
if ( sol[x][y]==-1 && x >= 0 && x < N && y >= 0 && y < N)
{
return true;
}
return false;
}
bool KNT(int sol[N][N], int moveNUM, int x, int y, int movex[8], int movey[8])
{
int i,next_x,next_y;
if (moveNUM == N * N)
{
return true;
}
for ( i = 0; i < 8; i++)
{
next_x = x + movex[i];
next_y = y + movey[i];
if (isPossible(sol, next_x, next_y))
{
sol[next_x][next_y]=moveNUM;
if (KNT(sol, moveNUM + 1, next_x, next_y, movex, movey))
{
return true;
}
sol[next_x][next_y] = -1; //Backtracking
}
}
return false;
}
int main()
{
int sol[N][N];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
sol[i][j]=-1;
}
}
int movex[8] = {2, 1, -1, -2, -2, -1, 1, 2};
int movey[8] = {1, 2, 2, 1, -1, -2, -2, -1};
KNT(sol,1,0,0,movex, movey);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cout << sol[i][j] << " ";
}
cout << endl;
}
}
NON WORKING CODE
#include <bits/stdc++.h>
#define N 8
using namespace std;
bool isPossible(vector<vector<pair<int, int>>> &Brd, int x, int y)
{
if ((Brd[x][y].first == -1) && x >= 0 && x < N && y >= 0 && y < N)
{
return true;
}
return false;
}
bool KNT(vector<vector<pair<int, int>>> &Brd, int moveNUM, int x, int y, int movex[8], int movey[8])
{
int i,next_x,next_y;
if (moveNUM == N * N)
{
return true;
}
for ( i = 0; i < 8; i++)
{
next_x = x + movex[i];
next_y = y + movey[i];
if (isPossible(Brd, next_x, next_y))
{
Brd[next_x][next_y].first = 1;
Brd[next_x][next_y].second = moveNUM;
if (KNT(Brd, moveNUM + 1, next_x, next_y, movex, movey))
{
return true;
}
Brd[next_x][next_y].first = -1;
Brd[next_x][next_y].second = 0;
//Backtracking
}
}
return false; //Check for error
}
int main()
{
vector<vector<pair<int, int>>> Brd;
for (int i = 0; i < N; i++)
{
vector<pair<int, int>> temp;
for (int j = 0; j < N; j++)
{
temp.push_back(make_pair(-1, 0));
}
Brd.push_back(temp);
}
int movex[8] = {2, 1, -1, -2, -2, -1, 1, 2};
int movey[8] = {1, 2, 2, 1, -1, -2, -2, -1};
KNT(Brd,1,0,0,movex,movey);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cout << Brd[i][j].second << " ";
}
cout << endl;
}
}
In NON WORKING code when I run the code it doesn't give any output but rather ends abruptly.
P.S. Any help will mean a lot I have already wasted around 2 days trying to find the solution for this.
Both programs have undefined behavior because you access the 2D array/vector out of bounds.
You first check if sol[x][y] == -1 and then you check if x and y are within bounds:
bool isPossible(int sol[N][N], int x, int y)
{
if (sol[x][y]==-1 && x >= 0 && x < N && y >= 0 && y < N)
You need to check the bounds first.
Your first solution should do:
if (x >= 0 && x < N && y >= 0 && y < N && sol[x][y]==-1)
Your second solution should do:
if(x >= 0 && x < N && y >= 0 && y < N && Brd[x][y].first == -1)
Note: The two programs produce different solutions. You'll have to decide which one is correct (if any).
First:
-1 59 38 33 30 17 8 63
37 34 31 60 9 62 29 16
58 1 36 39 32 27 18 7
35 48 41 26 61 10 15 28
42 57 2 49 40 23 6 19
47 50 45 54 25 20 11 14
56 43 52 3 22 13 24 5
51 46 55 44 53 4 21 12
Second:
0 59 38 33 30 17 8 63
37 34 31 60 9 62 29 16
58 1 36 39 32 27 18 7
35 48 41 26 61 10 15 28
42 57 2 49 40 23 6 19
47 50 45 54 25 20 11 14
56 43 52 3 22 13 24 5
51 46 55 44 53 4 21 12

Fill Matrix in a special order C++

I want to fill a 8 x 8 matrix with values in a special order (see example below), but I don´t know how to do that. Each numer stands for the ordering number: For example: #3 in the matrix is the third value of a e.g. a measurment I want to add.
The Order should be:
1 2 5 6 17 18 21 22
3 4 7 8 19 20 23 24
9 10 13 14 25 26 29 30
11 12 15 16 27 28 31 32
33 34 37 38 49 50 53 54
35 36 39 40 51 52 55 56
41 42 45 46 57 58 61 62
43 44 47 48 59 60 63 64
Does anybody knows an algorithmus to do that?
I have tried this, but that´s not a good way to to it, and it´s not working for the whole matrix
int b= 0, ii = 0, a = 0, iii = 0
i are different measurement values
and now a for loop
if (ii == 1)
{
b++;
}
if (ii == 2)
{
a++, b--;
}
if (ii == 3)
{
b ++;
}
tempMatrix[a][b] = i;
cout << "TempMatrix " << tempMatrix[a][b] << " a " << a << " b " << b << endl;
if (ii == 3)
{
ii = -1;
a --;
b ++;
}
if (iii == 7)
{
a = a + 2;
b = 0;
iii = -1;
}
Use recursion:
#include <iostream>
using namespace std;
void f(int a[8][8], int current, int x, int y, int size) {
if (size == 1) {
a[x][y] = current;
return;
} else {
size /= 2;
int add_for_each_square = size * size;
f(a, current, x, y, size);
f(a, current + add_for_each_square, x, y + size, size);
f(a, current + 2 * add_for_each_square, x + size, y, size);
f(a, current + 3 * add_for_each_square, x + size, y + size, size);
}
}
int main() {
int a[8][8];
f(a, 1, 0, 0, 8);
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
If the matrix will always be a fixed size, then you can generate two lookup tables for row and column indexes into the matrix. Then, just pass your index through these tables to get the desired positions in the matrix.
const auto MATRIX_SIZE = 8;
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> row_lookup = {{...}}; //put pre-computed values here.
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> col_lookup = {{...}};
for(size_t i = 0; i < MATRIX_SIZE * MATRIX_SIZE; i++)
{
auto val = get_coefficient(i);
auto row = row_lookup[i];
auto col = col_lookup[i];
mat[col][row] = val;
}

How to find antilog(base 2) of a number?

I used a for loop to find antilog of the given number.
int g = 0, m, diff = 10;
for(j = 0; g <= diff; j++)
{
g = pow(2, j);
}
m = j - 2;
cout << m;
It gives the power of 2 for which g is the number just less than diff.
I tried the base change theorem of log to find the antilog of the number something like this:
m = log(diff) / log(2);
without the for loop, but in this case whenever there is a number that is an exact multiple of 2s for example 8, then it gives 2 as the answer and not 3.
And using for loop for doing so is in a program is exceeding the time limit.
Is there a shorter and reliable way to do so?
Here is a fun solution without looping:
function antilog(int input) {
int pow2 = input - 1;
pow2 |= pow2 >> 16; // turn on all bits < MSB
pow2 |= pow2 >> 8;
pow2 |= pow2 >> 4;
pow2 |= pow2 >> 2;
pow2 |= pow2 >> 1;
pow2++; // get least pow2 >= input
return // construct binary offset of pow2 bit
((pow2 & 0xffff0000) != 0) << 4
| ((pow2 & 0xff00ff00) != 0) << 3
| ((pow2 & 0xf0f0f0f0) != 0) << 2
| ((pow2 & 0xcccccccc) != 0) << 1
| ((pow2 & 0xaaaaaaaa) != 0);
}
The latter half of which was adapted from some part of the bit twiddling hacks. (Knowing the source, there is probably some other function faster than this doing what you've asked.
Solutions aside, it should be noted that what particularly is causing your solution to be slow is the repeated calls to pow, which is a relatively expensive function. Because you are doing integer arithmetic (and what's more, multiplying by 2, every computer's favorite number), it is much more efficient to write your loop as the following:
int g=1,m,diff=10;
for(j = 0; g <= diff && g <<= 1; j++) /* empty */;
m=j-2;
cout<<m;
Which is quite the hack. int g=1 initializes g to the value it takes on the first time the code executes the body of the loop you've written. The loop conditions g <= diff && g <<= 1 evaluates to g <= diff. (Notice that this is a problem if diff >= 1 << (8 * sizeof(int) - 2), the greatest power of two we can store in an int). The empty statement simply allows us to have a well-formed for statement the compiler (mostly) won't complain about.
Use integer arithmetic and build up the power incrementally. For example:
#include <iostream>
using namespace std;
int main()
{
for (int diff = 1; diff < 129; diff += 5)
{
int p = 1;
int j;
for (j = 0; p <= diff; j++)
{
p *= 2;
}
cout << diff << " = " << (j - 1) << '\n';
}
}
Sample output:
1 = 0
6 = 2
11 = 3
16 = 4
21 = 4
26 = 4
31 = 4
36 = 5
41 = 5
46 = 5
51 = 5
56 = 5
61 = 5
66 = 6
71 = 6
76 = 6
81 = 6
86 = 6
91 = 6
96 = 6
101 = 6
106 = 6
111 = 6
116 = 6
121 = 6
126 = 6
An alternative test strategy tests boundaries:
#include <iostream>
using namespace std;
int main()
{
int diff[] = { 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65 };
int size = sizeof(diff) / sizeof(diff[0]);
for (int i = 0; i < size; i++)
{
int p = 1;
int j;
for (j = 0; p <= diff[i]; j++)
{
p *= 2;
}
cout << diff[i] << " = " << (j - 1) << '\n';
}
}
Sample output:
1 = 0
2 = 1
3 = 1
4 = 2
5 = 2
7 = 2
8 = 3
9 = 3
15 = 3
16 = 4
17 = 4
31 = 4
32 = 5
33 = 5
63 = 5
64 = 6
65 = 6
Clearly, the inside of the test loop should be wrapped into an antilog2 function — except for the printing operation.

Print 2-D Array in clockwise expanding spiral from center

I have an guaranteed to be a perfect square matrix. I want to start at the center of the matrix in this case it would be matrix[2][2], I know how to figure the center (int)(dimensions / 2). I need to output the contents of the array in this following outward spiral pattern. Of course the algorithm should work with any perfect square matrix. I wasn't sure if this algorithm already existed and I didn't want to re-invent the wheel.
int dimensions / 2;
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
The output for this example should be
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Let's identify the patterns first ..
Even-Size Square Matrix, Example: 4x4
07 > 08 > 09 > 10
^ v
06 (01)> 02 11
^ v v
05 < 04 < 03 12
v
[16]< 15 < 14 < 13
Starting Point: [2, 2] ~ [SIZE/2, SIZE/2]
Ending Point: [4, 1] ~ [SIZE, 1]
Chains: Count(K-chain)=2 for K = 1..(SIZE-2)
+ 3 for Count = SIZE-1
Odd-Size Square Matrix, Example: 5x5
21 > 22 > 23 > 24 >[25]
^
20 07 > 08 > 09 > 10
^ ^ v
19 06 (01)> 02 11
^ ^ v v
18 05 < 04 < 03 12
^ v
17 < 16 < 15 < 14 < 13
Starting Point: [2, 2] ~ [⌊SIZE/2⌋, ⌊SIZE/2⌋]
Ending Point: [1, 5] ~ [1, SIZE]
Chains: Count(K-chain)=2 for K = 1..(SIZE-2)
+ 3 for Count = SIZE-1
Live Code
void print_spiral (int ** matrix, int size)
{
int x = 0; // current position; x
int y = 0; // current position; y
int d = 0; // current direction; 0=RIGHT, 1=DOWN, 2=LEFT, 3=UP
int c = 0; // counter
int s = 1; // chain size
// starting point
x = ((int)floor(size/2.0))-1;
y = ((int)floor(size/2.0))-1;
for (int k=1; k<=(size-1); k++)
{
for (int j=0; j<(k<(size-1)?2:3); j++)
{
for (int i=0; i<s; i++)
{
std::cout << matrix[x][y] << " ";
c++;
switch (d)
{
case 0: y = y + 1; break;
case 1: x = x + 1; break;
case 2: y = y - 1; break;
case 3: x = x - 1; break;
}
}
d = (d+1)%4;
}
s = s + 1;
}
}
As this smells like homework then no code or direct answer instead just few hints:
You can look at this as an turtle problem:
Let m be movement by 1 cell and r be rotation by 90 degrees in your spiral direction (CW or CCW). then the spiral can be encoded as series of turtle commands forming this pattern (from the start point):
m,r,m,r,
m,m,r,m,m,r,
m,m,m,r,m,m,m,r,
m,m,m,m,r,m,m,m,m,r,
m,m,m,m,m,r
As you can see you start with 1x move then rotate after two repetition you switch to 2x move, after 2 moves switch to 3x move,... and so on. This can be done with just few for loops (or just by one with some proper iterations and stopping when matrix number of cells is hit ... or the endpoint corner is hit)
You need to handle even/odd matrix sizes
for odd matrix sizes is the middle point easy. For even sizes it is a bit more complicated. if you use CW rotation then use the rounded down division result of halving the size and start with moving to the right. (if you need different spiral then you need to add +1 to x and/or y and change starting direction) so the spiral will stay centered.
So If you got even sized matrix then the last movement is twice if you got odd size then the last movement is there just once (like in this example)
rotation
Have direction stored as 2D vector. for example d=(+1,0) means right. to rotate 2D vector you just swap coordinates and negate one axis (which one means the CW/CCW). For example (x,y) -> (y,-x)
movement
Store current position as 2D vector too. The movement is just adding current direction vector to it.
Have fun with solving this ...
int radius = 0;
int i = centerX;
int j = centerY;
Debug.Log("i=" + i + "; j=" + j);
++i;
radius += 2;
while ((i < dimm) && (i >= 0))
{
for (int c = j; j < c + radius; j++)
Debug.Log("i=" + i + "; j=" + j);
--j;
--i;
for (int c = i; i > c - radius + 1; i--)
Debug.Log("i=" + i + "; j=" + j);
if (i < 0)
break;
else
Debug.Log("i=" + i + "; j=" + j);
--j;
for (int c = j; j > c - radius; j--)
Debug.Log("i=" + i + "; j=" + j);
++i;
++j;
for (int c = i; i < c + radius; i++)
Debug.Log("i=" + i + "; j=" + j);
radius += 2;
}
This Code will output counterclockwise squared matrix (dimm X dimm) indexes from custom center(CenterX, CenterY); and end up, if it came out of matrix size.
bool IsIterationComplete(int iteration, int nCenter, std::vector<std::vector<bool>>& vVisited)
{
int nHigh = nCenter+iteration;
int nLow = nCenter-iteration;
//cout<<endl<<"High "<<nHigh<<"Low "<<nLow<<endl;
for(int i=nLow;i<=nHigh;i++)
{
if(!vVisited[nHigh][i] || !vVisited[nLow][i])
return false;
}
for(int i=nLow;i<=nHigh;i++)
{
if(!vVisited[i][nHigh] || !vVisited[i][nLow])
return false;
}
return true;
}
void PrintSpiral(std::vector<std::vector<int>>& vMat,std::vector<std::vector<bool>>& vVisited, int row, int col, int nCenter, int iteration)
{
cout<<vMat[row][col];
vVisited[row][col]=true;
if(row==0 && col==0)
return;
if(IsIterationComplete(iteration,nCenter,vVisited))
iteration++;
//cout<<endl<<"row "<<row<<" column "<<col<<"Iteration "<<iteration<<endl;
//left
if(col-1>=0 && !vVisited[row][col-1] && col-1>=nCenter-iteration)
{
cout<<"Left "<<endl;
PrintSpiral(vMat,vVisited,row,col-1,nCenter,iteration);
}
//Down
if((row+1)<vMat.size() && !vVisited[row+1][col] && row+1<=nCenter+iteration)
{
cout<<"Down "<<endl;
PrintSpiral(vMat,vVisited,row+1,col,nCenter,iteration);
}
//right
if((col+1)<vMat.size() && !vVisited[row][col+1] && col+1<=nCenter+iteration)
{
cout<<"Right "<<endl;
PrintSpiral(vMat,vVisited,row,col+1,nCenter,iteration);
}
//up
if(row-1>=0 && !vVisited[row-1][col] && row-1>=nCenter-iteration)
{
cout<<"Up "<<endl;
PrintSpiral(vMat,vVisited,row-1,col,nCenter,iteration);
}
}
int main (int argc, const char * argv[])
{
int nCount=1;
std::vector<std::vector<int>> vMat;
std::vector<std::vector<bool>> vVisited;
for(int i=0; i<7; i++)
{
std::vector<int> row;
std::vector<bool> visitedRow;
for(int j=0; j<7; j++)
{
row.push_back(nCount);
cout<<nCount<<'\t';
nCount++;
visitedRow.push_back(false);
}
cout<<'\n';
vMat.push_back(row);
vVisited.push_back(visitedRow);
}
cout<<'\n';
PrintSpiral(vMat,vVisited,vMat.size()/2,vMat.size()/2,vMat.size()/2,0);
return 0;
}

Heap Corruption Detected?

void allocateTriangle(int ** & twoDArray, int numRows);
void printTriangle(int ** twoDArray, int numRows);
void growToSquare(int ** & twoDArray, int numRows);
void printSquare(int ** & twoDArray, int numRows);
using namespace std;
int main(int argc, char ** argv){
srand((unsigned int)time(NULL));
int ** twoDArray;
int numRows = 10;
allocateTriangle(twoDArray, numRows);
cout << "******* Triangle array *******" << endl;
printTriangle(twoDArray, numRows);
growToSquare(twoDArray, numRows);
cout << "******* Sqaure array *******" << endl;
printSquare(twoDArray, numRows);
return 0;
}
void allocateTriangle(int ** & twoDArray, int numRows) {
twoDArray = new int*[numRows];
for (int x = 0; x < numRows; x++){
twoDArray[x] = new int[x];
for (int y = 0; y <= x; y++){
twoDArray[x][y] = rand() % 100;
}
}
}
void printTriangle(int ** twoDArray, int numRows){
for (int x = 0; x < numRows; x++){
for (int y = 0; y <= x; y++){
cout << setw(5);
cout << twoDArray[x][y];
}
cout << endl;
}
}
void growToSquare(int ** & twoDArray, int numRows) {
for (int x = 0; x < numRows; x++){
int *tempArray = new int[x];
*tempArray = *twoDArray[x];
--> delete [] twoDArray[x];
twoDArray[x] = new int[numRows];
for (int y = 0; y < numRows; y++){
if (y <= x)
twoDArray[x][y] = tempArray[y];
else
twoDArray[x][y] = rand() % 100;
}
}
}
void printSquare(int ** & twoDArray, int numRows){
for (int x = 0; x < numRows; x++){
for (int y = 0; y <= numRows; y++){
cout << setw(5);
if (y <= x)
cout << twoDArray[x][y];
else if (y - 1 == x)
cout << " ";
else
cout << twoDArray[x][y - 1];
}
cout << endl;
}
}
The arrow is pointing to where this program likes to crash. Giving me a Heap Corruption, I've spent the last 6 hours looking at this and other posts, I got nothing.
The main gets to growToSquare() and when I try to 'resize' the 2D array by deletion and allocation again, it stopes at deletion. I've commented out other lines to code to see if something else is triggering, nada.
Any words of advice? (I am using Visual studio 2013)
WhozCraig spotted it, in his comment above.
y <= x should be y < x, in multiple places in this code. – WhozCraig
Imagine that numRows is 1 here, for the sake of simplicity. Follow the code logic in that simple case.
void allocateTriangle(int ** & twoDArray, int numRows) {
twoDArray = new int*[numRows];
for (int x = 0; x < numRows; x++){
twoDArray[x] = new int[x];
for (int y = 0; y <= x; y++){
twoDArray[x][y] = rand() % 100;
}
}
}
Here is the code that would execute, which assigns to a zero-length array.
twoDArray = new int*[1];
twoDArray[0] = new int[0];
twoDArray[0][0] = rand() % 100;
Memory has now been corrupted.
Plausible Solution for Triangle Allocation
Though there a about a half-dozen different ways to calculate the indices, this way is likely the easiest to understand.
void allocateTriangle(int ** & twoDArray, int numRows)
{
twoDArray = new int*[numRows];
for (int x = 0; x < numRows; x++)
{
twoDArray[x] = new int[x+1]; // NOTE: size
for (int y = 0; y <= x; y++)
twoDArray[x][y] = rand() % 100;
}
}
void printTriangle(int ** twoDArray, int numRows)
{
for (int x = 0; x < numRows; cout << endl, ++x)
for (int y = 0; y <= x; y++)
cout << setw(5) << twoDArray[x][y];
}
This allows you to keep your indexing (mostly) while sizing the allocations to appropriate lengths.
Growing a Triangle Into A Square
Similarly, the following will extend your triangle into a square. Note: you can invoke this on something already extended to a square. It will simply re-random-generate the right-half diagonal when doing so (and rather expensively at that).
void growToSquare(int ** & twoDArray, int numRows)
{
for (int x = 0; x < numRows; x++)
{
int *tempArray = new int[numRows];
for (int y=0; y<=x; ++y)
tempArray[y] = twoDArray[x][y];
for (int y=x+1; y<numRows; ++y)
tempArray[y] = rand() % 100;
delete [] twoDArray[x];
twoDArray[x] = tempArray;
}
}
void printSquare(int ** & twoDArray, int numRows)
{
for (int x = 0; x < numRows; cout << endl, ++x)
for (int y = 0; y < numRows; y++)
cout << setw(5) << twoDArray[x][y];
}
Output
Using the above methods, your output will look something like this. Obviously the random nature will result in different values, but the important thing is the bottom-left portion of the square retains the original triangle.
******* Triangle array *******
80
80 1
45 93 28
19 96 90 7
38 70 23 26 98
97 26 98 48 37 97
77 25 43 0 28 84 90
95 78 48 16 23 30 14 64
14 29 83 60 7 83 14 77 94
79 1 43 55 22 14 80 34 40 53
******* Sqaure array *******
80 10 62 17 62 94 62 47 87 3
80 1 56 67 56 91 85 51 25 8
45 93 28 9 42 57 95 56 19 42
19 96 90 7 46 67 42 77 53 73
38 70 23 26 98 53 22 34 69 3
97 26 98 48 37 97 8 18 53 55
77 25 43 0 28 84 90 7 82 43
95 78 48 16 23 30 14 64 94 33
14 29 83 60 7 83 14 77 94 75
79 1 43 55 22 14 80 34 40 53