Reputation: 19
I am writing a program that determines the prime factors of a range of numbers. In the program, the startingNumber
and endingNumber
of the range is indicated as a std::pair
.
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const long long MAX = 100000000; // One hundred million
long long factor[MAX];
pair<const long long, const long long> get_pair() // Gets user start and end number to establish range in vector.
{
long long largestNumber = 100000000;
long long smallestNumber = 2;
std::pair<long long, long long> p;
cout << "Enter a start number: ";
cin >> p.first;
while (p.first < smallestNumber || p.first > largestNumber || cin.fail()) {
cin.clear();
cin.ignore(1000, '\n');
cout << "That's not a valid choice. Please try again (" << smallestNumber << " - " << largestNumber << "): ";
cin >> p.first;
}
cout << "Enter a end number: ";
cin >> p.second;
while (p.second < p.first || p.second > largestNumber || cin.fail()) {
cin.clear();
cin.ignore(1000, '\n');
cout << "That's not a valid choice. Please try again (" << p.first << " - " << largestNumber << "): ";
cin >> p.second;
}
cout << endl;
return make_pair(p.first, p.second);
}
vector<long long> rangeToVector(const long long &startingNumber, const long long &endingNumber) // creates vector of numbers from std::pair.
{
vector<long long> iterator;
for (long long i = 1; i <= ((10 - 1) + 1); i += 1) iterator.push_back((1-1)+i);
return iterator;
}
void precalculate() // Calculates all of the prime numbers between 1 and MAX. Stores prime numbers from smallest to largest.
{
for (long long i = 1; i < MAX; i++) { // stores 1 through Max in factor.
factor[i] = i;
}
for (long long i = 2; i * i < MAX; i++) if (factor[i] == i) { // If factor[i] is even.
for (long long j = i + i; j < MAX; j += i) {
factor[j] = i;
}
}
}
The above code works as intended. The code is then input into the follow function, I am unsure as to whether or works correctly(Since my function in main will not compile).
vector<long long> get_factors(vector<long long> &vect) // performs calculation on rangeToVector[i] (determined by precalculate) until it is not divisible, then it returns those that were divided into the number as prime factors of the rangeToVector[i].
{
vector<long long> factors;
for (auto i : vect)
{
while (vect[i] > 1)
{
long long f = factor[vect[i]];
factors.push_back(f);
vect[i] /=f;
}
}
sort(factors.begin(), factors.end()); // sorts the vector.
factors.erase(unique(factors.begin(), factors.end()), factors.end()); // erases duplicates (requires sorted vector).
return factors;
}
In main (line 3), I receive the error underlining rangeToVector
, initial value of reference to non-const must be an lvalue
.
int main()
{
for (auto i : get_factors(rangeToVector(pairs.first, pairs.second))) // get_factors returns factors of numbers in vector rangeToVector
{
cout << i << " ";
}
system("pause");
return 0;
}
I attempted to make the values in rangeToVector
constants, but this has not solved the problem. My question is, is my referencing incorrect? Should I pass the function differently? Or what can I do to the code to allow get_factors
to take the factors of rangeToVector[i]
in main on line 3. I am new to c++, so any help would be greatly appreciated.
Upvotes: 1
Views: 12205
Reputation: 41760
Your problem lies here:
std::vector<long long> get_factors(std::vector<long long> &vect) { ... }
The variable vect
is an lvalue reference, that means it's a reference that cannot bind to temporary variables.
Yet, you use it like that:
get_factors(rangeToVector(...))
Where rangeToVector
returns a temporary.
The solution to that is simply to make vect
a constant lvalue reference, which can bind to a temporary:
// const here -------v
std::vector<long long> get_factors(std::vector<long long> const& vect) { ... }
You have many other problems in your code, I suggest you to read a good C++ and try to not assume things about it's syntax. For example, you don't use range for loops correctly:
for (auto i : vect) {
while (vect[i] > 1) {
long long f = factor[vect[i]];
factors.push_back(f);
vect[i] /=f;
}
}
The correct usage will be:
for (auto& i : vect) {
while (i > 1) {
long long f = factor[i];
factors.push_back(f);
i /= f;
}
}
Upvotes: 3
Reputation: 19
First of all, I would like to thank everyone for their comments and suggestions, it helped me solve my problem. As Guillaume Racicot mentioned, I definitely needed to study up more on vectors. Again, thank you.
My problem was within the code below:
vector<long long> get_factors(vector<long long> &vect) // Notice how I have it relying on "vector<long long> &vect".
{
vector<long long> factors;
for (auto i : vect)
{
while (vect[i] > 1)
{
long long f = factor[vect[i]];
factors.push_back(f);
vect[i] /=f;
}
}
sort(factors.begin(), factors.end()); // sorts the vector.
factors.erase(unique(factors.begin(), factors.end()), factors.end()); // erases duplicates (requires sorted vector).
return factors;
}
and the way that I called it in main:
for (auto i : get_factors(rangeToVector(pairs.first, pairs.second))) // get_factors returns factors of numbers in vector rangeToVector
{
cout << i << " ";
}
In order to solve my problem, I needed to realize that in order to access vectors/arrays, you have to create a for loop to gather its values. Therefore, my solution was as follows.
vector<long long> get_factors(long long x, vector<long long> vec )
{
vector<long long> factors;
while (x > 1) { /* insert code*/ vec.push_back(f); } // Or use a for loop.
return vec;
}
int main(int argc, const char * argv[]) {
vector<long long> temp1;
for (long long val : inputVector) // where initial data was stored (see original post)
{
result1 = getPrimes(val, temp1); // iterate through vec as long long in function
}
return 0;
}
Upvotes: 0