Hello, I am new here.. I came here looking for help with some ACPP questions and found a couple. So now, hopefully, I can give back a little, but with a question!

Here is my solution for ACPP Exercises 4-2 through 4-4 (sort of, I havent switched it to use doubles yet).

Anyways, for anyone curious, here are the questions..


4-2. Write a program to calculate the squares of int values up to 100. The program should write two columns: The first lists the value; the second contains the square of that value. Use setw (described above) to manage the output so that the values line up in columns.

4-3. What happens if we rewrite the previous program to allow values up to but not including 1000 but neglect to change the arguments to setw? Rewrite the program to be more robust in the face of changes that allow i to grow without adjusting the setw arguments.

4-4. Now change your squares program to use double values instead of ints. Use manipulators to manage the output so that the values line up in columns.

So, what I eventually did was make the question ask for the max integer to create squares of up to, and the max square to display (4-3?).

My question is, was it overkill to add the checking if the sqrt of 'cutoff' is larger than 'max' than to make 'cutoff' = 'max'.

The reason I decided to do this was to not makiea vector that may be too large, specifically if it wasnt going to be displayed.. make sense?

Anyways, i was stuck on this problem for a while and this is what I finally came up with.. any advice or tips on how I could improve this?? Am i wrong in my assumption of trying to save cycles by not writing to the vector if its not necessary??

Thanks!

#include <iostream>
#include <vector>
#include <iomanip>
#include <math.h>

using namespace std;

int main()
{
    int x, max, sqWidth, iWidth, cutoff = 0;
    vector<int> squares;

    while (cutoff <= 0 ) {
        cout << "Enter cutoff square to output: ";
        cin >> cutoff;
    }

    while (max <= 0 ) {
        cout << "Enter max number to calcate squares up to: ";
        cin >> max;
    }

    if (sqrt(cutoff) < max) {
        max = sqrt(cutoff);
    }

    for (int i=0; i != max; i++) {
        x = (i+1) * (i+1);
        squares.push_back(x);
    }

    iWidth = log10(max)+1;
    sqWidth = log10(squares[max-1])+1;

    x = 0;
    while (squares[x] < cutoff && x != max) {
        cout << setw(iWidth) << x+1 << " " << setw(sqWidth) << squares[x] << endl;
        x++;
    }

    for (int i = 0; i < max; i++) {
        cout << setw(iWidth) << i+1 << " " << setw(sqWidth) << squares[i] << endl;
        i++;
    }
}

You're asking two questions when one question will suffice, so I would say it's overkill. Ask either of these:

Input largest value to square :

or

Input largest squared value :

but not both because one derives from the other. Frankly I think the first question is easier for the user to understand. You can have some maximum value and check against it:

bool haveMaxValue = false;
const int MAX_ALLOWED_CUTOFF = 1000;
int cutoff;

while (!haveMaxValue)
{
     cout << "Enter largest value to square : ";
     cin >> cutoff;

     if (cutoff < 0 || cutoff > MAX_ALLOWED_CUTOFF)
     {
         cout << "Please enter a non-negative value <= ";
         cout << MAX_ALLOWED_CUTOFF << endl;
     }
     else
         haveMaxValue = true;
}

If you can ask one question instead of two, do it.

Thanks VD. Agreed that I could have gotten away with just setting the max square to display as a const int. But, in the interest of learning I wanted to make it an entered variable so I could see how setting it to different values would affect the vector of squares.

You may notice that I calculate all the squares up to the max number and store them in a vector. Then I display the vector twice, first using the cutoff of the square to display and second, the entire vector, formatting the column widths with depending on how many digits are in the largest cutoff amount and the max value.

Then, I found that if I set the max square to caclulate up to was say 500, but I set my cutoff to dislpay only up to 1000 if found the vector still stored squares 1 - 500, but wouldnt show all of them (expectedly) - hence why I checked to see if the sqrt(cutoff) is smaller than the max value.. and if so set max to that so, result being it doesnt create a vector with a whole bunch of squares that will never be displayed.

I was just curious if this a valid tactic when optimizing c++ code, or am I just totally over engineering this thing? I did learn a lot though!

Thanks VD. Agreed that I could have gotten away with just setting the max square to display as a const int. But, in the interest of learning I wanted to make it an entered variable so I could see how setting it to different values would affect the vector of squares.

You may notice that I calculate all the squares up to the max number and store them in a vector. Then I display the vector twice, first using the cutoff of the square to display and second, the entire vector, formatting the column widths with depending on how many digits are in the largest cutoff amount and the max value.

Then, I found that if I set the max square to caclulate up to was say 500, but I set my cutoff to dislpay only up to 1000 if found the vector still stored squares 1 - 500, but wouldnt show all of them (expectedly) - hence why I checked to see if the sqrt(cutoff) is smaller than the max value.. and if so set max to that so, result being it doesnt create a vector with a whole bunch of squares that will never be displayed.

I was just curious if this a valid tactic when optimizing c++ code, or am I just totally over engineering this thing? I did learn a lot though!

It's definitely not optimal. One, calculating the square root is unnecessary. Calculate the squares. I have to believe that's a much faster operation. I see nothing in the specification that says you need to calculate the square root of anything. Ditto the logarithms. Why are you calculating the logarithms? That's another unnecessary, computationally expensive calculation. Finally, if you are optimizing, take advantage of the fact that you know EXACTLY how many squares you need to calculate and make your vector that size if you want to use a vector. Right now, using push_back, you force the compiler to guess, then when its guess is wrong, resize the vector. That's inefficient. When you KNOW the size, and you do here because the user enters it, SPECIFY the size. it takes all the guesswork out.

[EDIT]
OK, I see your reasoning behind the logarithms now, so that's not bad. Regarding efficiency/optimization, though, please take a look at the rest of my post.
[/EDIT]

Thannks again VD, makes sense. Lessons are, when optimizing is to take advantage of explicitly declared numbers, sqrt is a CPU intensize function, ram is cheap :)

Cheers!

This question has already been answered. Start a new discussion instead.