I am attempting to print out a histogram of values that correspond to the amount of times a pixel value appears in a .pgm file. I know I am reading in the values correctly, it's when I try to print them where I have issues.
int pixelHold[product];
for(long int i = 0; i < product; i++)
{
pixelHold[pixels[i]]++;
//cout << pixels[i] << ' ' << endl;
}
for(long int j = 0; j < product; j++)
{
cout << pixelHold[j] << ' ';
}
"product" is the Width x Height pixel value, which corresponds to the size of the vector I'm using to store all of the values. "pixelHold" is just an array that I'm using to increment every time it comes across a pixel value. For example, it if came across "222" 3 times, it would print a "3" for the "222" slot.
However, the issue is that, when I print the histogram, I get a bunch of zeroes, and then garbage for the last 100 slots or so. When I change the parameters of the for loop to a smaller number, like "221", it prints out the correct histogram up to that point.
Any help is much appreciated!
You always need to initalize your arrays - otherwise they contain absolutely arbitrary contents - the contents of RAM where the compiler decided to put your array.
Also, your histogram table should have the dimensions of 256 - since that's how many (8-bit) colors there are in a greyscale image.
The following code should do the trick:
const int histogramLevels = 256;
int pixelHold[histogramLevels];
for (int i=0; i<histogramLevels; i++) pixelHold[i] = 0;
for(long int i = 0; i < product; i++)
{
pixelHold[pixels[i]]++;
//cout << pixels[i] << ' ' << endl;
}
for (int i=0; i<histogramLevels; i++) {
cout << pixelHold[j] << ' ';
}
Related
code can be run/compiled here https://onlinegdb.com/9yhzLeVu3
this code will only print value 4 for all the values if tested on a 2x2 matrix
[1][2]
[3][4]
I believe its with the cout statement, I am fairly convinced it is saving the values to the matrix but, am not seeing it print correctly.
If could please tell me what I am not seeing? this syntax is very new to me, this program functions as functional programming but, is difficult once I start converting it to methods/functions.
#include <iostream>
using namespace std;
// Create a matrix based graph representation.
// It will need to support the following operations.
// Ask the user how many points there are. DONE
// Ask the user to label those points, ie "ABC", "XYZ", "C12"... DONE
// Define the matrix as a square matrix (2 dimensional array) based on the number of points, also keep an array of the labels. DONE
// Repeatedly ask the user to define edges between two points. Add these edges to the matrix. DONE
// Have a list method that will list out all of the edges in the graph.
// REFERENCE
// https://www.geeksforgeeks.org/how-to-access-elements-of-a-square-matrix/
// https://www.geeksforgeeks.org/comparison-between-adjacency-list-and-adjacency-matrix-representation-of-graph/
// https://www.cplusplus.com/reference/utility/make_pair/
// https://www.tutorialspoint.com/cplusplus-program-to-implement-adjacency-matrix
// https://stackoverflow.com/questions/2828648/how-to-pass-a-multidimensional-array-to-a-function-in-c-and-c
// https://www.techiedelight.com/pass-2d-array-function-parameter-cpp/
// https://www.tutorialspoint.com/Passing-two-dimensional-array-to-a-Cplusplus-function
// https://stackoverflow.com/questions/71907069/my-print-function-does-not-print-correctly-when-passing-a-2d-array-please-tell/71907317#71907317
// one possible implementation would be make pair to track the label for edge cout statement for user input
// Code is formatted to be best read with labels the size of 3 this is hard coded per implementation requirements.
int main()
{
// PROTOTYPE
void printMatrix(string *labelArray, int *matrix, int rowIndex, int columnIndex, int size);
int size ;
cout << "How many points would you like this to be. Points meaning -size- of matrix: ";
cin >> size;
// example 2x2 matrix
// A B
// A [][]
// B [][]
// determine size, and modulo to create matrix form
string label; // labeling convention for determining assignments
string labelArray[size]; // label containing array to track for printing and labeling purposes
int edgeYesOrNo;
int counter = 0;
cout << "Will now ask to label the points of graph matrix.\n";
int *matrix = new int[size * size]; // this is how to define a 2d array
int rowIndex; // these are to access individual elements
int columnIndex; // ^^
for(int i=0; i<size; i++)
{
cout << "Enter label: "; // enter the label here to insure that there is no redundancy
cin >> label;
labelArray[i] = label;
}
// Get the square matrix
cout << "Enter 1 for edge 0 for no edge" << endl;
for (rowIndex = 0; rowIndex < size; rowIndex++)
{
for (columnIndex = 0; columnIndex < size; columnIndex++)
{
cout << "Is there an edge to: " << labelArray[counter] << " and " << labelArray[columnIndex] << ": ";
cin >> edgeYesOrNo;
matrix[rowIndex * size + columnIndex] = edgeYesOrNo;
}
counter++;
}
printMatrix(labelArray, matrix, rowIndex, columnIndex, size);
delete[] matrix;
return 0;
}
// Display the matrix
void printMatrix(string *labelArray, int *matrix, int rowIndex, int columnIndex, int size)
{
cout << "The matrix is\n" << endl;
cout << " ";
for(int i=0; i<size; i++)
{
cout << labelArray[i] << " "; // To print the labels so its understandable
}
cout << endl;
for (rowIndex = 0; rowIndex < size; rowIndex++)
{
cout << labelArray[rowIndex] << " ";
for (columnIndex = 0; columnIndex < size; columnIndex++)
{
cout << matrix[rowIndex * size + columnIndex] << " ";
}
cout << endl;
}
return;
}
What do you think these lines are going to do:
matrix[size * size] = edgeYesOrNo;
cout << matrix[size * size] << " ";
I find it far more likely you need rowIndex * size + colIndex in both places.
I'll explain the difference. You've already allocated your array when you did this:
int *matrix = new int[size * size];
This is not a 2D array. It's a single dimension array. But that's okay. If size is four, size * size is 16, so you allocated space for 16 integers.
matrix[rowIndex * size + colIndex]
This is how I use it in both my places. What this means is you'll store them kind of like this:
[ 0][ 1][ 2][ 3]
[ 4][ 5][ 6][ 7]
[ 8][ 9][10][11]
[12][13][14][15]
That is, row 0, col 0 is thus in the 0'th index. row 1, col 1, is in the row * size + col location, or 5.
Does that make sense now?
C++ doesn't actually have 2D arrays. You can simulate it. This is one way to do so.
What you were doing was using (for size == 4) the 16th spot each time, which is actually one slot past the end. You were stepping on who knows what.
So I've been working on problem 15 from the Project Euler's website , and my solution was working great up until I decided to remove the cout statements I was using for debugging while writing the code. My solution works by generating Pascal's Triangle in a 1D array and finding the element that corresponds to the number of paths in the NxN lattice specified by the user. Here is my program:
#include <iostream>
using namespace std;
//Returns sum of first n natural numbers
int sumOfNaturals(const int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
return sum;
}
void latticePascal(const int x, const int y, int &size)
{
int numRows = 0;
int sum = sumOfNaturals(x + y + 1);
numRows = x + y + 1;
//Create array of size (sum of first x + y + 1 natural numbers) to hold all elements in P's T
unsigned long long *pascalsTriangle = new unsigned long long[sum];
size = sum;
//Initialize all elements to 0
for (int i = 0; i < sum; i++)
{
pascalsTriangle[i] = 0;
}
//Initialize top of P's T to 1
pascalsTriangle[0] = 1;
cout << "row 1:\n" << "pascalsTriangle[0] = " << 1 << "\n\n"; // <--------------------------------------------------------------------------------
//Iterate once for each row of P's T that is going to be generated
for (int i = 1; i <= numRows; i++)
{
int counter = 0;
//Initialize end of current row of P's T to 1
pascalsTriangle[sumOfNaturals(i + 1) - 1] = 1;
cout << "row " << i + 1 << endl; // <--------------------------------------------------------------------------------------------------------
//Iterate once for each element of current row of P's T
for (int j = sumOfNaturals(i); j < sumOfNaturals(i + 1); j++)
{
//Current element of P's T is not one of the row's ending 1s
if (j != sumOfNaturals(i) && j != (sumOfNaturals(i + 1)) - 1)
{
pascalsTriangle[j] = pascalsTriangle[sumOfNaturals(i - 1) + counter] + pascalsTriangle[sumOfNaturals(i - 1) + counter + 1];
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <--------------------------------------------------------
counter++;
}
//Current element of P's T is one of the row's ending 1s
else
{
pascalsTriangle[j] = 1;
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <---------------------------------------------------------
}
}
cout << endl;
}
cout << "Number of SE paths in a " << x << "x" << y << " lattice: " << pascalsTriangle[sumOfNaturals(x + y) + (((sumOfNaturals(x + y + 1) - 1) - sumOfNaturals(x + y)) / 2)] << endl;
delete[] pascalsTriangle;
return;
}
int main()
{
int size = 0, dim1 = 0, dim2 = 0;
cout << "Enter dimension 1 for lattice grid: ";
cin >> dim1;
cout << "Enter dimension 2 for lattice grid: ";
cin >> dim2;
latticePascal(dim1, dim2, size);
return 0;
}
The cout statements that seem to be saving my program are marked with commented arrows. It seems to work as long as any of these lines are included. If all of these statements are removed, then the program will print: "Number of SE paths in a " and then hang for a couple of seconds before terminating without printing the answer. I want this program to be as clean as possible and to simply output the answer without having to print the entire contents of the triangle, so it is not working as intended in its current state.
There's a good chance that either the expression to calculate the array index or the one to calculate the array size for allocation causes undefined behaviour, for example, a stack overflow.
Because the visibility of this undefined behaviour to you is not defined the program can work as you intended or it can do something else - which could explain why it works with one compiler but not another.
You could use a vector with vector::resize() and vector::at() instead of an array with new and [] to get some improved information in the case that the program aborts before writing or flushing all of its output due to an invalid memory access.
If the problem is due to an invalid index being used then vector::at() will raise an exception which you won't catch and many debuggers will stop when they find this pair of factors together and they'll help you to inspect the point in the program where the problem occurred and key facts like which index you were trying to access and the contents of the variables.
They'll typically show you more "stack frames" than you expect but some are internal details of how the system manages uncaught exceptions and you should expect that the debugger helps you to find the stack frame relevant to your problem evolving so you can inspect the context of that one.
Your program works well with g++ on Linux:
$ g++ -o main pascal.cpp
$ ./main
Enter dimension 1 for lattice grid: 3
Enter dimension 2 for lattice grid: 4
Number of SE paths in a 3x4 lattice: 35
There's got to be something else since your cout statements have no side effects.
Here's an idea on how to debug this: open 2 visual studio instances, one will have the version without the cout statements, and the other one will have the version with them. Simply do a step by step debug to find the first difference between them. My guess is that you will realize that the cout statements have nothing to do with the error.
i'm a complete beginner to programming and I started with C++. I'm on arrays now and i'm trying to create a simple ten times table. I succeeded with the following code but i's sceptical i did the right thing since there are no square brackets:
#include <iostream>
using namespace std;
int main() {
int product;
for(int i = 1; i < 11; ++i) {
for(int j = 1; j < 11; ++j) {
product = i*j;
cout << product << "\t" << flush;
}
cout << endl;
}
return 0;
}
After messing about a bit i came up with the following:
#include <iostream>
using namespace std;
int main() {
int row = 11;
int col = 11;
int table[row][col];
for(row = 1; row < 11; ++row) {
for(col = 1; col < 11; ++col) {
table[row][col] = row*col;
cout << table[row][col] << "\t" << flush;
}
cout << endl;
}
return 0;
}
Both give the desired output, my question is why? I'm also curious to know if the first really is an array, if not what is it? Any advice on my basic code writing will also be greatly appreciated.
The first example does not use an array. You are printing out the 10x tables but you are not storing that information in the program. This means that after the loop, the program will not remember what the table looks like.
In the second example the variable table is the multidimensional array.
After the look you could call cout << table[4][6] << endl; for example, and 24 would be printed, without re-computing what 4*6 is. This is because you saved the information in the multidimensional array.
(also as the comments mentioned, arrays in programming start at 0, meaning that ideally you should makes your loops for(row = 0; row <= 10; ++row) {. This way the first slot in the array is not being wasted.
Also as the comments are mentioning, 'vectors' are nice but if you are learning programming, you should understand how an array works, and I would suggest not getting into vectors until you understand the basics of an array)
Both give the desired output, my question is why?
Because in both cases you print the same value.
In first case, you save the value in a variable
product = i*j;
and print the variable
cout << product << "\t" << flush;
In second case, you save the same value (row has the same value as i, col has the same value as j; so row * col has the same value as i * j) in a variable
table[row][col] = row*col;
(this time is a variable inside an array of array, that depends from row and col) and you print the same variable
cout << table[row][col] << "\t" << flush;
I'm also curious to know if the first really is an array, if not what is it?
Do you mean product?
No: product is a simple integer variable.
A variable that change value at every iteration of product = i*j;
It's the table variable in the second example that is an array; or better, an array of arrays.
The difference is that at the end of the double for, product maintain only the value of the last calculated product when table maintain all the calculated product.
Any advice on my basic code writing will also be greatly appreciated.
First of all, as explained from Some programmer dude, the code
int row = 11;
int col = 11;
int table[row][col];
isn't correct C++ because you can't use non constant values for array dimensions.
You can use directly 11
int table[11][11];
or you can define row and col as constants
int const row = 11;
int const col = 11;
int table[row][col];
or better (starting from C++11) as constexpr constants
constexpr int row { 11 };
constexpr int col { 11 };
int table[row][col];
Second: IMHO it's better avoid (when possible) using namespace std; but explicating the namespace; so
std::cout << table[row][col] << "\t" << std::flush;
This avoid risks of name collisions when you use other libraries.
I have been writing code to produce a horizontal histogram. This program takes user input of any range of numbers into a vector. Then it asks the user for the lowest value they want the histogram to begin at, and how big they want each bin to be. For example:
if lowestValue = 1 and binSize = 20
and vector is filled with values {1, 2, 3, 20, 30, 40, 50} it would print something like:
(bin) (bars) (num)(percent)
[ 1-21) #### 4 57%
[21-41) ## 2 28%
[41-61) ## 2 28%
Here is most of the code that does so:
void printHistogram(int lowestValue, int binSize, vector<double> v)
{
int binFloor = lowestValue, binCeiling = 0;
int numBins = amountOfBins(binSize, (int)range(v));
for (int i = 0; i<=numBins; i++)
{
binCeiling = binFloor+binSize;
int amoInBin = amountInBin(v,binFloor, binSize);
double perInBin = percentInBin(v, amoInBin);
if (binFloor < 10)
{
cout << "[ " << binFloor << '-' << binCeiling << ") " << setw(20) << left << formatBars(perInBin) << ' ' << amoInBin << ' '<< setprecision(4) << perInBin << '%' << endl;
binFloor += binSize;
}
else
{
cout << '[' << binFloor << '-' << binCeiling << ") " << setw(20) << left << formatBars(perInBin) << ' ' << amoInBin << ' '<< setprecision(4) << perInBin << '%' << endl;
binFloor += binSize;
}
}
}
and the function that counts how many terms are in each bin:
int amountInBin(vector<double> v, int lowestBinValue, int binSize)
{
int count = 0;
for (size_t i; i<v.size(); i++)
{
if (v[i] >= lowestBinValue && v[i] < (lowestBinValue+binSize))
count += 1;
}
return count;
}
Now my issue:
For some reason, it is not counting values between 20-40. At least as far as I can see from my testing. Here is an image of a run:
Any help is appreciated.
I would suggest a different approach. Making two passes, first calculating the number of bins, then another pass to add them up, looks fragile, and error-prone. Not really surprise to see you trying to figure out a bug of this kind. I think your original approach is too complicated.
As the saying goes "the more you overthink the plumbing, the easier it is to stop up the drain". Find the simplest way to do something, and it will have the least amount of surprises and gotchas, to deal with.
I think it's simpler to make a single pass over the values, calculating which bin each value belongs to, and counting the number of values seen per bin. Let's use a std::map, keyed by bin number, with the value being the number of values in each bin.
void printHistogram(int lowestValue, int binSize, const std::vector<double> &v)
{
std::map<int, size_t> histogram;
for (auto value:v)
{
int bin_number= value < lowestValue ? 0:(value-lowestValue)/binSize;
++histogram[bin_number];
}
And ...that's it. histogram is now your histogram. histogram[0] is now the number of values in the first bin, [lowestValue, lowestValue+binSize), which also includes all values less than lowestValue. histogram[1] will be the number of values found for the next bin, and so on.
Now, you just have to iterate over the histogram map, and generate your actual histogram.
Now, the tricky part here is that the histogram map will only include keys for which at least 1 value was found. If no value was dropped into the bin, the map will not include the bin number. So, if there were no values in the first bin, histogram[0] won't even exist, the first value in the map will be the bin for the lowest value in the vector.
This isn't such a difficult problem to solve, by iterating over the map with a little bit of extra intelligence:
int next_bin_number=0;
for (auto b=histogram.begin(); b != histogram.end(); b++)
{
while (next_bin_number < b->first)
{
// next_bin_number had 0 values. Print the histogram row
// for bin #next_bin_number, showing 0 values in it.
++next_bin_number;
}
int n_values=b->second;
// Bin #n_next_number, with n_values, print its histogram row
++next_bin_number;
}
The code in the loop doesn't initialize i, so the results are at best unpredictable.
Trying to insert values into a 2D array, but the output isnt giving my values, instead random letters
int myArr[8][2] = {700,730,760,790,810,840,910,1000}{0.011,0.035,0.105,0.343,0.789,2.17,20,145};
cout << myArr << endl;
system("Pause");
How should I adjust the code, or is it easier to use a text file and insert?
Numerous problems:
the array dimensions are wrong
you don't have outer braces or a comma for the nested arrays
you're trying to store double precision floating point values in an int array
you can't use cout with an entire array.
The array declaration should probably be something like this:
double myArr[2][8] = { {700,730,760,790,810,840,910,1000},
{0.011,0.035,0.105,0.343,0.789,2.17,20,145} };
and to output the contents you could do something like this:
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 8; ++j)
{
cout << " " << myArr[i][j];
}
cout << endl;
}
Live Demo
First - you can't print the whole array just by using cout << myArr, you need to iterate over the elements of the array using a for loop.
Second - you are trying to put decimal values into an integer array which will truncate all of the decimals.
Third - Your array should be sized myArr[8][2] not myArr[2][8]. I'm surprised your compiler lets you get away with this. You should probably look into using a different compiler.
You need to iterate through each row and column, otherwise you're just printing out the pointer value of the array handle.
for (int i=0;i<8;i++){
for (int j=0;j<2;j++){
cout << myArr[i][j] << " ";
}
cout << endl;
}
system("Pause");