I have a float** array that contains num_rows rows and num_cols columns. I'd like to determine the number of occurrences of every number between 0-9 columnwise. To do this, I thought of using another 2D array of size [10][num_cols], so that for each column the number corresponding to an element is the number of occurrences of that number in the original table.
Example: if the original table contains 1 2 3 1 1 in the fifth column, then in the second column, the values should be like: 1-> 3, 2 -> 1, 3 -> 1.
I tried using the function as follows, but it gives me a pointer error. I tried using vectors but that too brings no luck.
int ** attribute_count(float * * input, int row_num, int col_num) {
int ** arr_2 = new int * [10];
int * arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i][j] = 0;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
EDIT:
I tried your suggestions. The new code is:
int** attribute_count(float** input, int row_num, int col_num) {
int** arr_2 = new int* [10];
int* arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i] = new int[col_num];
}
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
This still gives me memory errors. The function is being called in the .cpp like this:
int** attr = attribute_count(training_data, 10, num_cols_train);
cout<<attr[5][1];
Any idea what I'm doing wrong even now?
I think your problem is in incorrect allocation of the 2D array. Try
int ** arr_2 = new int* [row_num];
for (int i = 0; i < row_num; i++)
arr_2[i] = new int[col_num];
You've only allocated one dimension of arr_2. You need to loop through and allocate an array of ints on each one to get the 2nd dimension.
EDIT: Also, what's up with arr? You allocate it, never use it, don't return it, and don't deallocate it. That's how we spell memory leak.
arr_2 is defined and allocated as an array of pointers to int, but you don't actually assign/allocate those pointers.
Here's a stab at correcting your code - however I'm not convinced you have rows and columns the right way around...
int ** attribute_count(float ** input, int row_num, int col_num)
{
int ** arr_2 = new int * [10];
for (int i = 0; i < 10; i++)
{
arr_2[i] = new int[col_num];
for(int j = 0 ; j < col_num ; j++)
{
arr_2[i][j] = 0;
}
}
for (int i = 0; i < row_num; i++)
{
for (int j = 0; j < col_num; j++)
{
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
Related
So I got a function which creates me 2D array and fill it with test data.
Now I need to assign the pointer to an array
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
int arr[m][n];
//Algorithm - transpose
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
arrT[j][i] = arr[i][j];
}
}
Is there any way of doing this?
There are at least four problems with the function.
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
First of all you declared a variable length array
int arr[n][m];
Variable length arrays are not a standard C++ feature.
The second problem is that these for loops
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
are incorrect. It seems you mean
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
*((ptr+i*m)+j) = rand()%10;
}
}
You are returning a pointer to a local array with automatic storage duration that will not be alive after exiting the function. So the returned pointer will be invalid.
And arrays do not have the assignment operator.
Instead use the vector std::vector<std::vector<int>>. For example
std::vector<std::vector<int>> testArrData(int m, int n){
std::vector<std::vector<int>> v( n, std::vector<int>( m ) );
for ( auto &row : v )
{
for ( auto &item : row )
{
item = rand() % 10;
}
}
return v;
}
This is how I would accomplish this. I agree with int ** because it is easy to understand if you dont know how to use vectors. Also, the rand() can cause trouble if you are using the result to index an array. Make sure to use abs(rand() % number) if you don't want negative numbers.
I've updated the answer due to some vital missing code.
// This method creates the overhead / an array of pointers for each matrix
typedef int* matrix_cells;
int **create_row_col_matrix(int num_rows, int num_cols, bool init_rnd)
{
num_rows = min(max(num_rows, 1), 1000); // ensure num_rows = 1 - 1000
num_cols = min(max(num_cols, 1), 1000); // ensure num_cols = 1 - 1000
int *matrix_total = new int[num_rows*num_cols];
// overhead: create an array that points to each row
int **martix_row_col = new matrix_cells[num_rows];
// initialize the row pointers
for (int a = 0; a < num_rows; ++a)
{
// initialize the array of row pointers
matrix_row_col[a] = &matrix_total[num_cols*a];
}
// assign the test data
if (init_rnd)
{
for (int run_y = 0; run_y < num_rows; ++run_y)
{
for (int run_x = 0; run_x < num_cols; ++run_x)
{
matrix_row_col[run_y][run_x] = abs(rand() % 10);
}
}
}
return matrix_row_col;
}
int src_x = 7, dst_x = 11;
int src_y = 11, dst_y = 7;
int **arr_src = create_row_col_matrix(src_y, src_x, true);
int **arr_dst = create_row_col_matrix(dst_y, dst_x, false);
for (int a = 0; a < dst_y; ++a)
{
for (int b = 0; b < dst_x; ++b)
{
arr_dst[a][b] = arr_src[b][a];
}
}
delete matrix_src[0]; // int *matrix_total = new int[src_y*src_x]
delete matrix_src; // int **matrix_row_col = new matrix_cell[src_y]
delete matrix_dst[0]; // int *matrix_total = new int[dst_y*dst_x]
delete matrix_dst; // int **matrix_row_col = new matrix_cell[dst_y]
// the overhead is matrix_src and matrix_dst which are arrays of row pointers
// the row pointers makes it convenient to address the cells as [rown][coln]
I figured out how to make this one work already but can't explain in details what is so different in these two codes here.
Incorrect code:
const int nRows = 2;
const int nCols = 2;
int * colSum (int [nRows][nCols]);
int * rowSum (int [nRows][nRows]);
int main() {
int my2Darray[nRows][nCols] = {{10, 20}, {30, 40}};
int totalsByColumn[nCols] = {};
*totalsByColumn = *(colSum(my2Darray));
for (int i = 0; i < nCols; i++) {
cout << totalsByColumn[i] << endl;
}
}
int * colSum (int arrayArg[nRows][nCols]) {
static int arr[nRows] = {};
for (int i = 0; i < nCols; i++) {
for (int rowcount = 0; rowcount < nRows; rowcount++) {
arr[i] += arrayArg[rowcount][i];
}
}
return arr;
}
I was getting 40 0 as the output.
Then I fixed it by doing this:
int main() {
int my2Darray[nRows][nCols] = {{10, 20}, {30, 40}};
int *totalsByColumn = colSum(my2Darray);
for (int i = 0; i < nCols; i++) {
cout << totalsByColumn[i] << endl;
}
}
Output is 40 60, just what I wanted.
Was I just decaying to the first element of totalsByColumn by using the dereference operator on my first block of code? I feel like there might be a quicker way of adding the columns and rows together and assigning them to arrays in the main function, but as long as it does what I want I'm okay with that for the moment.
Was I just decaying to the first element of totalsByColumn by using the dereference operator on my first block of code?
Yes.
I feel like there might be a quicker way of adding the columns and rows together
Certainly. Also ways that are thread safe unlike your solution. A simple way is to use an output iterator to write directly to the array where you want the results:
int* colSum (int arrayArg[][nCols], int out[]) {
for (int i = 0; i < nCols; i++) {
out[i] = 0;
for (int rowcount = 0; rowcount < nRows; rowcount++) {
out[i] += arrayArg[rowcount][i];
// ...
int totalsByColumn[nCols];
colSum(my2Darray, totalsByColumn);
for my assignment I have to multiply two matrices together to create a new one. I will then sort the new one from an inherited class. My question is what is the format to multiply two arrays of different dimensions my first one a1d is 5 integers. My other one a2d is a 5x10 array. What is the correct way to multiply these together being that they are different sizes and dimensions. Do I multiply a1d by every row of a2d? I am going to output the products to a 1 dimensional array so that sorting is easier. I have drawn out the two arrays as tables to help me visualize it. I will attach the short code I have and my illustration. This is in C++.
#pragma once
#include<ctime>
#include<iostream>
#include<cmath>
using namespace std;
class matrices
{
private:
int* a1d[5]; // Old Code:int* a1d = new int[5];
int** a2d = new int* [5];
public:
int* matrix;
matrices();
~matrices();
int* filla1d();
int* filla2d();
int* multiply();
};
int* matrices::filla1d() {
for (int i = 0; i < 5; i++) {
a1d[i] = new int;
}
for (int i = 0; i < 5; i++) {
*a1d[i] = rand() % 10 + 1;
}
return *a1d;
}
int* matrices::filla2d() {
for (int i = 0; i < 5; i++) {
a2d[i] = new int[10];
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = rand() % 10 + 1;
cout << a2d[i][j] << endl;
}
}
return *a2d;
}
int* matrices::multiply() {
}
it is required that I only use pointer type variables and pointer returning functions, though that doesn't change too much. I don't know how they should be multiplied, and because of that, I am not sure how many values will be generated from the multiplication for the size of the new array. Thanks in advance!
Here is what I have designed to multiply them together. I have changed how my pointer arrays are allocated. My problem now is that it tells me that "expression must have arithmetic or unscoped enum type". Where I have matrix[i] =(a1d[index1] * a2d[index1][index2]); I thought maybe a1d needed to be a pointer type but it gives me the error where it can't convert from int* to int.
Also, when I debug, my a1d and matrix arrays allocate perfectly and show the correct number of data slots when moused over. However, a2d only shows one pointer which points to 5 in this case. I followed the syntax I have seen online for an array of pointers to create a 2d array.
int* matrices::filla1d() {
for (int i = 0; i < 5; i++) {
a1d[i] = new int;
}
for (int i = 0; i < 5; i++) {
*a1d[i] = rand() % 10 + 1;
}
return *a1d;
}
int* matrices::filla2d() {
for (int i = 0; i < 5; i++) {
a2d[i] = new int[10];
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = rand() % 10 + 1;
}
}
return *a2d;
}
int* matrices::multiply() {
for (int i = 0; i < 50; i++) {
matrix[i] = new int;
}
int index1 = 0;
int index2 = 0;
for (int i = 0; i < 50; i++) {
matrix[i] = (a1d[index1] * a2d[index1][index2]);
index1++;
index2++;
}
return *matrix;
}
class matrices
{
private:
int* a1d[5];
int** a2d = new int*[5];
public:
int* matrix[50];
matrices();
~matrices();
int* filla1d();
int* filla2d();
int* multiply();
};
Edit 2:
I changed the line to fill up the new matrix to say
*matrix[i] = a2d[index1][index2] * *a1d[index1];
Now I get an access violation error on this line. I have matrix allocated the same way I have a1d allocated, what can cause my access violation?
I'm trying to run through a 2-dimensional array and update values using a pointer to pointer to int.
Swap function:
void foo(int ** vacancies, int **transfers, int transfer)
{
for (int i = 0; i < transfer; i++)
{
(*transfers[i]) = 0;
(*vacancies[i]) = 2;
}
}
Declaration:
int ** vacancies = new int*[getVacancies(grid)];
int ** transfers = new int*[transfer];
Function call:
foo(vacancies, transfers, transfer);
Unfortunately this doesn't seem to actually update any values, is there something I need to change? Thanks!
Edit:
getVacancies(vacancies, grid, transfer);
getTransfers(transfers, grid, transfer);
void getVacancies(int ** vacancies, int grid[][ROW], int vCount)
{
for (int i = 0; i < vCount; i++)
{
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (grid[col][row] == 0)
{
vacancies[i] = &grid[col][row];
}
}
}
}
}
And the same for getTransfers.
Edit 2:
void getVacancies(int ** vacancies, int grid[][ROW], int vCount)
{
int i = 0;
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (grid[col][row] == 0)
{
vacancies[i] = &grid[col][row];
i++;
}
}
}
}
You have allocated only "one dimension". Those int* elements should point to arrays of int or just ints. Dereferencing these uninitialized pointers is undefined behavior.
I think this is how you need to initialize your array. You shouldn't loop through vacancies, because that will fill each element with a pointer to the same element of grid (the last vacant one). Instead, you just want to loop through grid, and add each vacant element to the next entry in vacancies.
I've also changed the function to return the number of elements that were filled in. Alternatively, you could initialize vacancies to nullptr in each element, and test for this when looping through it later.
int getVacancies(int ** vacancies, int grid[][ROW], int vCount)
{
int i = 0;
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (grid[col][row] == 0)
{
if (i >= vCount) { // Prevent overflowing vacancies
return i;
}
vacancies[i++] = &grid[col][row];
}
}
}
return i;
}
Allocate a two dimensional array like this (see How do I declare a 2d array in C++ using new?):
int** twoDimensionalArray = new int*[rowCount];
for (int i = 0; i < rowCount; ++i) {
twoDimensionalArray[i] = new int[colCount];
}
I'm currently reading Jumping into C++ by Alex Allain and am stuck on Chapter 14's Practice Problem number 1.
Write a function that builds a two-dimensional multiplication table with arbitrary sizes for two dimensions.
I'm having trouble actually assigning the times table to the array but all these nested loops are giving me a headache! I'm getting an output of "999999999".
My Code:
#include <iostream>
using namespace std;
int main()
{
int **p_p_tictactoe;
p_p_tictactoe = new int*[3];
for (int i = 0; i < 3; i++)
p_p_tictactoe[i] = new int[3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
p_p_tictactoe[i][j] = 1;
for (int y = 0; y < 4; y++)
{
for (int t = 0; t < 4; t++)
{
p_p_tictactoe[i][j] = y * t;
}
}
cout << p_p_tictactoe[i][j];
}
}
cin.get();
for (int i = 0; i < 3; i++)
delete[] p_p_tictactoe[i];
delete[] p_p_tictactoe;
}