Hello everyone I am required to create a program that reads in an input file containing digits and then finds the standard deviation using the following method:
sqrt(( x1 - mu )^2 + ( x2 - mu )^2 + ( x3 - mu )^2 + ( x4 - mu )^2)/mu
The x's are equal to the digits read in, and mu is equal to the mean. I am having trouble doing this because I don't know how to set up different variables (x1, x2, x3, x4) for the values that are read in from the input file within my while loop. Also it is important to note that we are supposed to read in the first digit and then every third digit after that. This is what I have so far:
fin.open(FileName.c_str());
if (fin.fail())
{
cout <<"Bad file name or location.\n" ;
exit(0);
}
fin >> X;
first_score = X;
Counter = 0, Sum=0;
while (!fin.eof() )
{
Counter++;
if (Counter%3==0)
{
fin >> X;
Sum += X;
Counter++;
Counter2 ++ ;
Avg = (Sum+first_score)/(Counter2+1);
deviation = pow((X-Avg),2);
sum_of_deviations += deviation;
}
fin >> Score;
}
quotient_of_deviations = sum_of_deviations/Counter2;
standard_dev2 = sqrt(quotient_of_deviations);
fin.close();
I know this code is logically incorrect because I am subtracting a different mean from every x value. Does someone know how I could assign the X within the while loop to a new variable each time the while loop is ran? If I can do this, I will then be able to subtract each x value by the same mean outside of the loop. I hope I explained that good enough so that you guys can understand my problem. If not I will be happy to explain more. Thanks in advance for your time.
If you don't want to use arrays then you might have to read file multiple times.
int counter = 0;
int sum1=0;
ifstream fin,fin2; //fin and fin2 to read the file each time.
fin.open("myfile.txt"); //opening a file to read it.
while (!fin.eof() ) //reading a file
{
fin>>X;
sum1 = sum1+X; //adding all the numbers in the file
counter++; //counting number of items in the file
}
fin.close()
//Now first calculate mean
int mean=0;
mean = sum1/counter; //calculating the mean
//now calculate sum of squares of difference of each term and mean
int sum2=0;
fin2.open("myfile.txt"); //again opening the file with fin2
while (!fin2.eof() ) //again reading the file
{
fin2>>Y;
sum2 = sum2+ pow(Y-mean,2);
}
fin2.close()
//finally standard deviation
double sd=0;
sd = sqrt(sum2/mean); //calculating standard deviation
The problem with this is that you need to know the value of the average, but you won't know this until you have read in all the data. You are trying to calculate the deviation based on the average of the terms read in so far. This is incorrect
You should use the sqrt(Sum(x^2) /n - (sum(n) /n)^2) formula for the standard deviation.
Calculate the two sums in the loop, and then divide by n and complete the calculation at the end. Then you don't need to assign a new variable each time.
Related
Started to practice C++ by trying to do some tasks in CodeSignal, but I can’t figure it out why it has an output which is always false. Saw a similar answer to this task but didn’t want to copy and paste without understanding where the error is.
Ticket numbers usually consist of an even number of digits. A ticket number is considered lucky if the sum of the first half of the digits is equal to the sum of the second half.
Example:
For n = 1230, the output should be isLucky(n) = true
For n = 239017, the output should be isLucky(n) = false
Code:
bool isLucky(int n) {
string convert = to_string(n); // to convert from string to int
int sizehalbe = convert.size() / 2; //divide into 2 halfs
//Stor each half
string h1 = convert.substr(0, sizehalbe-1);
string h2 = convert.substr(sizehalbe, convert.size()-1);
int sum1=0, sum2=0; //Calculate the halfs
for(int i=0;i<h1.length();i++)
{
sum1 += int(h1.at(i));
}
for(int j=0;j<h2.length();j++)
{
sum2 += int(h2.at(j));
}
if(sum1 == sum2)
return true;
else
return false;
}
(1). Foremost your h1 always miss one digit so instead of
h1 = convert.substr(0, sizehalbe-1);
that's the only main issue your code has, convert should be gone till sizehalbe
string h1 = convert.substr(0, sizehalbe);
(2). whenever you typecast from character to integer, check what it gives
cout<<int('0'); will give you 48 instead of 0.
in particular, this case it's not changed your main output
(due to both sum1 & sum2 will get higher result than what actually should be,
but get same level of higher.)
sum½ += int(h½.at(i)) - 48;
(3). you can optimize your last condition.
when boolean result is depending on condition you can do
return (sum1 == sum2);
To get some more practice in C++, I decided to do some basic math functions without the aid of the math library. I've made a power and factorial function and they seem to work well. However, I'm having lots of problems regarding my Taylor Series cosine function.
Wikipedia Cosine Taylor Series
It outputs a good approximation at cos(1), cos(2), and begins losing precision at cos(3) and cos(4). Beyond that, its answer becomes completely wrong. The following are results from ./a.out
Input an angle in radians, output will be its cosine
1
Output is: 0.540302
Input an angle in radians, output will be its cosine
2
Output is: -0.415873
Input an angle in radians, output will be its cosine
3
Output is: -0.974777
Input an angle in radians, output will be its cosine
4
Output is: -0.396825 <-------------Should be approx. -0.654
Input an angle in radians, output will be its cosine
5
Output is: 2.5284 <-------------Should be approx. 0.284
Here is the complete source code:
#include <iostream>
#include <iomanip>
using std::cout;
using std::cin;
using std::endl;
int factorial(int factorial_input) {
int original_input = factorial_input;
int loop_length = factorial_input - 1;
if(factorial_input == 1 || factorial_input == 0) {
return 1;
}
for(int i=1; i != loop_length; i++) {
factorial_input = factorial_input - 1;
original_input = original_input * factorial_input;
}
return original_input;
}
double power(double base_input, double exponent_input) {
double power_output = base_input;
if(exponent_input == 0) {
return 1;
}
if(base_input == 0) {
return 0;
}
for(int i=0; i < exponent_input -1; i++){
power_output = power_output * base_input;
}
return power_output;
}
double cos(double user_input) {
double sequence[5] = { 0 }; //The container for each generated elemement.
double cos_value = 0; //The final output.
double variable_x = 0; //The user input x, being raised to the power 2n
int alternating_one = 0; //The (-1) that is being raised to the nth power,so switches back and forth from -1 to 1
int factorial_denom = 0; //Factorial denominator (2n)!
int loop_lim = sizeof(sequence)/sizeof(double); //The upper limit of the series (where to stop), depends on size of sequence. Bigger is more precision.
for(int n=0; n < loop_lim; n++) {
alternating_one = power(-1, n);
variable_x = power(user_input, (n*2));
factorial_denom = factorial((n*2));
sequence[n] = alternating_one * variable_x / factorial_denom;
cout << "Element[" << n << "] is: " << sequence[n] << endl; //Prints out the value of each element for debugging.
}
//This loop sums together all the elements of the sequence.
for(int i=0; i < loop_lim; i++) {
cos_value = cos_value + sequence[i];
}
return cos_value;
}
int main() {
double user_input = 0;
double cos_output;
cout << "Input an angle in radians, output will be its cosine" << endl;
cin >> user_input;
cos_output = cos(user_input);
cout << "Output is: " << cos_output << endl;
}
At five iterations, my function should maintain accuracy until after around x > 4.2 according to this graph on Desmos:
Desmos Graph
Also, when I set the series up to use 20 iterations or more (it generates smaller and smaller numbers which should make the answer more precise), the elements start acting very unpredictable. This is the ./a.out with the sequence debugger on so that we may see what each element contains. The input is 1.
Input an angle in radians, output will be its cosine
1
Element[0] is: 1
Element[1] is: -0.5
Element[2] is: 0.0416667
Element[3] is: -0.00138889
Element[4] is: 2.48016e-05
Element[5] is: -2.75573e-07
Element[6] is: 2.08768e-09
Element[7] is: -7.81894e-10
Element[8] is: 4.98955e-10
Element[9] is: 1.11305e-09
Element[10] is: -4.75707e-10
Element[11] is: 1.91309e-09
Element[12] is: -1.28875e-09
Element[13] is: 5.39409e-10
Element[14] is: -7.26886e-10
Element[15] is: -7.09579e-10
Element[16] is: -4.65661e-10
Element[17] is: -inf
Element[18] is: inf
Element[19] is: -inf
Output is: -nan
Can anyone point out what things I'm doing wrong and what I should be doing better? I'm new to C++ so I still have a lot of misconceptions. Thank you so much for taking the time to read this!
You have the following problems:
In the graph you are showing in the picture k is included in the sum, while you are excluding it in your code. Therefore k=5 in the Desmos graph is equal to double sequence[6] = { 0 } in your code.
This fixes the output for user_input = 4.
For user_input = 5 you can then compare to the graph to see that it gives a similar result as well (which is already far off of the true value)
Then you will have bugs for larger number of terms, because the factorial function outputs int, but the factorial grows so quickly that it will go out-of-range of the values int can hold quickly and also quickly out-of-range of any integer type. You should return double and let original_input be double as well, if you want to support a somewhat (though not much) larger input range.
In power you take the exponent as double, but work with it as if it was an integer. In particular you use it for the limit of loop iterations. That will only work correctly as long as the values are small enough to be exactly representable by double. As soon as the values become larger, the number of loop iterations will become inexact.
Use int as second parameter to power instead.
If one were to implement cos with this approach, one would normally use cos symmetry first, to reduce the range to something smaller, e.g. [0,pi/2] first, by using e.g. that cos(x + 2pi) = cos(x) and cos(x+pi) = - cos(x) and cos(-x) = cos(x), etc.
The problem comes from the factorial function you implemented.
I made minimal changes to your code and it runs fine for your example calculation of cos(1). Just #include <cmath> and replace factorial((n*2)) by tgamma(2*n+1). The output then reads
Input an angle in radians, output will be its cosine
Element[0] is: 1
Element[1] is: -0.5
Element[2] is: 0.0416667
Element[3] is: -0.00139082
Element[4] is: 2.48022e-05
Element[5] is: -2.75573e-07
Element[6] is: 2.08768e-09
Element[7] is: 4.65661e-10
Element[8] is: -4.65661e-10
Element[9] is: 4.65661e-10
Element[10] is: -4.65661e-10
Element[11] is: 4.65661e-10
Element[12] is: -4.65661e-10
Element[13] is: 4.65661e-10
Element[14] is: -4.65661e-10
Element[15] is: 4.65661e-10
Element[16] is: -4.65661e-10
Element[17] is: 4.65661e-10
Element[18] is: -4.65661e-10
Element[19] is: 4.65661e-10
Output is: 0.5403
This is the expected output for cos(1). For cos(n) with n>1 the problem is that the values for factorial_denom are getting to big for an integer. You should change the type to double: double factorial_denom. With your modified code I am getting the following results:
cos(1): Output is: 0.5403
cos(2): Output is: -0.416147
cos(3): Output is: -0.989992
cos(4): Output is: -0.653644
cos(5): Output is: 0.283662
Run your modified code online.
In addition to the changes already suggested, consider limiting the use of the series to a relatively narrow range of inputs. There are numerical problems you can encounter for very large angles, and they increase the amount of testing you need to do.
The cosine function has several identities, such as cos(x) = cos(-x) and cos(x) = cos(n*2*pi+x) for any integer n. Use these to reduce the angle to a limited range before running your series solution.
I am new c++ learner.I logged in Codeforces site and it is 11A question:
A sequence a0, a1, ..., at - 1 is called increasing if ai - 1 < ai for each i: 0 < i < t.
You are given a sequence b0, b1, ..., bn - 1 and a positive integer d. In each move you may choose one element of the given sequence and add d to it. What is the least number of moves required to make the given sequence increasing?
Input
The first line of the input contains two integer numbers n and d (2 ≤ n ≤ 2000, 1 ≤ d ≤ 106). The second line contains space separated sequence b0, b1, ..., bn - 1 (1 ≤ bi ≤ 106).
Output the minimal number of moves needed to make the sequence increasing.
I write this code for this question:
#include <iostream>
using namespace std;
int main()
{
long long int n,d,ci,i,s;
s=0;
cin>>n>>d;
int a[n];
for(ci=0;ci<n;ci++)
{
cin>>a[ci];
}
for(i=0;i<(n-1);i++)
{
while(a[i]>=a[i+1])
{
a[i+1]+=d;
s+=1;
}
}
cout<<s;
return 0;
}
It work good.But In a test codeforces server enter 2000 number.Time limit is 1 second.But it calculate up to 1 second.
How to make this code shorter to calculate faster?
One improvement that can be made is to use
std::ios_base::sync_with_stdio(false);
By default, cin/cout waste time synchronizing themselves with the C library’s stdio buffers, so that you can freely intermix calls to scanf/printf with operations on cin/cout. By turning this off using the above call the input and output operations in the above program should take less time since it no longer initialises the sync for input and output.
This is know to have helped in previous code challenges that require code to be completed in a certain time scale and which the c++ input/output was causing some bottleneck in the speed.
You can get rid of the while loop. Your program should run faster without
#include <iostream>
using namespace std;
int main()
{
long int n,d,ci,i,s;
s=0;
cin>>n>>d;
int a[n];
for(ci=0;ci<n;ci++)
{
cin>>a[ci];
}
for(i=0;i<(n-1);i++)
{
if(a[i]>=a[i+1])
{
int x = ((a[i] - a[i+1])/d) + 1;
s+=x;
a[i+1]+=x*d;
}
}
cout<<s;
return 0;
}
This is not a complete answer, but a hint.
Suppose our seqence is {1000000, 1} and d is 2.
To make an increasing sequence, we need to make the second element 1,000,001 or greater.
We could do it your way, by repeatedly adding 2 until we get past 1,000,000
1 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + ...
which would take a while, or we could say
Our goal is 1,000,001
We have 1
The difference is 1,000,000
So we need to to do 1,000,000 / 2 = 500,000 additions
So the answer is 500,000.
Which is quite a bit faster, because we only did 1 addition (1,000,000 + 1), one subtraction (1,000,001 - 1) and one division (1,000,000 / 2) instead of doing half a million additions.
Just as #molbdnilo said, Use math to get rid of the loop, and it's simple.
Here is my code, accepted on Codeforces.
#include <iostream>
using namespace std;
int main()
{
int n = 0 , b = 0;
int a[2001];
cin >> n >> b;
for(int i = 0 ; i < n ; i++){
cin >> a[i];
}
int sum = 0;
for(int i = 0 ; i < n - 1 ; i++){
if(a[i] >= a[i + 1]){
int minus = a[i] - a[i+1];
int diff = minus / b + 1;
a[i+1] += diff * b;
sum += diff;
}
}
cout << sum << endl;
return 0;
}
I suggest you profile your code to see where the bottlenecks are.
One of the popular areas of time wasting is with input. The fewer input requests, the faster your program will be.
So, you could speed up your program by reading from cin using read() into a buffer and then parse the buffer using istringstream.
Other techniques include loop unrolling and optimizing for data cache. Reducing the number of branches or if statements will also speed up your programs. Processor prefer crunching data and moving data around to jumping to different areas in the code.
I am working with a file that contains a set of data:
x values y values
20.00 0
20.02 15
20.04 27
20.06 39
20.08 54
20.10 65
20.12 75
The program is supposed to calculate the area under curve. In this part I am to do so for the first 6 x-y sets. My algorithm for finding the area is the sum of each trapezoid , which for these constraints, should only be 5 trapezoids. The each of each trapezoid is defined by: A = 0.5(base-base_0) * (height + height_0).
This is my code:
int main()
{
ifstream infile;
double AreaCurve = 0.0, NumberTraps = 0.0, height, height_0, base, base_0, AreaTrap;
infile.open("xydata.dat");
cin.ignore(20, '2');
while (NumberTraps < 6)
{
infile >> base_0;
infile >> height_0;
infile >> base;
infile >> height;
AreaTrap = 0.5 * (base - base_0) * (height + height_0);
AreaCurve += AreaTrap;
NumberTraps++;
}
cout << "The area under the curve is: " << setprecision(4) << AreaCurve << endl;
infile.close();
return 0;
}
When I compile the program nothing prints to the screen. I am not sure why this is happening but I believe it may have to do with an error in the line of my code containing the cin.ignore function (I can't edit the data, and I need to skip the line that reads: "x values\t\t y values")
Remove the line cin.ignore(20, '2'); .
This line will make your program wait for user input until they either enter twenty 2s, or enter a different character.
You shouldn't be reading any user input in this program, your input data comes from infile.
You will need to add code to ignore the first line of infile. A simple way to do that is string s; getline(infile, s);
Your program's main loop has a logic bug as well. You are reading in 2 lines at a time and considering that trapezoid, but then you are ignoring the trapezoid just after that one. (So you only count about half of the trapezoids).
Finally you should check for input success before processing that trapezoid:
if ( !infile )
break;
To ignore the first line of the infile stream (regardless of its length) you need:
infile.ignore( numeric_limits<streamsize>::max(), '\n' ) ;
Note, this needs the <limits> header.
You do not need to ignore to the first '2'. For starters the first x value would always have to start with '2', but more usefully std::istream::operator>> (double&); skips white-space including line ends in any case.
There are other issues with this code, such as attempting to read more values that the file contains, an incorrect integration algorithm, and having no error checking for a valid stream. Consider:
infile.ignore( numeric_limits<streamsize>::max(), '\n' ) ;
infile >> base_0;
infile >> height_0;
while( infile.good() )
{
infile >> base;
infile >> height;
if( infile.good() )
{
AreaTrap = 0.5 * (base - base_0) * (height + height_0);
AreaCurve += AreaTrap;
base_0 = base ;
height_0 = height ;
}
}
I am new to C++ programming and I am a bit lost. Here is what I am suppose to do and my code. Any ideas on what to do?
Write a program that uses while loops to calculate the first n Fibonacci numbers. Recall from math the following definition of the Fibonacci sequence:
The Fibonacci numbers Fn are defined as follows. F0 is 1, F1 is 1 and Fi+2 = Fi + Fi+1 for i = 0, 1, 2, ... . In other words, each number is the sum of the previous two numbers. The first few Fibonacci numbers are 1, 1, 2, 3, 5, 8, and 13.
The program should prompt the user for n (the number of Fibonacci numbers) and print the result to the screen. If the user enters an invalid value for n (n <= 0), print an error message and ask the user to re-enter n (an input validation loop for n). This MUST be a loop, not an if statement like Lab 2.
The output should be similar to the following:
Enter the number of Fibonacci numbers to compute: 3
The first 3 Fibonacci numbers are:
1 1 2
#include <iostream>
using namespace std;
int main()
{
int f0 = 0, f1 = 1,f2= 2, i = 0, n;
cout << "Enter the number of Fibonacci numbers to compute: ";
cin >> n;
if ( n <= 0)
{
cout <<"Error: Enter a positive number: ";
return 1;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
cout << "The first " << n << " Fibonacci numbers are: " << endl;
cin >> n;
return 0;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
See this loop, this is where the problem is, since this is homework, i'll not tell exactly what the problem is, take a pen and paper, and start executing your statements, specially this loop, you'll find your error. Just a hint, Fibonacci number is the sum of previous two fibonacci numbers.
You got the f2=f0+f1 right. However, you should note that when you increment i, then f2 becomes f1 and f1 becomes f0.
If you name them like this, it would make more sense:
int f_i_minus_2 = 0, f_i_minus_1 = 1, f_i;
and you would have
f_i = f_i_minus_1+f_i_minus_2;
Now, imagine i is 3. You have written:
f[3] = f[2]+f[1]
When you increment i, you must have:
f[4] = f[3]+f[2]
That is f_i is put in the place of f_i_minus_1 and f_i_minus_1 is put in the place of f_i_minus_2.
(Look at this:
f[3] = f[2] + f[1]
| |
\_____ \____
\ \
f[4] = f[3] + f[2]
)
So you need two assignments after computing f_i:
f_i_minus_2 = f_i_minus_1;
f_i_minus_1 = f_i;
Note that I first changed f_i_minus_2 to f_i_minus_1 because the second assignment destroys the value of f_i_minus_1.
According to wikipedia, your definition is off. F0=0, F1=1, F2=1, F3=2, ...
http://en.wikipedia.org/wiki/Fibonacci_number
Assuming wikipedia is right your loop is basically
int i = 0, f, fprev;
while( i < n )
{
if( i == 0 )
{
f = 0;
fprev = 0;
}
else if( i == 1 )
{
f = 1;
}
else
{
int fnew = f + fprev;
fprev = f;
f = fnew;
}
i++;
}
As others have pointed out, since you never modify f0 and f1 in the
loop, f2 isn't going to depend on the number of times through the
loop. Since you have to output all of the numbers at the end anyway,
why not try keeping them in an array. I'd initialize the first two
values manually, then loop until I had enough values.
(This can be done quite nicely using the STL:
// After having read n...
std::vector<int> results( 2, 1 );
while ( results.size() < n )
results.push_back( *(results.end() - 1) + *(results.end() - 2));
I'm not sure that this is what your instructor is looking for, however.
I rather suspect that he wants you to to some indexing yourself. Just
remember that if you initialize the first two values manually, your
index must start at 2, not at 0.)
Another thing: the specification you post says that you should loop if
the user enters an illegal value. This is actually a little tricky: if
the user enters something that isn't an int (say "abc"), then 1)
std::cin will remain in error state (and all further input will fail)
until cleared (by calling std::cin.clear()), and the illegal
characters will not be extracted from the stream, so your next attempt
will fail until you remove them. (I'd suggest >>ing into an
std::string for this; that will remove everything until the next white
space.) And don't ever access the variable you >>ed into until
you've checked the stream for failure—if the input fails. If the
input fails, the variable being input is not modified. If, as here, you
haven't initialized it, then anything can happen.
Finally (and I'm sure this goes beyond your assignment), you really do
need to do something to check for overflow. Beyond a certain point,
your output will become more or less random; it's better to stop and
output that you're giving up in this case.
If you are interested, there are better ways to calculate it.