C++ Arrays, Array Conversion not working - c++

I've been stuck on a problem for quite a while today, and despite my searching the internet, I'm not sure as to what I should do. This program (that I will post the source code to) is supposed to be based off of the Birthday Paradox, and help us to prove it correct.
The idea is that we have multiple arrays, one of which simulates the paradox by counting the times that there is NOT a matching birthday pair, another which takes that array and creates a ratio(array value/over total iterations) and another that creates a theoretical array ratio value.
Now, this is where I"m stuck. I can get the first two functions to work perfectly, birthdayFrequency and ratioArray, but the next one idealArray I cannot get to work properly. Both ratioArray and idealArray should be a double data type, and ratioArray stores it properly as a double.
However, idealArray does not. It stores the data in the array positions as integers. I want to know if there's something I missed, something that might have caused me to accidentally make the array an integer.
*I'm going to apologize, the code is really long. Also, I can't get it all to fit in a code window. I apologize.
using namespace std;
//Arraytype declarations
typedef int Birthday[365];
typedef bool Counter[365];
typedef double Ratio[365];
void ratioArray(int, Birthday, Ratio);
void idealArray(Ratio);
void outputTable();
int randomInt(int);
//Main function
int main()
{
Birthday array = {0};
Ratio vector = {0};
Ratio matrix = {0};
int seed;
int runs;
//Prompt the user for the number of times the simulation is to be run.
cout << "Hello and welcome to the Birthday Paradox Simulator. " << endl;
cout << "This program uses simulated runs to calculate and verify the paradox." << endl << endl;
cout << "Please enter the number of runs you want done. IMPORTANT, must be a positive integer." << endl;
cin >> runs;
while (runs <= 0)
{
cout << "That's an invalid value. Please enter a positive number." << endl;
cin >> runs;
}
//Prompt the user for a non-negative integer seed value
cout << "Please input a seed to be used for randomly generating numbers. It must be an integer, and non-negative." << endl;
cin >> seed;
while (seed < 0)
{
cout << "I'm sorry, that is an invalid value. Please enter a non-negative number)" << endl;
cin >> seed;
}
//Seed the srand function
srand(seed);
//Call birthdayFrequency function
birthdayFrequency(runs, array);
//Call ratioArray function
ratioArray(runs, array, vector);
//Call idealRatioArray function
idealArray(matrix);
//Testing values
cout << array[1] << endl;
cout << array[2] << endl;
cout << array[3] << endl;
cout << vector[1] << endl;
cout << vector[2] << endl;
cout << vector[3] << endl;
cout << matrix[1] << endl;
cout << matrix[2] << endl;
cout << matrix[3] << endl;
//Call outputTable function
outputTable();
return 0;
}
void birthdayFrequency(int n, Birthday number)
{
int iteration = 0;
int value;
int boundary = 364;
//For loop for n iterations
for ( int k =0 ; k < n ; k++)
{
Counter boolean = {0};
iteration = 0;
//Randomly mark birthdays until there's a duplicate using a for loop
for ( int i = 0; i < 366; i ++)
{
value = randomInt(boundary);
if (boolean[value] == 1)
break;
else
boolean[value] = 1;
number[iteration]++; //Increment the frequency array for every non-match
iteration++;
}
}
}
void ratioArray(int n, Birthday number, Ratio vectors)
{
double ratio;
//For loop for the number of runs, storing the value of ratios to the total number of runs.
for ( int i = 0 ; i < 364 ; i++)
{
ratio = (double)number[i] / n;
vectors[i] = ratio;
}
}
void idealArray(Ratio number)
{
number[0]= 1.0;
number[1] = 1.0;
//Create an ideal, theoretical probability array
for ( int n = 2; n < 364; n++)
{
number[n] = (number[n - 1]*(1- (n-1)/365));
}
}
void outputTable()
{
//Not completed yet.
}
int randomInt(int bound)
{
return static_cast<int>( rand() / (RAND_MAX + 1.0) * bound );
}

In this code:
for ( int n = 2; n < 364; n++)
{
number[n] = (number[n - 1]*(1- (n-1)/365));
}
n is an integer, therefore (1-(n-1)/365)) will evaluate to an integer value, since all values in the expression are integers. Also, an integer multiplied by an integer will produce an integer. Since you start off setting number[1] to 1.0, and each element is calculated by multiplying the previous element by an integer amount, all subsequent values will be integer amounts (although stored as doubles).
Change your code to use doubles for the calculation:
for ( int n = 2; n < 364; n++)
{
number[n] = (number[n - 1]*(1.0-((double)n-1.0)/365.0));
}

Related

How do I add the outputs of a loop?

So in this program, I have to do multiplication in a very tedious fashion and for the second loop, the for loop, I'm multiplying one variable by 2 and the output is the product of that multiplication I am wondering how I could go about taking those output values and adding them together. The code and output of the code are below
#include <iostream>
using namespace std;
int main()
{
cout << "Time to do some Martian Math" << endl;
// variables for math
int righthandnum;
int lefthandnum;
cout << "Please enter two numbers" << endl;
// get values to do the martian math
cin >> lefthandnum;
cin >> righthandnum;
//while loop for right hand number
int i = 0;
while (righthandnum >= 1 ) {
//cout << righthandnum << endl;
//if to find out if any values are odd
if (righthandnum % 2 == 0) {
i -= 1;
}
righthandnum = righthandnum / 2;
i++;
}
int num;
for (num = 1; num <= i; num++) {
lefthandnum = lefthandnum * 2;
//lefthandnum + lefthandnum;
cout << lefthandnum << endl;
}
return 0;
}
The output is
Time to do some Martian Math
Please enter two numbers
50
30
100
200
400
800
Thank you so much for any help!
I don't know if this is what you are looking for but maybe a stack or an array might help you
with the array (the easy way), you make a list of N size for the data as an example:
int values[10];
for(int i = 0; i < 10; i++){
std::cin>>values[i];
}
for(int i = 0; i < 10; i++){
std::cout<<"List element "<<i<<": "<<values[i]<<std::endl;
}
while the stack as I've used it it's a bit more complex and requires pointers.
this is a video (sorry it's in Spanish): https://youtu.be/joAw2jWgZqA

"Uninitialized Local Variable Used"

I have a call to 2 functions which find the highest and lowest grade, respectively. they return "highestGrade" and "lowestGrade" but I am confused why the error appears when I compile. This is a lab assignment and most of the code was pre-written and I was tasked with filling in the missing code. The error occurs around lines 55 and 63, and the functions I am referring to are at the end of the code.
I am new to using arrays so I am assuming I may have some for of erroneous code inside the functions "findHighest" and "findLowest". For example, the program in "findHighest" will assume the first array it runs into is the highest grade and will compare the remaining arrays to it until it finds one that is higher. If it is, it will then assign that array to "highestGrade".
float findAverage(const GradeType, int);
int findHighest(const GradeType, int);
int findLowest(const GradeType, int);
int main()
{
GradeType grades;
int numberOfGrades;
int pos;
float avgOfGrades;
int highestGrade;
int lowestGrade;
// Read in the values into the array
pos = 0;
cout << "Please input a grade from 1 to 100, (or -99 to stop)" << endl;
cin >> grades[pos];
int i = 1;
while (grades[pos] != -99)
{
// read in more grades
pos = i;
cout << "Please input a grade from 1 to 100, (or -99 to stop)" << endl;
cin >> grades[pos];
}
numberOfGrades = pos; // Fill blank with appropriate identifier
// call to the function to find average
findAverage(grades, numberOfGrades);
avgOfGrades = findAverage(grades, numberOfGrades);
cout << endl << "The average of all the grades is " << avgOfGrades << endl;
// Fill in the call to the function that calculates highest grade
findHighest(grades, highestGrade);
highestGrade = findHighest(grades, highestGrade);
cout << endl << "The highest grade is " << highestGrade << endl;
// Fill in the call to the function that calculates lowest grade
findLowest(grades, lowestGrade);
// Fill in code to write the lowest to the screen
lowestGrade = findLowest(grades, lowestGrade);
cout << endl << "The lowest grade is " << lowestGrade << endl;
return 0;
}
float findAverage(const GradeType array, int size)
{
float sum = 0; // holds the sum of all the numbers
for (int pos = 0; pos < size; pos++)
sum = sum + array[pos];
return (sum / size); //returns the average
}
int findHighest(const GradeType array, int size)
{
// Fill in the code for this function
float highestGrade = array[0];
for (int i = 0; i < size; i++)
{
if (array[i] > highestGrade)
highestGrade = array[i];
}
return highestGrade;
}
int findLowest(const GradeType array, int size)
{
// Fill in the code for this function
float lowestGrade = array[0];
for (int i = 1; i < size; i++)
{
if (array[i] < lowestGrade)
lowestGrade = array[i];
}
return lowestGrade;
}
The program is unable to output the highest and lowest grade due to the error.
findLowest(grades, lowestGrade);
You are using lowestGrade before initializing it.
int lowestGrade;
should be
int lowestGrade = 0; // or to anything that has meaning for your app.
And of course, as better C++, declare it just before you need it, not at the top of the function.
Same thing for the other variables.
All of this of course if the logic is correct. Why do you pass the lowest/higest grade as a size parameter in the functions?

Dynamic arrays using float

I've got a small task I need to complete and I'm rather confused. This task has 3 parts to it which are:
Write a program that dynamically allocates a float array of a size specified by a user (currently working on - if anyone could check my code for this it would be appreciated.
It should then allow the user to input that number of floats, which should be stored in the array. (I have no clue what this means so if I'd appreciate someone explaining it if they could)
Program should print what was saved into the array, the sum, and the average value in the array, and exit.
As you could tell I'm new to C++ and coding in general so please spell it out for me wherever possible. It is mandatory that I am using pointers so I'm afraid I can't change that.
#include <iostream>
using namespace std;
int main()
{
int length;
cout << “Please enter the length of the array: “;
cin >> length;
float * dArray = new float [length];
for (int i = 0; i < length; i++)
{
cin >> dArray[i] = i;
for (int i = 0; i < length; i++)
{
cout << dArray[i] << “ “;
}
cout << ‘/n’;
int sum = 0;
for (int i=0; i < length; i++)
{
sum +=dArray[i];
avg =sum/length;
cout << “Sum is “ << sum << “/nAverage is “ << average;
delete [] dArray;
}
return 0;
}
Please explain the 2nd part.
Thanks in advance.
Regarding
It should then allow the user to input that number of floats, which should be stored in the array. (I have no clue what this means so if I'd appreciate someone explaining it if they could)
It means that you have to let the user input the values to that array. What you are doing is giving them values yourself.
What you need to do is change
for (int i = 0; i < length; i++)
{
dArray[i] = i;
}
to
for (int i = 0; i < length; i++)
{
cin>>dArray[i];
}
Also Note that length should be an int and not a float.
After completion, this would probably be the code you need ( although I would advice you to do the part of finding the sum and average by yourself and use this code I have posted as reference to check for any mistake, as finding the sum and average for this is really easy )
#include <iostream> // include library
using namespace std;
int main() // main function
{
int length; // changed length to int
float sum = 0 , avg; // variables to store sum and average
cout << "Please enter the length of the array: "; // ask user for array
cin >> length;
float *dArray = new float[length];
cout << "\nEnter " << length << " values to be added to the array\n";
for (int i = 0; i < length; i++)
{
cin >> dArray[i]; //accepting values
sum += dArray[i]; // finding sum
}
avg = sum / length; //the average
cout << "\nThe array now contains\n"; // Displaying the array
for ( int i = 0; i < length; i++) // with the loop
{
cout << dArray[i] << " ";
}
cout << "\nThe sum of all values in the array is " << sum; // the sum
cout << "\n\nThe average value is " << avg; // the average
delete[] dArray;
return 0;
}
EDIT
After getting your comment, I decided to post this new code. ( I am assuming what you meant is that the program should repeat as long as the user wants )
I have done it by using a do while loop.
#include <iostream> // include library
using namespace std;
int main() // main function
{
int length; // changed length to int
char a; // a variable to store the user choice
do
{
float sum = 0 , avg; // variables to store sum and average
cout << "\nPlease enter the length of the array: "; // ask user for array
cin >> length;
float *dArray = new float[length];
cout << "\nEnter " << length << " values to be added to the array\n";
for ( int i = 0; i < length; i++ )
{
cin >> dArray[i]; //accepting values
sum += dArray[i]; // finding sum
}
avg = sum / length; //the average
cout << "\nThe array now contains\n"; // Displaying the array
for ( int i = 0; i < length; i++ ) // with the loop
{
cout << dArray[i] << " ";
}
cout << "\nThe sum of all values in the array is " << sum; // the sum
cout << "\n\nThe average value is " << avg; // the average
cout << "\n\nDo you want to try again ( y/n ) ?\n";
cin >> a;
delete[] dArray;
}while( a =='Y' || a == 'y' ); // The do while loop repeats as long as the character entered is Y or y
return 0;
}
Well, hope this is what you were looking for, if not, please do notify me with a comment... :)
Just so you know, the new code you have posted doesn't even compile. Here are some of the problems.
cin >> dArray[i] = i;
You don't need to use = i here. Just cin >> dArray[i] ; is enough.
The next problem is
cout << ‘/n’;
First of all, its \n and not /n. You also need to enclose it in double quotes and not single quotes. That is cout << "\n";
Next one, you have not defined the variable avg . Also note that you have also used an undefined variable average, which I assume you meant avg.
Now here's one of the main problems , You have not closed the curly brackets you opened. You open the brackets for for loops, but forget to close it. I'm leaving that part to you as you need to learn that part yourself by trying.
Now Here's one problem I don't understand, you have used “ “, which is somehow not the same as " ". I don't know if it's something wrong with my computer, or if it's a totally different symbol. My compiler couldn't recognize it. If its not causing any trouble on your end, then don't mind it.
Well, this sums up the problems I noticed in your code ( the problems that I noticed ).
Your issues are too simple for us to just give you the answers, but I've commented your code with suggestions on how to solve your problem:
#include <iostream>
using namespace std;
int main()
{
float length; //it doesn't make sense for something to be of a float length
//should be size_t instead
cout << "Please enter the length of the array: ";
cin >> length;
float *dArray = new float[length];
for (int i = 0; i < length; i++)
{
dArray[i] = i; //this line is incorrect
//how should we read the data into this array?
//we've used cin before
}
for (int i = 0; i < length; i++)
{
cout << dArray[i] << " ";
}
cout << '\n';
//now we've output the array, just need to output the sum and average value
int sum = 0;
for (int i=0; i < length; i++)
{
sum += //what should go here?
}
int average = //how should we calculate the average?
cout << "Sum is " << sum << "\nAverage is " << average;
delete[] dArray;
return 0;
}

Entering 20 numbers into an array with no duplicates

int main()
{
int theArray [20] = {0};
int userInput = 0;
int populateCount = 0;
cout << "Enter 20 integers between 10 and 100 inclusive. " << endl;
while (populateCount < 20)
{
cin >> userInput;
theArray[populateCount] = {userInput};
if (userInput<10||userInput>100)
{
cout << "That is not a legal input. " << endl;
populateCount - 2;
}
else
{
populateCount++;
}
}
cout << "\n";
for (int i = 0; i < 20; i++)
{
cout << theArray[i] << endl;
}
}
I've got the baseline of my code done. The user enters twenty numbers and they're added to the array. If it's less than 10 or greater than 100 it's not a legal input, I subtract from the count, and they're allowed to go again. Then after the user finishes plugging in numbers it prints the array. However, I've been trying different if statements inside the array to eliminate duplicates, such as (if theArray[i] == theArray[i+1] then [i+1] = 0) I suppose that could work if I incorporated a sort to get all the 0's at the end, but is there a more efficient way to do this?
Before I go to the answer I suggest we clean it up slightly to make the problem more clear and remove other confusion.
Misconception
The statement populateCount - 2 has no effect.. instead you are simply not incrementing populateCount which is why the loop doesn't advance.
I would suggest something of this format within the loop. It puts the 'happy' path first, which will also make for some clearer ways to handle the second part.
if (userInput >= 10 && userInput <= 100 ) {
theArray[populateCount++] = userInput;
}
else {
std::cout << userInput << " is not legal input, must enter value "
<< "between 10 and 100. " << std::endl;
}
Preface
Before we attack the problem first let's refactor so that we can break it down to a single function so that as we work we don't disturb everything else as well as gain flexibility for testing and simplify readability.
Refactor
/* this code is responsible for doing what is needed to
* only insert unique items */
bool insert( const int& input, int* array, int num_elements ) {
// the fun part!
// more to follow shortly
};
/* gets user input forcing input to be between min and max */
int getUserInput(int min, int max) {
bool found = false;
int result = 0;
/* this can be done with less code but this makes it easy
* to see whats going on */
while ( !found ) {
cout << "Please enter a value between " << min << " and " << max << "." << endl;
cin >> result;
if ( result >= min && result <= max ) {
found = true; //yes we could break or return from here
} else {
cout << result << " invalid. "<< endl;
}
}
return result;
};
void printArray( const int* array, const int& size ) {
for (int i = 0; i < size; i++)
{
cout << array[i] << endl;
}
};
int main()
{
const int totalElements = 20;
int theArray [totalElements] = {0};
int userInput = 0;
int populateCount = 0;
int minVal = 10;
int maxVal = 100;
cout << "Enter " << totalElements << " integers between "
<< minVal << " and " << maxVal << " inclusive. " << endl;
while ( populateCount < numElements )
{
//this will percievably loop until it's good
userInput = getUserInput(minVal, maxVal);
if ( insert( userInput, theArray, populateCount ) )
++populateCount; //increments if we did insert it
}
}
cout << endl;
printArray( theArray, totalElements );
}
Attacking the problem
Ok so now our problem is simple, we just have to write the insert function. There are a couple of choices here, you can check each element in turn which as you said can be slow, O(n), or we could sort the array to make it quick, O(log n) + cost of sorting. Other possibilities I presume aren't available are using a std::set instead of an array, or using STL to do the work of sorting and finding. Note that in these modes insert won't actually do an insertion if the number is already present.
Another unique idea is to use an array of bools size max-min, and simply flag the index of input-min as true when you find it. This will be fast at the cost of size depending upon the gap between min and max. (this is essentially a hash function)
The advantage we are at from a refactor is that you can in turn write and try each of these solutions and even feed them the same canned input now that we've refactored so that you can try and time each one. For timing I would heavily suggest you add lots of numbers and consider greatly expanding the min and max to understand the scalability of each choice

Storing individual numbers of an int in an array

I was trying to write a program in which I take an input number,
example 891 and input each of these number in an array for example
x[0] = 8, x[1] = 9 and x[2] = 1
I was trying to use recursion to implement my method:
void calc(int val, int k)
{
static int number = val;
if((val/10))
{
calc(val/10, k--);
}
int x = number - val*pow(10, k);
cout << x << ", k = " << k << " and number = " << number << endl;
}
int main()
{
//write a program that converts a number to string
int number;
cout << "Enter a number: ";
cin >> number;
number = 891;
int k = 0;
//while(number/10 != 0)
k = 2;
calc(number, k);
}
Basically I'm trying to use my recursive function to try to break the
number down in its finer parts, however I get an output of (in val):
91, 1, -8019. Is there a way I can improve on this, but maintaining
the structure?
Both putting your data into an array and solving this problem recursively requires a bit of pointer arithmetic.
You'll need to allocate your array ahead of time, which means you need to know the number of digits. You'll also need to pass around the pointer to the array so that recursive calls can assign to it.
Below is a shortish solution that fits both of these requirements.
#import <math.h>
#import <iostream>
using namespace std;
void calc(int num, int* digs) {
if (num > 0) {
calc(num/10, digs-1); //recursive call, doing head recursion
*digs = num %10; //assigning this digit
}
}
int main() {
//Get number from user
int inputNumber;
cout << "Input a number: ";
cin >> inputNumber;
int numDigits = log10(inputNumber) + 1;
int outputArray[numDigits];
//I give a pointer to the end of the array
//This is because we are receiving digits from the end
//So we traverse backwards from the end of the array
calc(inputNumber, outputArray+numDigits-1);
//Following is not logic, just printing
for (int i=0; i < numDigits; i++) {
cout << outputArray[i] << " ";
}
cout << endl;
}
void calc(int val)
{
cout << "digit:"<<val % 10<< " and number = " << val << endl;
if((val/10))
{
calc(val/10);
}
}
This will print out each digit (which looks like what you are trying to do in the function).