Not getting any output from c++ program - c++

#include <vector>
#include <cmath>
void print(std::vector <int> const& a) {
for (int i = 0; i < a.size(); i++) {
std::cout << a.at(i) << " ";
}
}
std::vector<int> factors(int n) {
std::vector<int> vec = {};
for (int i = 0; i < round(sqrt(n)); i++) {
if (size(factors(i)) == 0) {
vec.push_back(i);
}
std::cout << i;
}
return vec;
}
int main() {
std::vector<int> vec = factors(600851475143);
print(vec);
}
This is my C++ code for Project Euler #3.
New to C++, so my code might be completely wrong syntactically, however I am not getting any build errors (using Visual Studio).
Not getting any output however. I understand this could be my fault, and the program might just be running extremely slow. But I programmed this in python using the same iterative method and it worked perfectly with a fast runtime.
Edit:
I am however getting this message in the console:
D:\RANDOM PROGRAMMING STUFF\PROJECTEULER\c++\projecteuler3\x64\Debug\projecteuler3.exe (process 13552) exited with code 0.
Press any key to close this window . . .

If you enable your compiler warnings, you should see an overflow warning
prog.cc: In function 'int main()':
prog.cc:23:36: warning: overflow in conversion from 'long int' to 'int' changes value from '600851475143' to '-443946297' [-Woverflow]
23 | std::vector vec = factors(600851475143);
so what gets passed to factors is not 600851475143 but -443946297

Of course Gaurav has given the correct answer. This is how to fix it, change from int to unsigned long long, to allow for the biggest integers possible that are supported without any external libraries
#include <cmath>
#include <iostream>
#include <vector>
void print(std::vector<int> const& list){
for( auto const& item : list){
std::cout << item << "\n";
}
}
std::vector<int> factors(unsigned long long n) {
std::vector<int> vec = {};
for( int i = 0; i < std::round(std::sqrt(n)); ++i ){
if( factors(i).empty() ) {
vec.push_back(i);
}
//std::cout << i << ", ";
}
return vec;
}
int main() {
std::vector<int> vec = factors(600851475143ULL);
print(vec);
}
I have also done some other minor changes:
Change the foor loop of print to a rang-based for loop
Added a delimeter i printing
added std:: namespace to functions
replaced size(vec) == 0 with empty to improve readability
Another good habit is to compile with -Wall to enable more warnings and -Werror so you are actually forced to take care of all warnings instead of brushing them off.

Related

Selection Sort Implementation with C++ incorrect

really new to C++, trying to instantiate some basic algorithms with it. Having trouble returning the correct result for selection sort. Here is my code
#include <iostream>
#include <array>
#include <vector>
using namespace std;
// Selection Sort :
int findMin(vector<int> &arr, int a)
{
int m = a;
for (int i = a + 1; i < arr.size(); i++)
{
if (arr[i] < arr[m])
{
m = i;
}
return m;
}
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void selectionSort(vector<int> &arr)
{
if (!arr.empty())
{
for (int i = 0; i < arr.size(); ++i)
{
int min = findMin(arr, i);
swap(arr[i], arr[min]); // Assume a correct swap function
}
}
}
void print(vector<int> &arr)
{
if (!arr.empty())
{
for (int i = 0; i < arr.size(); i++)
{
cout << arr[i] << "";
cout << endl;
}
}
}
int main()
{
vector<int> sort;
sort.push_back(2);
sort.push_back(1);
sort.push_back(7);
sort.push_back(4);
sort.push_back(5);
sort.push_back(3);
print(sort);
cout << "this was unsorted array";
cout << endl;
cout << findMin(sort, 0);
cout << "this was minimum";
cout << endl;
selectionSort(sort);
print(sort);
}
I am getting the following results:
comparison_sort.cpp:20:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
^
1 warning generated.
2
1
7
4
5
3
this was unsorted array
1
this was minimum
1
2
4
5
3
0
My question is: What is causing this control path error? Why is the "7" here being replaced with a "0"?
Thanks in advance! Sorry for the noob question.
I have reviewed all my current functions and nothing seems to explain why the 7 is replaced with a 0. I have tried multiple integers and it looks like the maximum number is always replaced.
The warning is very real, and it alludes to the problem that's breaking your sort as well.
You are currently returning m inside your loop body. What that means is that if the loop is entered, then the function will return m on the very first time around the loop. It only has a chance to check the first element.
And of course, if a is the last index of the array, then the loop will never execute, and you will never explicitly return a value. This is the "control path" which does not return a value.
It's quite clear that you've accidentally put return m; in the wrong place, and even though you have good code indentation, some inexplicable force is preventing you from seeing this. To fix both the warning and the sorting issue, move return m; outside the loop:
int findMin(vector<int> &arr, int a)
{
int m = a;
for (int i = a + 1; i < arr.size(); i++)
{
if (arr[i] < arr[m])
{
m = i;
}
}
return m;
}

My program keeps throwing compilation error,I am not able to figure out why the error has occured

Can't seem to figure out the error that the program keeps throwing.The program keeps throwing the error when I am dereferencing an iterator.Could anyone tell me where did I go wrong?
The problem for the code goes like this "Given five positive integers, find the minimum and maximum values that can be calculated by summing exactly four of the five integers. Then print the respective minimum and maximum values as a single line of two space-separated long integers."
void miniMaxSum(vector<int> arr) { //arr = {1,2,3,4,5}
int sum = 0;
unordered_map<int,int> results;
for(size_t i = 0;i < arr.size();i++)
{
results[arr[i]] = accumulate(arr.begin(),arr.end(),sum) - arr[i];
}
pair<unordered_map<int,int>::iterator,unordered_map<int,int>::iterator> mn;
mn = minmax_element(results.begin(),results.end());
cout<< *mn.first<<" "<<*mn.second; //line where the error is occuring
}
Solution.cpp: In function 'void miniMaxSum(std::vector)':
Solution.cpp:9:9: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream'} and 'std::pair')
cout<< *mn.first<<" "<<*mn.second;
~~~~^~~~~~~~~~~~
Edit: my answer fixes the compilation problem, but OP function does not do what they wanted it to do. John's answer solves the real algorithmic problem.
I reworked your snippet to make it immediately compilable:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <unordered_map>
using namespace std;
void miniMaxSum(vector<int> arr) { //arr = {1,2,3,4,5}
int sum = 0;
unordered_map<int,int> results;
for(size_t i = 0;i < arr.size();i++)
{
results[arr[i]] = accumulate(arr.begin(),arr.end(),sum) - arr[i];
}
pair<unordered_map<int,int>::iterator,unordered_map<int,int>::iterator> mn;
mn = minmax_element(results.begin(),results.end());
auto minIt = mn.first;
auto maxIt = mn.second;
cout<< "key min elem: " << minIt->first << " value min elem: " << minIt->second;
cout<< "key max elem: " << maxIt->first << " value max elem: " << maxIt->second;
}
The issue is the type of mn: pair<unordered_map<int,int>::iterator,unordered_map<int,int>::iterator>. mn is a pair. With mn.first you get an iterator to a key-value pair (the pair the error refer to). Once you have your pair you need to access directly the element you are interested in. I made the passage explicit in my example. You can look here (example at the bottom): https://en.cppreference.com/w/cpp/container/unordered_map for the structure of iterators on a unordered_map .
PS: you might want to avoid using namespace std I did it to keep the differences between your and my snippet to the minimum.
So here's the way to solve your problem
void miniMaxSum(vector<int> arr) { //arr = {1,2,3,4,5}
vector<int> results(arr.size());
for (size_t i = 0; i < arr.size();i++)
{
results[i] = accumulate(arr.begin(), arr.end(), 0) - arr[i];
}
auto mn = minmax_element(results.begin(), results.end());
cout << *(mn.first) << " " << *(mn.second);
}
The basic error was that you picked unordered_map<int,int> instead of vector<int> to store your intermediate results.
And notice that the correct syntax is *(mn.first) and *(mn.second) because you have a pair of iterators not an iterator pointing at a pair.
Working example

Code failure insert digits before data of the vector

I am supossed to do a code using function which after asking the user for input,puts number before the vector like this:
if vector is 11,12,13,14
new vector is 1 11 2 12 3 13 4 14 until the vector finishes and then I have to print it but I get an error of vector subscript out of range,aprecciate any help.
Here is my code
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<double> llena_vector(int x,vector<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x);
ingreso.push_back(x);
return ingreso;
}
vector<double> arma_vector(int contador,vector<double> intercalado)
{
int i=0;
for(contador=1;contador< intercalado.size()+1;contador++);{
intercalado.insert(intercalado.begin()+i,contador);i++;}
return intercalado;
}
vector<double> imprime_vector(int cuenta,vector<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++);
cout<<imprimir[cuenta]<<" ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
vector<double> usuario;
vector<double> guardar;
vector<double> resultado;
vector<double> print;
guardar= llena_vector(y,usuario);
resultado=arma_vector(q,guardar);
print=imprime_vector(w,resultado);
system("pause");
}
Here is a cleaner version of the code, in working condition.
#include <iostream>
#include <vector>
using namespace std;
void fill_vector(vector<double>& v)
{
cout << "Enter 5 numbers." << endl;
for (int i = 0; i < 5; ++i)
{
double d;
cin >> d;
v.push_back(d);
}
}
void insert_count(vector<double>& v)
{
size_t size = v.size();
for (size_t i = 0, j = 0; i < size; ++i, j += 2)
{
vector<double>::iterator pos = v.begin() + j;
v.insert(pos, i + 1);
}
}
void print_vector(vector<double>& v)
{
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
cout << endl;
}
int main()
{
vector<double> v;
fill_vector(v);
insert_count(v);
print_vector(v);
}
Like others (may have) pointed out:
you didn't need to pass by value (you're basically passing around a bunch of copies), you can pass by reference instead to reduce overhead and speed it up
you shouldn't put semicolons (;) directly behind your loop statements
size_t is often better than int when looping on size
you included <string> when it wasn't being used
you were passing arguments that weren't needed (e.g. a counter)
you used a while loop for user input, but it's only appropriate when piping in data otherwise it will loop forever; a for loop with a known count is more appropriate for user input
the function that inserted numbers between the existing elements had an error, you were incorrectly calculating the position to insert
your code formatting was a mess, making the code very difficult to read
you shouldn't pollute the namespace (i.e. using namespace std), but I left it as is since it's common in example code
if you're using C++11, I recommend using a for-each loop for printing the vector, and the auto keyword when declaring the iterator
i guess there is a typo: you should remove the last ; in for(cuenta=0;cuenta<imprimir.size();cuenta++);
Edit: as pointed by jrd1, you have this typo in all your for and while loops...
To begin with, your code has a number of issues. But, I've modified it to keep it as similar to your original.
#include <iostream>
#include <string>
#include <deque>
#include <cstdlib>
using namespace std;
deque<double> llena_deque(int x, deque<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x)
ingreso.push_back(x);
return ingreso;
}
deque<double> arma_deque(int contador, deque<double> intercalado)
{
int size = intercalado.size()+1;
for(int i=1; i < size; ++i) {
cout << i << endl;
intercalado.push_front(i);
}
return intercalado;
}
deque<double> imprime_deque(int cuenta, deque<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++)
cout << imprimir[cuenta] << " ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
deque<double> usuario;
deque<double> guardar;
deque<double> resultado;
deque<double> print;
guardar= llena_deque(y,usuario);
resultado=arma_deque(q,guardar);
print=imprime_deque(w,resultado);
return 0;
}
All your loops had ; at the end of them. That's one reason why you're getting your errors, as the semi-colon terminates a statement - hence, your loops were never truly accessing the vectors, which is why you were getting the memory access violations.
You're passing all your memory by value (which could potentially be slow). Consider using references.
Your operations suggest that you constantly need to keep pushing new data in front of your vector. If so, then use deque (as I did) as it is has functionality designed explicitly for that purpose (insert operations at both ends).
Although, I will say that the logic of your code is quite puzzling at times: i.e. in arma_vector, why pass the value of contador if you don't even use it? You could have used i instead...

Segmentation fault: 11; range-based for loop

I'm working on a small programming exercise in C++. Goal is to initiate an array with the first 32 exponentations of 2 and to output them afterwards.
Using a normal for loop there's no problem but I tried to use the range-based for loop introduced in the C++11 standard.
During compilation I get the warning "range-based for loop is a C++11 extension [-Wc++11-extensions]".
Running the program I get the error "Segmentation fault: 11" without any further output.
I got already that the elem variable somehow is broken but I don't know how.
Hope you can help a n00b :)
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
const int LAENGE = 32;
long potenzen[LAENGE];
for(int elem : potenzen)
{
potenzen[elem] = pow(2.0, (double) (elem + 1));
}
for(int elem : potenzen)
{
cout << endl;
cout << potenzen[elem];
}
cout << endl;
return 0;
}
elem is assigned the values in potenzen, not indices. cout << elem; is what you want instead to print the elements of the array. And in order to fill the array, simply use integer indices:
for (int i = 0; i < LENGTH; i++) { // ProTip #1: use English identifiers
array[i] = 2 << i; // ProTip #2: don't use `pow()` when working with integers
}
As to the compiler warning: use the -std=c++11 or -std=c++0x flag when compiling to tell the compiler you are intending to use C++11 features (assuming you use GCC or clang -- I'm not sure about other compilers.)
Ranged for loop wil give you element values, and not the element indices.
potenzen[elem] = pow(2.0, (double) (elem + 1));
should be
for(int i = 0; i < LAENGE; i++)
potenzen[i] = 2 << i;
(For shifting, refer to the H2CO3's answer and to the his comments below)
Note that you can't use foreach loop here:
for(int& elem : potenzen)
{
elem = pow(2.0, (double) (elem + 1));
}
as you're accessing not-initialized value of elem in the right side of the statement.
Also:
for(int elem : potenzen)
{
cout << endl;
cout << potenzen[elem];
}
Should be
for(int elem : potenzen)
{
cout << endl;
cout << elem;
}
as elem will contain array values.
The above answers rightly point out the issues in your code, however if you want to have array indices as element values you've to set them up, without which they'd be initialized to indeterminate (garbage) values; the following code is also a solution that's somewhat similar to what you tried to do:
#include <iostream>
#include <algorithm>
int main()
{
constexpr auto count = 32;
unsigned long long values[count] = { }; // initialise elements to 0
auto i = 0;
// fill them with their respective index values
std::generate_n(values, count, [&i] { return i++; });
for(auto &x : values)
{
// without casting the literal 2 would be treated as an int
x = static_cast<unsigned long long>(2) << x;
std::cout << x << std::endl;
}
return 0;
}
I've used unsigned long long instead of long, since on many systems the size of a long is 4 bytes, but 2^32 = 4294967296 = 0x100000000 I.e. 33 bits are required. Also since we know that all values are going to be positive, making it unsigned makes more sense.

issues with for loops in lambdas

I am currently rewriting a small project i written some time ago, and am replacing function pointers with std::function and lambdas.
While doing this i stumbled over an issue with for loops in lambdas.
in Visual Studio 2010 (with SP1) generates strange errors when for loops are used inside lambdas, IF the lambda is defined at file scope:
#include <iostream>
auto print_sum =
[]( int n )
{
int sum=0;
// line below generates:
// error C2143: syntax error : missing ')' before ';'
for( int i=1; i<=n; ++i )
sum += i;
std::cout << sum << "\n";
};
int main()
{
print_sum(3);
return 0;
}
following snippet however compiles fine:
#include <iostream>
int main()
{
auto print_sum =
[]( int n )
{
int sum=0;
for( int i=1; i<=n; ++i )
sum += i;
std::cout << sum << "\n";
};
print_sum(3);
return 0;
}
Both snippets compile fine using MinGW GCC 4.7.
Has anyone else observed this behaviour aswell?
Is this a bug in the lambda implementation of the Visual Studio?
Do you know any workarounds?
Edit:
bug report on microsoft connect:
https://connect.microsoft.com/VisualStudio/feedback/details/660742/error-with-for-loops-in-file-scope-lamdas-c-0x#details
I can verify this behavior on Visual Studio 2010 RTM. It appears to be limited to just for loops as the following compiles just fine.
auto print_sum =
[](int n)
{
int sum=0;
int i = 1;
while (i <= n)
{
sum += i;
i++;
}
std::cout << sum << "\n";
};
I would definitely alert microsoft to this issue by filing a bug on connect
http://connect.microsoft.com
Note: I don't 100% know if this is a bug but evidence suggests that it is