c++: general q about for-statements and arguments [duplicate] - c++

This question already has answers here:
What is the correct way of using C++11's range-based for?
(4 answers)
Closed 4 years ago.
I'm in the process of learning c++. I've come across an assignment about temperatures I don't understand. Could you guys clarify some things for me?
Here's the code
// compute mean and median temperatures
int main()
{
vector<double> temps; // temperatures
for (double temp; cin>>temp; ) // read into temp
temps.push_back(temp); // put temp into vector
**// compute mean temperature:
double sum = 0;
for (int x : temps) sum += x;
cout << "Average temperature: " << sum/temps.size() << '\n';**
// compute median temperature:
sort(temps); // sort temperatures
cout << "Median temperature: " << temps[temps.size()/2] << '\n';
}
Now the second block (//compute mean temperature) is the stuff I cannot follow.
First off, a for-statement is used with a single argument. Won't this mean that there is just an initial expression and no condition?
I also don't think I have a firm understanding of int X : temps int X isn't defined anywhere else in this bit of code. Won't it cause an error as it has no value assigned to it? Let's say it has a value of 1; what does it do/what does it check? Does it check how many times X fits in vector temps? Why not do this then:
int sum_of_measurements = 0; //value of all measurements
for (int y = 0; y <= temps.size(); ++y){
sum_of_measurements = sum_of_measurements + temps[y]; // add value of measurement to the total for each measurement
}
double mean = sum_of_measurements/temps.size();
cout << mean <<'\n';
//rest of code
What's this identifier called so I can learn more about it (the : in int X : temps)
Thanks :)

That's the range-based for loop, introduced in C++11.
A statement like:
for (int someVal: someCollection)
will iterate over someCollection with someVal being set to each item within the collection (one per iteration).
In your specific case (after changing the type of x to one more suitable), the snippet:
double sum = 0;
for (double x : temps)
sum += x;
is functionally equivalent to:
double sum = 0;
for (int i = 0; i < temps.size(); ++i)
sum += temps[i];

Related

Merging points closest to each other in an array of 3 elements each

I am implementing a simple greedy merging algorithm that merges the two points which are closest to each other and averages their position. After merging two points at indices i and j, I need to replace one of them, say i, by the mean of the two points. Then, copy the last point in the array over the other point, say j, after which I can reduce the array size by 1 with all remaining points being within the new reduced range.
I need to repeat the above step until there are only 3 representative points left, each of which represents a group of merged points. I have written the following code, but I guess it is not able to update the array (pts). I would appreciate if anyone could help me figure out the mistake. Thanks in advance. This is my code:-
void merge_point(Point pts[], int &size) {
double a;
int x, y;
Point d;
while(size != 3) {
double min = get_distance(pts[0],pts[1]);
for (int i = 0; i < size; i++) {
for (int j = i+1; j < size; j++) {
get_distance(pts[i], pts[j]);
if ((a = get_distance(pts[i],pts[j])) <= min) {
x = i;
y = j;
}
a = get_distance(pts[i],pts[j]);
}
}
d = mean_point(pts[x],pts[y]);
pts[x] = d;
pts[y] = pts[size-1];
size = size - 1;
}
}
When I am entering the input array as :-
3 8 2
5.7 7.2 2.2
10.83 6.48 2.42
20.577 5.832 2.662
39.0963 5.2488 2.9282
74.283 4.72392 3.22102
141.138 4.25153 3.54312
268.162 3.82638 3.89743
509.507 3.44374 4.28718
968.063 3.09936 4.7159
My expected output should be:-
181.974 4.29686 3.57395
968.063 3.09936 4.7159
509.507 3.44374 4.28718
But, I am getting an output of:-
4.35 7.6 2.1
968.063 3.09936 4.7159
36.6506 5.8958 2.68145
Think I find out the problem, you don't update the min distance as soon as you find a new one during the cicle, try this:
cout << "distance between p[" << i << "] and " << "p[" << j << "]" << "is " << get_distance(pts[i], pts[j]) << '\n';
if ((a = get_distance(pts[i], pts[j])) <= min)
{
cout << "current min distance is between point[" << i << "]" << " and point[" << j << "]" << '\n';
min = a;
x = i;
y = j;
}
you've got to add this instruction:
min = a;
in order to update the min.
Otherwise it will works only for some edge cases.

How to display values *only* at every x steps

I'm trying to finish up a program which calculates the natural logarithm of 2, based on the desired # of terms to use and how many values to display after every x step. For example if the user inputs 6 terms, displaying them every 2 steps it would have this output;
0.5000000000
0.5833333333
0.6166666667
instead of:
1.0000000000
0.5000000000
0.8333333333
0.5833333333
0.7833333333
0.6166666667
This loop doesn't work correctly for what I'm trying to do and I'm trying to find out what adjustments to make for it to work. Any help is appreciated.
for(double x = 1; x <= numofterms; x += 1){
logarithm += denominator * 1 / x;
denominator = -denominator;
int printCounter = 0;
for(int i=1; i<=numofterms; i++) {
printCounter++;
if(printCounter >= displaycount) {
cout << setprecision(10) << showpoint << logarithm << endl;
printCounter = 0;
}
You are using printCounter >= displaycount which is wrong
Lets say printCounter is 100 and displaycount is 20 so you should get 6 lines, but after printCounter reaches 20 it will display for every line so you get 81 lines.
So better use printCounter % displaycount == 0 this will only show the lines for 0,20,40,60,80,100 value of printCounter
Here is a code that can do it:
int curPrintStep = displayCount;
for (int i = 1; i <= numOfterms ; i++) {
logarithm += denominator * 1 / (double) i;
denominator = -denominator;
if (i == curPrintStep) {
cout << setprecision(10) << showpoint << logarithm << endl;
curPrintStep += displayCount;
}
}
The variable i contains the current step of the algorithm and at the same time is used to calculate the logarithm.
I set up a step counter variable curPrintStep which is set to the first printing step. Every time I check and if the current step is equal to the print step, I print the logarithm and change the curPrintStep to point to the next print step (by adding displayCount to it).

Product sequence in a for cicle [duplicate]

This question already has an answer here:
Integer division always zero [duplicate]
(1 answer)
Closed 8 years ago.
I know this has to be something extremely idiotic, but I really can't find my mistake.
I'm trying to write a program to calculate (2/i)^i, where i is an integer put in input by the user. If i = 0, the function returns 1.
This is the function I have been using.
double f (int x)
{
double y = 1.0;
if (x == 0)
return 1;
else
for (int i = 1; i <= x; i++)
y *= pow (2/i, i);
return y;
}
int main ()
{
for(int i=0;i<=10;++i)
cout << "f(" << i << ") =" << f(i) << endl;
}
Now.. This is supposed to be an extremely simple code. Yet, it doesn't work. It compiles correctly, but the results are not what I'm expecting. After some iterations, I always get 0 as a result. What am I doing wrong?
Integer division:
change to:
y *= pow (2.0/i, i);
^^^
Also, why do you need a loop?

Working with files & FOR loop [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
My task is: in every language is n most used words. A boy after d days is leaving for Sweden. Wanting to understand Swedish, the first day he learns z words and the each following day k words more than a day before. Write a program, which would check if a boy will successfully will learn n words during d days.
Let's say that he needs to learn 100 words. He has 20 days. The first day he learned 5 words. Each following day he learned 1 words more than a day before.
In this case answer should be: yes (he will successfully will learn it during 20 days), and 11 (during 11 days he will learn 100 words).
I have a code written.
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main()
{
int n, d=0, k, z;
ofstream fr("Rezults.txt");
ifstream fd("Data.txt");
fd>>n>>d>>z>>k;
int learned_words = 0;
for(int i=0; i<d; i++){
learned_words += z;
z = z+k;
}
if(n<=learned_words) {
fr<<"Yes"<<endl;
}
else
{
fr<<"No"<<endl;
}
z=z-d; d=0;
for(int m=0; m<=n; m+=z, z+=k, d++) {}
cout << "You need " << d << " days to learn " << n << " words";
fd.close();
fr<<d;
fr.close();
return 0;
}
You can simply count the loop by using the for loop in this way:
for (i=z; i<=n; i++)
{
}
cout<< i << endl;
You can simply see the variable "i"'s value right after the loop
This simple function solves the problem in the beginning of your question:
// z : the number of words learned during the first day
// k : this much more we learn after every day
// (i.e first day we learn z words, then z+k, then z+k+k etc.)
// d : this many days we have time to learn
// n: this many words we should learn
bool solve(int z, int d, int k, int n) {
int learned_words = 0;
for(int i=0; i<d; i++){
learned_words += z;
z = z+k;
}
if(n<=learned_words) {
return true;
}
return false;
}
To answer your question about loops, I think the following very simple loop would work:
int n = 100;
int z = 5;
int k = 1;
int d = 0;
for(int m=0; m<n; m+=z, z+=k, d++) {}
cout << "You need " << d << " days to learn " << n << " words";
Here the loop will get executed the minimal number of times needed to learn those n words. The variable d counts the days needed and must be declared before the loop. m counts how many words we have learned.
Despite having for loop in the title, there's no requirement for the loop in the task and no reason to actually use it here (unless you're limited to integer arithmetic).
It would be much easier to simply compute days needed to learn n words (it's simple quadratic equation) and compare it with d.
Number of words (y) learnt during first x days is:
y = z * x + k * x * (x-1)/2. So just solve this equation for y = n.
I'd do something like: (variables a and b are coefficients of the quadratic equation).
const double a = k/2.0;
const double b = z-k/2.0;
const double days_needed = -b + ::sqrt(b*b + 4 * a * n)/(2.0 * a);
std::cout << (days_needed <= d ?"yes":"no") << ", you need " << ::ceil(days_needed) << "days\n";

Finding a minimum value in a for loop and keeping the index of it

I am working on a homework assignment where I calculate the values in an interval of integers of a function (f(x) = x * x – 12 * x + 40) in a 'for' loop. I need to find a minimum value. That's all fine, but I also need to keep the index number for which the value was smallest. At the moment I reiterate the function again in another loop, but this looks really messy. Also I could derive x and calculate the answer using the known minimum, but that's also weird, because derivation is not so straightforward. Do you have any tips for me? Thanks.
#include <iostream>
#include "limits.h"
using namespace std;
int main ()
{
int lBound, uBound, y, min;
cout << "Give the lower and the upper bounds of integer numbers: " << endl;
cin >> lBound >> uBound;
min=INT_MAX;
int x = lBound;
for (int i = x; i <=uBound; i ++) {
y = i * i - 12 * i + 40;
cout << x << " " << y << endl;
if (y<min) {
min=y;
}
x++;
}
for (int i = lBound; i <= uBound; i++) {
y = lBound * lBound - 12 * lBound + 40;
if (y==min) {
y = lBound;
i=uBound; // terminates the loop
}
lBound++;
}
cout << "smallest value of the function is " << min << " for x = " << y << endl;
return 0;
}
Here's a hint: Whenever you need to "keep something around" in a program, that means you need to store it in a variable. Whether that variable is local, global, or passed around depends on how long you need to keep it around. This is called the variable's "scope". It's considered good practice to keep the scope of any variable to a minimum, hence the guidelines discouraging globals.
i=uBound; // terminates the loop
This is not a very good coding practice. To terminate a loop, you should use a flow control construct like break. Doing so in this case would preserve the index of the minimum element.
Edit: If you want i to outlive the loop, you simply need to declare it outside. To wit:
change
for (int i = lBound; i <= uBound; i++) {
to
int i; // variable exists outside loop
for (i = lBound; i <= uBound; i++) {
Furthermore, just FYI, loop bounds are usually specified as half-open intervals to avoid the potential issue where lbound and ubound represent the limits of the int data type. This means that you usually use < instead of <=.
It's not clear if you're in an algebra class or a CS class…