I'm trying to create random coordinates but to make sure they aren't used I decided to create a 2D array initialized at 0 to show each space is empty.
I'm using this function for the randomness:
int randomNoGenerator(int limit)
{
std::random_device r;
std::default_random_engine e1(r());
std::uniform_int_distribution<int> uniform_dist(1, limit);
int rand = uniform_dist(e1);
return rand;
}
And my main:
int main(void)
{
int numRows = 5;
int numCols = 7;
int **occupiedSpace;
occupiedSpace = (int **)calloc(numRows, sizeof(int *));
for (int i = 0; i < numRows; i++)
occupiedSpace[i] = (int *)calloc(numCols, sizeof(int));
for (int i = 0; i < 5; i++)
{
int x;
int y;
int match = 1;
x = randomNoGenerator(numCols);
y = randomNoGenerator(numRows);
//This is where the crash is happening?
occupiedSpace[x][y] = 1;
}
return 0;
}
My ultimate goal was to have something like where if it's empty it just replaces it with a 1. Otherwise it keeps generating X, Y if it's already occupied.
while (match)
{
x = randomNoGenerator(numCols);
y = randomNoGenerator(numRows);
if(occupiedSpace[x][y] = 0)
{
occupiedSpace[x][y] = 1;
match = 0;
}
}
You're generating your x and y coordinate the wrong way round. The outer index is the row, the inner index is the column, so you should do:
x = randomNoGenerator(numRows); // instead of numCols
y = randomNoGenerator(numCols); // instead of numRows
Then, you set up your random generator with wrong numbers. It should be uniform_dist(0, limit - 1) instead of uniform_dist(1, limit) since row and column indexing starts at 0.
You can also use std:array instead calloc :
std::array<std::array<int,5>,7> occupiedSpace;
for ( int i = 0; i < numCols; i++)
{ for (int j = 0; j < numRows; j++) occupiedSpace[i][j] = 0 ;
}
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]
Ok, im starting c++ and i want to assign a value to a specific position in a vector of a vector. I have done it with an array of array (2D) but now would like to do it with vectors.
int main() {
int newLine = 10;
int newColumm = 10;
const string WALL = "\u2588";
cout << endl;
string grille[10][10];
for (int j = 0; j < newColumm + 1; j++) {
int i = 0;
grille[i][j] = WALL;
}
for (int j = 0; j < newColumm + 1; j++) {
int i = newLine + 1;
grille[i][j] = WALL;
}
I would like to do the same thing with vectors.
I Have :
int main() {
int newLine = 10;
int newColumm = 10;
const string WALL = "\u2588";
cout << endl;
// string grille[10][10];
vector<vector<string>> grille;
for (int j = 0; j < newColumm + 1; j++) {
int i = 0;
grille.at(i).at(j) = WALL;
}
for (int j = 0; j < newColumm + 1; j++) {
int i = newLine + 1;
grille.at(i).at(j) = WALL;
}
It's obviously not working for the moment.
(Sorry for my bad language, english is my second language...)
Your vector has no size. You are getting a std::range_error exception when you access the vector out-of-bounds. Since you are not handling exceptions, your program crashes.
The naive fix for this is to simply pre-allocate your vector to the dimensions you expect:
vector<vector<string>> grille(10, std::vector<string>(10));
Note that your for-loops will naturally overshoot anyway and you'll still get an exception, since they are actually looping to 10 inclusive. Remember that if you have 10 elements, then the valid indices are 0 to 9 inclusive.
I want to make the values of num[] replace all of the a[][] values when one of the numbers equal k. So all the values of num correspond to each place at k. So for example when k reaches 20 if there is a 20 in the 2d array I want to replace all 20's with whatever is in num[19], but whenever I try it that, they all become skewed numbers and I can't find the reason why. Are my for loops set up wrong or what else could be the problem?
#include<iostream>
int main(){
//other code that uses a file to make 2d array
int width, height, maxval;
fin >> P2 >> width >> height >> maxval;
int **a = new int *[height];
for (int i = 0; i < height; i++)
a[i] = new int[width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
fin >> a[i][j];
}
}
}
void eq(int **a, int h, int w) {
int num[255];
double num1[255];
double prob[255], cumul[255]{ 0 };
double x, y, z=0;
for (int k = 1; k <= 255; k++)
{
int temp = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {//counts the repeated pixel values
if (pix[i][j] == k)
{
temp += 1;
}
}
}
num1[k - 1] = temp;
}
for (int i = 0; i < 255; i++) {
prob[i] = (num1[i] / (height*width));//show the decimal number of how many pixel values are in the image over the total
cout << prob[i] << endl;
}
for (int i = 0; i < 255; i++) {
y = prob[i];
x = y + z;
z = x;// adds all the probabilities to make the sum
cumul[i] =x;
cout << cumul[i] << endl;
}
for (int i = 0; i < 255; i++) {
num[i] =floor(cumul[i]*255);// converts the cumulative number to the new pixel value and sets it in a array
}
for (int k = 1; k <= 255; k++) {//loop that is not coming out right
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (a[i][j] == k)
{
a[i][j] =num[k-1];
}
}
}
}
}
Basically I am making a function that deals with histogram equalization to make a pgm image clearer. In the main function I am calling a pgm file and setting all the pixel values into a 2d array. So the num[] is the part where I make the new pixel values, but for some reason whenever I call for example a[0][0] I should be getting something that is not zero or 255 since both of those values mean that none of the pixels had that corresponding intensity, but whenever I call it I get 255 or some other random number.
If i understand what you want to do, this line :
a[i][j] =num[i];
should be :
a[i][j] =num[k-1];
Because you want:
if( a[i][j] = k = 20){
a[i][j] = num[k-1 = 19]
}
I put in my program two loops - one fills 2D array with one value N0, and next loop is generating random number. And my program does not work when I have loop for array. I get "Unhandled exception... (parameters: 0x00000003)". But without first loop it works correctly. Thanks for help.
#include <iostream>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
using namespace std;
const double czas = 1E9;
int main()
{
//Declaration of variables
const int k = 20;
const int L = 30;
double N0 = 7.9E9;
int t,i,j, WalkerAmount;
double excitation, ExcitationAmount;
double slab[30][600];
//Random number generator
boost::random::mt19937 gen;
boost::random::uniform_int_distribution<> numberGenerator(1, 4);
//Filling slab with excitation
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++) { slab[i][j] = N0; }
}
//Time loop
for (t = 0; t < czas; t++) {
WalkerAmount = 0;
ExcitationAmount = 0;
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++)
{
int r = numberGenerator(gen);
cout << r << endl;
}
}
}
system("pause");
return 0;
}
Arrays in C++ are indexed from 0 to n-1 where n is the capacity of the array. Then, the code following code is wrong.
int main()
{
//Declaration of variables
const int k = 20;
const int L = 30;
double N0 = 7.9E9;
double slab[30][600];
// [...]
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++) { slab[i][j] = N0; }
}
}
When you initialize your array, you always go one steep too far. As you consider the case where i == L and j == k*L you reach an area in the memory that out of your array.
The loop you want to execute is
for (int i = 0; i < L; i++)
for (int j = 0; j < k*L; j++)
// Initialize
i have a simple program for operations with matrixies, but i have a problem -> i have for example array[3][3] and i need some way how to get the number of dimensions- in this case 3, here is the code:
#include <stdio.h>
#include <stdlib.h>
int **count()
{
printf("Write number of rows and collumns in format ROWS space COLLUMNS");
int i = 0;
int j = 0;
scanf("%i %i", &i, &j);
int **mat1 = (int**)malloc(i*sizeof(int*));
for (int x = 0; x < j;x++){
mat1[x] = (int*)malloc(j*sizeof(int));
}
for (int x = 0; x < i;x++){
for (int y = 0; y < j;y++){
scanf("%i",&mat1[x][y]);
}
}
printf(Write number of rows and collumns in format ROWS space COLLUMNS");
int i2 = 0,j2 = 0;
scanf("%i %i", &i2, &j2);
int **mat2 = (int**)malloc(i2*sizeof(int*));
for (int x2 = 0; x2 < j2;x2++){
mat2[x2] = (int*)malloc(j2*sizeof(int));
}
for (int x2 = 0; x2 < i2;x2++){
for (int y2 = 0; y2 < j2;y2++){
scanf("%i",&mat2[x2][y2]);
}
}
int i3 = i, j3 = j;
int **mat3 = (int**)malloc(i3*sizeof(int*));
for (int x = 0; x < j3;x++){
mat3[x] = (int*)malloc(j3*sizeof(int));
}
for (int x3 = 0; x3 < i3;x3++){
for (int y3 = 0; y3 < j3;y3++){
mat3[x3][y3] = mat1[x3][y3] + mat2[x3][y3];
}
}
return mat3;
}
int writeMatrix(int **mat, int rows, int collumns)
{
int i = rows, j=collumns;
for (int x = 0; x < i;x++){
for (int y = 0; y < j;y++){
printf("%3i ",mat[x][y]);
}
printf("\n");
}
return 0;
}
int main()
{
int **m1 = count();
writeMatrix(m1,x,x);//HERE I NEED TO KNOW NUMBER OF ROWS AND COLLUMNS
free(m1);
}
Here is the code which worked for me in a case of normal array[][] but not in this case -
int y = (sizeof(m1)/sizeof(m1[0][0])) / (sizeof(m1)/sizeof(m1[0]));
You can't have a multidimensional array if you don't knwo statically the size of the first dimension, you'll need a jagged array (an array of arrays), as you did it.
And then you can still get the number of allocated rows and columns. Change the count prototype to:
int** count(int& rows, int& columns)
and in it do these assignments (after you've read the values of i and j):
rows = i;
columns = j;
And call count from main like this:
int rows;
int columns;
int** m1 = count(rows, columns);
Then you can call writeMatrix:
writeMatrix(m1, rows, columns);
BTW, unless you're doing this for educational purposes, you should use std::vector<std::vector<int>> (or some similar array class), not int**.