Make a program that makes a double vector with at least 30 negative and positive elements. I also must have functions to calculate/print the standard deviation (that one I finished earlier here, thank you dutch: http://www.cplusplus.com/forum/beginner/273688/ ), the mean value, the highest value, and the lowest value of the vector. Next, I will need a split() function to split the values of the double vector into 2 new double vectors, positive and negative (the former will have all values from 0 - max_positive_value while the latter will have all nonzero negative values). Finally, I need one last function to display both of these modified vectors.
My Issue:
Nothing is being printed from my split() function! For debugging purposes, I made it so that it prints all the values of the positive and negative vectors, but it isn't printing anything!
In the first bit of code lines 3 and 4 define a vector, but it has no size, i.e., no elements.
In lines 13 and 18 you are trying to access a if it has a fixed number of elements like an array does. What you need in place of positive[j] = data[i]; is positive.push_back(data[i]) which will add to the vector until "data" has reached the end.
A possible problem is that lines 3 and 4 are local variables and will be destroyed when the function, so if you need these vectors outside the function consider defining them in "main" and passing them to the function like you did "data", but without the "const" part.
In lines 24 and 29 change the "int" to "size_t" as the ".size()" function returns a "size_t" type variable. This way in the middle conparison the variable types will match based on your header files and how "size_t" is defined. You will also need to change everywhere you use a ".size()" function
Thanks for the help! I didn't know about the size_t thing before since I don't really have much experience with vectors. The great thing is that it DOES print now, but some reason doesn't store the negative numbers of the data vector in the negative array. It outputs something like this:
I made the changes that you suggested. As for lines 3 and 4, I was intending to figure out some way to return these vectors since I have to use as the parameters for some other functions (namely, to find the largest/lowest and the mean). The new source:
In my main() function on L77, should I also change that to data.push_back(rand() - (RAND_MAX / 2)); ? I am not completely sure, but it doesn't SEEM like it causes an issue. Is it because I already declared the size of the vector and it's not empty, so that's why I can access any of its empty elements?
Also I like to use this with "srand": srand(static_cast<unsignedint>(time(nullptr)));. "stand" takes an "unsigned int" as its parameter, but "time()" does not return an "unsigned int". In more modern C++ the "nullptr" is the better choice even though what you have still works.
int main()
{
constexprint MAXSIZE{ 30 };
// vector with minimum 30 values
vector <double> data; // <--- Do not give this a starting size.
vector <double> positive;
vector <double> negative;
// seed rand() with time
//srand(time(NULL));
srand(static_cast<unsignedint>(time(nullptr)));
// fill vector with neg/pos num
for (int i = 0; i < MAXSIZE; ++i)
{
data.push_back(rand() - (RAND_MAX / 2));
// cout << data[i] << endl;
}
split(data, positive, negative);
}
// <--- Should be a void function. No reason to return anything.
void split(const vector<double> &data, vector<double> &positive, vector<double> &negative)
{
//int j = 0; // iterate inner <--- Does this hae a use?
// add to pos/neg vector depending on value of data[i]
for (size_t i = 0; i < data.size(); ++i)
{
if (data[i] >= 0)
{
positive.push_back(data[i]);
//j++;
}
elseif (data[i] < 0)
{
negative.push_back(data[i]);
//j++;
}
}
// ... more code follows.
By passing the last 2 vectors by reference you do not have to return anything. Any how the problem is that a function can only return 1 thing. That is the best way of looking at it for now because any code that could return both vectors is likely beyond where you are at right now.
And for fun, since I am figuring that you will not keep this part I did:
To your other question. When you define vector <double> data (30);. You are creating a vector with 30 elements all set to 0.0. Later when you do the "push_back" you are just adding to the original 30 and end up with a vector that has a size if 60. No what you want.
No worries. It happens to the best of us now and then.
Andy
Edit:
The way I noticed is the when "positive.size()" was less than "negative.size()" the second for loop was trying to access the "positive" vector beyond the end of its size.
Additionally, on L21 of that same codeblock, why do you pass them in as direct parameters? I read that passing by reference uses significantly less resources (I'm sure modern computers don't have much issue dealing with a few extra bytes here and there, but I previously thought that the point still stood) than passing in a parameter directly. I thank you for your time thus far and going forwards!
( If you are curious as to what my final product looks like, it is saved at this location: https://pastebin.com/JRPKttEg )
constexpt started with the C++ 2011 standards. It is similar to using const. VAriables defined as constant are usually in all capital letters, but not a requirement.
The point of defining at the beginning of the function, or near the beginning of the file, is that you only have 1 place to change this variable and everywhere it is used in the code will see this change.
An example would be let's say that you have 1000 to 1500 lines of code and that you have many for loops like: for (int i = 0; i < 10; i++). Now you need to go through these 1000+ lines of code to find all the for loops to change the 10 to 20, but you will likely miss 1 or 2 that you will find when the program runs and some output is short.
Using for (int i = 0; i < MAXSIZE; i++) in all the for loops you only have 1 place to change the size of the variable and it will been seen everywhere "MAXSIZE" is used and use the new value of "MAXSIZE".
It is a simple thing that makes writing the code easier.
I think you are referring to split(data, positive, negative);. This is the function call and you only have to send the variable name(s) for this. At the function definition: void split(const vector<double> &data, vector<double> &positive, vector<double> &negative). Here it is saying that the variables are being received by reference and that you will be using the variables where they were first defined, in this case "main". The opposit would be to leave off the "&" which means that the variables are being received by value, or it is a copy of the variable passed to the function, which can get expensive to create the extra memory needed just to use it in the function.
When it comes to "std::string"s, "std::vector"s and other container classes it is better to pass by reference and not have to make an expensive copy.
When I looked at your link I noticed that in the "split" function several things.
First you do make use of blank lines, but in several places the double spacing is not needed. You kind of over did it there.
You define the "int j", but it does not appear to have any use.
A function should do 1 thing, do it well and return. The last lines of the function calling the other functions should not be here. They should be in "main" where "main" is designed to set up and direct the program flow to the other functions. Which is why you would define the vectors "positive" and "negative" in "main" and then pass them to the functions that need them.
At first glance I did not see anything that might be a big problem, but I will copy the code and give it a test and let you know what I find.