C++ functions that takes multiple numbers and perform different jobs - c++

I have an exercise where I should input multiple numbers which finish with zero and then perform different calculations with them. So far I have created a do..while-loop for storing the numbers. I´ve been told that this is possible to do without an array, if that´s wrong please tell me right away. The functions I need to do is to add all the numbers together, locate the highest number and the second highest number, and also the mid (mean) value of all the numbers.
I think there are different libraries I should use and there may be different options also.
Please help me to understand the different libraries and how to use them.
The search results I´ve found on the the web does not give me the answers I´m looking for because I could not find a similar problem to mine.
This is my code so far:
#include<iostream>
#include<string>
using namespace std;
int sumCalc (int);
int midValCalc (int);
int secHighCalc (int);
int highestCalc (int);
void printCalc ();
int main() {
int nums;
cout << "Input numbers, quit with 0: ";
do {
cin >> nums;
cout << nums << " "; // This is just to see the result
}
while (nums != 0);
return 0;
}
What is wrong with this add function?
int sumCalc (int total) {
total = 0;
while (nums != 0) {
total += nums;
}
return nums;
}

I don't think you need any unusual libraries for this.
Think about how you'd calculate these things mentally. For example, if you want to sum a list of numbers that I read off to you, you'd just keep track of the running total, and forget each number as you added it - so that only needs one variable. If you want to keep track of the greatest number entered, again, you simply remember the biggest one you've seen so far and compare new numbers as you get them.
You can probably solve these.

If you need to get the mean and highest and second-highest numbers you don't need an array(you don't need to store the numbers)
Essentially, you can keep track of the highest and second highest numbers that the user has entered, and if the user enters a number higher than those, you can adjust accordingly.
As for the mean average, you can also keep a running sum and count(# of numbers entered) which you can use to calculate the mean with whenever you need to.

Related

Simple C++ code to have fun and learn algorithm

==
Code founded online in Chegg, however the output is not the one that was told. It supposed to give a ounce_left of 4, but is giving an 8.
Someone knows where is the bug?
==
In this problem, our task is to find the no_of _cans needed and the no_of_ounce left over.
The formula to calculate no_of_cans needed is: ceil(amount/12).
Formula to calculate no_of_ounce needed is: 12*ceil(amount/12)-amount.
Algorithm
Take input amount from user.
Divide amount/12 and store ceil of quotient in variable cans_needed.
Ounce_left will be calculated as 12*cans_needed-amount.
Print cans_needed.
Print ounce_left.
Stop.
Now let us try to implement the above algorithm using C++.
//header files used
#include<bits/stdc++.h>
using namespace std;
int main()
{
int amount;
//taking input from user
cout<<"Enter Amount in ounces:";
cin>>amount;
//finding no of cans needed
//if it is evenly divided by 12 then ceil(quotient)=quotient
//else ceil(quotient)=quotient+1
int cans_needed=ceil((double)amount/12);
//finding ounce_left
int ounce_left=amount%12;
cout<<"Cans Needed :"<<cans_needed<<endl; //printing cans_needed
cout<<"Ounce left: "<<ounce_left<<endl; //printing ounce_left
}

Vector + for + if

OK, so the goal of this was to write some code for the Fibonacci numbers itself then take those numbers figure out which ones were even then add those specific numbers together. Everything works except I tried and tried to figure out a way to add the numbers up, but I always get errors and am stumped as of how to add them together. I looked elsewhere but they were all asking for all the elements in the vector. Not specific ones drawn out of an if statement.
P.S. I know system("pause") is bad but i tried a few other options but sometimes they work and sometimes they don't and I am not sure why. Such as cin.get().
P.S.S I am also new to programming my own stuff so I have limited resources as far as what I know already and will appreciate any ways of how I might "improve" my program to make it work more fluently. I also take criticism well so please do.
#include "../../std_lib_facilities.h"
int main(){
vector<int>Fibonacci;
int one = 0;
int two = 1;
int three = 0;
int i = 0;
while (i < 4000000){
i += three;
three = two + one; one = two; two = three;
cout << three << ", ";
Fibonacci.push_back(three);
//all of the above is to produce the Fibonacci number sequence which starts with 1, 2 and adds the previous one to the next so on and so forth.
//bellow is my attempt and taking those numbers and testing for evenness or oddness and then adding the even ones together for one single number.
}
cout << endl;
//go through all points in the vector Fibonacci and execute code for each point
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0)//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
system("pause");
}
Just do it by hand. That is loop over the whole array and and keep track of the cumulative sum.
int accumulator = 0; // Careful, this might Overflow if `int` is not big enough.
for (i = 0; i <= 31; i ++) {
int fib = Fibonacci.at(i);
if(fib % 2)
continue;
cout << fib << endl;//how to get these numbers to add up to one single sum
accumulator += fib;
}
// now do what you want with "accumulator".
Be careful about this big methematical series, they can explode really fast. In your case I think the calulation will just about work with 32-bit integers. Best to use 64-bit or even better, a propery BigNum class.
In addition to the answer by Adrian Ratnapala, I want to encourage you to use algorithms where possible. This expresses your intent clearly and avoids subtle bugs introduced by mis-using iterators, indexing variables and what have you.
const auto addIfEven = [](int a, int b){ return (b % 2) ? a : a + b; };
const auto result = accumulate(begin(Fibonacci), end(Fibonacci), 0, addIfEven);
Note that I used a lambda which is a C++11 feature. Not all compilers support this yet, but most modern ones do. You can always define a function instead of a lambda and you don't have to create a temporary function pointer like addIfEven, you can also pass the lambda directly to the algorithm.
If you have trouble understanding any of this, don't worry, I just want to point you into the "right" direction. The other answers are fine as well, it's just the kind of code which gets hard to maintain once you work in a team or have a large codebase.
Not sure what you're after...
but
int sum=0; // or long or double...
for (i = 0; i <= 31; ++i)
if (Fibonacci.at(i) % 2 == 0) {//is Fibonacci.at(i) even?
cout << Fibonacci.at(i) << endl;//how to get these numbers to add up to one single sum
sum+=Fibonacci.at(i);
}
// whatever
}

how to improve the efficient of program of crazy guy waiting airplane

I recently wrote a program about the crazy guy waiting airplane question, which says:
A line of 100 airline passengers is waiting to board a plane. They each hold a ticket to one of the 100 seats on that flight. (For convenience, let's say that the nth passenger in line has a ticket for the seat number n.)
Unfortunately, the first person in line is crazy, and will ignore the seat number on their ticket, picking a random seat to occupy. All of the other passengers are quite normal, and will go to their proper seat unless it is already occupied. If it is occupied, they will then find a free seat to sit in, at random.
What is the probability that the last (100th) person to board the plane will sit in their proper seat (#100)?
I did monte carlo to get the answer, but not very efficient, since for the passengers, whose seat is sited. I first get a random number, and then checked from the first seat, if it is sited, then skip that one.
By the way the answer should be 1/2 :)
anybody has a better idea to do this one?
#include <iostream>
#include <vector>
#include <random>
using namespace std;
mt19937 generator;
uniform_real_distribution<double> ranuni(0, 1);
bool test(){
vector<int> line(100, 0);
int remaining(100);
int temp = remaining * ranuni(generator);
if (temp == 99)
return 0;
line[temp] = 1;
--remaining;
for (int i = 1; i < 99; ++i){
temp = remaining * ranuni(generator);
auto itr = line.begin();
while (temp != 0){
++itr;
if (*itr == 0)
--temp;
}
if (itr == line.end()-1)
return 0;
else
*itr = 1;
--remaining;
}
return 1;
}
int main(){
cout << "please input number of simulations" << endl;
int num;
cin >> num;
int sum(0);
for (int i = 0; i < num; ++i)
sum += test();
cout << double(sum) / double(num) << endl;
return 0;
}
I'll offer a couple of thoughts. Probably not a definitive answer, though.
First, I wondered: if you pre-computed a "shuffled" list of plane seats to use, would that help things? The idea being: when a passenger attempts to sit in his/her seat and finds it occupied, you simply pop values off the list until you find one that is unoccupied instead of calling random(). You can pop them off because you don't want later passengers to waste time considering those (occupied) seats either. This means you DO avoid the problem near the end of the line where a random number generator keeps generating occupied seats. (Although, not yours I see, since you deterministically find an unoccupied seat when the assigned seat is occupied). Given such a shuffled list of seat assignments, it is very quick and easy to evaluate the original problem.
The real problem is that generating this "shuffled" list is exactly the same problem as the original one (for ticket# in 0..99, put ticket# in slot(random). Is it occupied? etc.) So, given that generating a nicely shuffled list of seat assignments has the same complexity as the original problem, is there a way we can simplify doing this lots and lots of times?
That brings me to my second thought: once you have one such shuffled list, there are lots of ways of creating other ones, much easier than 100 additional calls to random(). For example, just swap two of the values. The resulting list represents a different run of the problem with slightly different selections by passengers. Do this lots of times and you get many different runs.
The part I can't quite answer, though, is how to ensure the samples you get have a good sampling of the problem space (which is necessary for monte carlo to give you good results). I'll have to leave that for someone else.

make permutations of an array of numbers, then turn them into a single int

Basic idea: Given an array, find all the permutations of that array. Then, take each of those arrays and put it all together. Eg the array {6,5,3,4,1,2} gives you 653412. The permutations work, but I cannot get the integers.
int main ()
{
int myints[] = {2,3,4,5,6,7,8,9};
int k;
int dmartin=0;
int powof10=1;
std::cout << "The 8! possible permutations with 8 elements:\n";
do {
for(k=0; k<8; k++){
std::cout << myints[k] << ' ';
dmartin=myints[8-k-1]*powof10+dmartin;
powof10=powof10*10;
}
cout << "\n" << dmartin << "\n";
} while ( std::next_permutation(myints,myints+8) );
dmartin=0;
return 0;
}
I also have some code that works when you just have one array, but in this case there are thousands. I though I needed to reset dmartin=0 at the end of each while loop so that it didn't keep adding to the previous answer, however when I tried that I got "0" for each of my answers. Without trying to reset, I get answers that seem random (and are negative).
The problem is that you're not resetting your two variables inside your loop, so they'll continue from the values they had during the previous iteration, which will just be wrong, and will quickly overflow, giving seemingly rubbish output. Try putting this at the beginning or the end of the do-while loop:
dmartin = 0;
powof10 = 1;
But you're really overcomplicating it a lot. It would be way simpler to just build the number from the most significant digit instead of the least significant one instead. This would eliminate the need for a powof10 variable. This new for-loop would look like this:
for(k = 0; k < 8; k++){
std::cout << myints[k] << ' ';
dmartin = 10*dmartin + myints[k];
}
That won't work for long, since your integer will soon overflow.
That's probably what you are experiencing when you get negative numbers.
Using an integer to store the result does not seem the most appropriate choice to me. Why not use a string, for instance? That would save you the hassle of reinventing base10 conversion in 2014, and you could easily derive a number from the string when needed.
That won't solve the overflow problem, though.
First point: the code to take a vector of digits and turn them into a single number should almost certainly be written as a function, not just code inside the loop.
Second point: you can use std::string like a container of char, and apply normal algorithms to it.
Seem to me, the lazy way would look like this:
std::string input="23456789";
do {
std::cout<<std::stoi(input)<<"\n";
} while (std::next_permutation(input.begin(), input.end()));

Optimizing C code [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Suppose we have an array of numbers say {1,2,3} and we want to equalize the numbers in the least number of turns possible; where the definition of a "turn" is as follows:
In a turn, you need to fix the value of one of the elements as is, and increment every other number by 1.
Considering the eg. already mentioned - A={1,2,3} , the goal is to equalize them.What I've already done is formulate the logic i.e The method to using a minimum number of turns is to choose the maximum number in each turn.
Iteration 1: Hold A[2]=3. Array at end of iteration => {2,3,3}
Iteration 2: Hold A[2]=3. Array at end of iteration => {3,4,3}
Iteration 3: Hold A[1]=4. Array at end of iteration => {4,4,4}
So,number of turns taken = 3
The code I've written is as follows:
#include<iostream>
#include<stdio.h>
int findMax(int *a,int n)
{
int i,max;
max=1;
for(i=2;i<=n;i++)
{
if(a[i]>a[max])
{
max=i;
}
}
return max;
}
int equality(int *a,int n)
{
int i;
for(i=1;i<n;i++)
{
if(a[i]!=a[i+1]) return 0;
}
return 1;
}
int main()
{
int a[100],i,count,t,posn_max,n,ip=0;
scanf("%d",&t);
while(ip<t)
{
count=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
while(equality(a,n)==0)
{
posn_max=findMax(a,n);
for(i=1;i<=n;i++)
{
if(i!=posn_max)
{
a[i]=a[i]+1;
}
}
count++;
}
printf("%d\n",count);
ip++;
}
return 0;
}
This gives me the correct answer I need alright. But I want to optimize it further.
My Time Limit is 1.0 s . But the judge site tells me my code takes 1.01s. Can anyone help me out?
As far as I can see, I've used scanf/printf statements as compared to cout/cin, in a bid to optimize the input/output part. But what else should I be doing better?
In your algorithm, you are increasing all numbers in the expect for the maximum.
If you do it the other way around, decreasing the maximum and leaving the rest of the numbers, the result should be the same (but with much less memory/array operations)!
To make it even faster, you can get rid of the memory oeprations completely (as suggested by Ivaylo Strandjev also): Find the minimum number and by the idea above (of decreasing numbers instead of increasing) you know how much decreases you require to decrease all numbers to this minimum number. So, after finding the minimum you need one loop to calculate the number of turns.
Take your example of {1,2,3}
The minimum is 1
Number of turns: (1-1)+(2-1)+(3-1) = 0 + 1 + 2 = 3
If you are really clever, it is possible to calculate the number of turns directly when inputting the numbers and keeping track of the current minimum number... Try it! ;)
You only care about the count not about the actual actions you need to perform. So instead of performing the moves one by one try to find a way to count the number of moves without performing them. The code you wrote will not pass in the time limit no matter how well you optimize it. The maximum element observation you've made will help you along the way.
Besides the other comments, if I get this right and your code is just a little bit too slow, here are two optimizations which should help you.
First, you can combine equality() and findMax() and only scan once through the array instead of your current worst case (twice).
Second, you can split the "increase" loop into two parts (below and above the max position). This will remove the effort to check the position in the loop.
1) Try unrolling the loops
2) Can you use SIMD instruction? That would really speed this code up
I would printf in a separate thread, since it's an I/O operation and is much slower than your calculations.
It also does not demand complicated management e.g Producer-Consumer queue, since you only pass the ordered numbers from 0 to last count.
Here's the pseudo-code:
volatile int m_count = 0;
volatile bool isExit = false;
void ParallelPrint()
{
int currCount = 0;
while (!isExit)
{
while (currCount < m_count)
{
currCount++;
printf("%d\n", currCount);
}
Sleep(0); // just content switch
}
}
Open the thread before the scanf("%d",&t); (I guess this initialization time is not counted), and close the thread by isExit = true; before the return from your Main().