I'm implementing the MERGE SORT algorithm. I use std::list < int > as my list of input numbers. This is my code:
#include <iostream>
using namespace std;
#include <list>
void MergeSort(list<int> _list)
{
if (_list.size() > 1)
{
list<int> left;
list<int> right;
int mid = (0+_list.size())/2;
list<int>::iterator i = _list.begin();
for (int j = 0; j<mid; j++) ++i;
left.assign(_list.begin(),++i);
right.assign(i, _list.end());
MergeSort(left);
MergeSort(right);
_list.merge(left,right);
}
return;
}
int main()
{
list<int> myList;
myList.push_front(38);
myList.push_back(27);
myList.push_back(43);
myList.push_back(3);
myList.push_back(9);
myList.push_back(82);
myList.push_back(10);
cout << "Before sorting:\n";
list<int>::iterator i;
for(i=myList.begin(); i != myList.end(); ++i) cout << *i << " ";
// Merge Sort Function
MergeSort(myList);
//
cout << "\nAfter sorting:\n";
for(i=myList.begin(); i != myList.end(); ++i)
{
cout << *i << " ";
}
system("pause");
return 0;
}
But I builded this source file on Visual Studio 2012 and got this error: error C2064: term does not evaluate to a function taking 2 arguments (file)c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility (line)595
This is the first time i've dealed with this error and I have no idea how to fix it... Hope you guys can help me with this, thanks so much in advanced !
You are not using list<int>::merge correctly in the expression _list.merge(left, right);
check the documentation for merge function. There you can also find an example on how to use it.
Related
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;
}
I am trying to solve this simple problem in C++ (complier: Visual Studio). The result should be the smallest and largest sum you can make with the elements of a given vector, but always excluding one element when getting the sum. My solution was to make all the sums, put them in a vector, sort them and then show the first and last element.
The problem I have is that the program is not executing. I get errors like arr / vector / miniMaxSum undeclared identifier... I have all the right headers included, so I don't understand why it doesn't work...
UPDATE: My program is modified and it works now. Thank you all for your input :)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//new and working function:
void miniMaxSum(vector<int> arr) {
double minSum=0, maxSum=0;
sort(arr.begin(), arr.end());
for (int j = 0; j<arr.size()-1; j++) {
minSum = minSum + arr[j];
maxSum= maxSum + arr[j+1];
}
cout << minSum << " " << maxSum;
}
//old and not working implementation
void miniMaxSum(vector<int> arr) { //Third error here:Error C2065 'vector': undeclared identifier
vector<int> sums;
int i = 0;
while (i <= arr.size()) {
for (int j = 0; j<arr.size(); j++) {
if (i == j) { sums[i] = sums[i] + arr[j + 1]; }
else { sums[i] = sums[i] + arr[j]; }
}
i++;
}
sort(sums.begin(), sums.end());
cout << sums[0] << " " << sums[sums.size() - 1];
}
int main() {
vector<int> arr { 1,2,3,4,5 };
miniMaxSum(arr);//First error here: Error C2065 'arr': undeclared identifier / Second error also here: Error C3861 'miniMaxSum': identifier not found
}
I checked your program with Visual Studio. It compiles.
Please try to select the commands "Clean Solution" from the build menu and then "Rebuild Solution"
Maybe that will help you.
Additionally:
But when you run your program, exceptions will be thrown. This, because in Visual Studios default debug modus, out-of-bounds checks will be performed. And, in case of problems, an exception will be thrown.
And you have several out of bounds errors here. The root cause is, that you need to understand, that arrays start with index 0. And if you have an array with 5 elements, so a size of 5, then the valid 5 indices are: 0,1,2,3,4.
If you write i <= arr.size() then the last value for i will be 5. And that is out of bounds. And, you access arr[j + 1]. This will also be out of bounds.
So, your program cannot run.
Please see here your programm with comments, where I see a problem:
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std; // Should never be used. Always use fully qualified names
void miniMaxSum(vector<int> arr) { // Vector should be passed by reference to the function
vector<int> sums; // Problem. Vector is Empty. It has no element
int i = 0;
while (i <= arr.size()) { // <= is false. Arrays in C++ start with index 0. So, this will go out of bounds
for (int j = 0; j < arr.size(); j++) {
if (i == j) {
sums[i] = sums[i] + arr[j + 1]; // Will go out of bounds for i and j
}
else {
sums[i] = sums[i] + arr[j]; // Will go out of bounds for i and j
}
}
i++;
}
sort(sums.begin(), sums.end());
cout << sums[0] << " " << sums[sums.size() - 1];
}
int main() {
vector<int> arr{ 1,2,3,4,5 };
miniMaxSum(arr);
// Return missing
}
For the problem solving approach. I do not fully understand your question.
The result should be the smallest and largest sum you can make with the elements of a given vector, but always excluding one element when getting the sum
This does not seem to fit to your implementation. Example. If you would sort the std::vector in the very beginning, then the sum of the smallest element, except one, would be extremely simple. JUst sum up the first n-1 elements. For the maximum value it would be the corresponding approach.
If you clarify the requirements, I will edit my anser and add a correct solution.
Based on my original understanding, the solution could be:
#include <iostream>
#include <vector>
#include <limits>
#include <algorithm>
void showMinMaxSum(std::vector<int>& data) {
// Initialize temporary variables
int sum{}, minValue{ std::numeric_limits<int>::max() }, maxValue{ std::numeric_limits<int>::min() };;
// Calculate sum of vector elements and get may and min value
for (int temp : data) {
sum += temp;
maxValue = std::max(maxValue, temp);
minValue = std::min(minValue, temp);
}
std::cout << "Min Sum: " << sum - maxValue << " \tMax Sum: " << sum - minValue << '\n';
}
int main() {
// Test data
std::vector<int> data{ 1,2,3,4,5 };
// Calculate and show results
showMinMaxSum(data);
return 0;
}
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
I am new to c++. I am getting an error when I try to output the result of a string vector. I was hoping someone can why? the code for GenerateCombinations function is from https://www.programmingalgorithms.com/algorithm/unique-combinations. I wrote the main() function. I am using VS community 2015.
#include "stdafx.h"
#include <iostream>
#include <Vector>
#include <string>
using namespace std;
//*****Please include following header files***** /
// string
// vector
/***********************************************/
/*****Please use following namespaces*****/
// std
/*****************************************/
static vector<vector<string>> GenerateCombinations(vector<string> arr)
{
vector<vector<string>> combinations;
int length = arr.size();
for (int i = 0; i < (1 << length); ++i)
{
vector<string> combination;
int count = 0;
for (count = 0; count < length; ++count)
{
if ((i & 1 << count) > 0)
combination.push_back(arr[count]);
}
if (count > 0 && combination.size() > 0) {
combinations.push_back(combination);
}
}
return combinations;
}
int main() {
vector<string> arr = { "How", "Are", "You" };
vector<vector<string>> combinations = GenerateCombinations(arr);
vector <string> ::iterator itr;
for (itr = combinations.begin(); itr < combinations.end(); itr++)
{
cout << *itr << endl;
}
As #Sam has pointed out in the comments, you are attempting to assign a std::vector<std::vector<std::string>>::iterator from combinations.begin() to std::vector<std::string>::iterator, hence the mismatch.
The easiest way to solve your problem is to worry less about actual types, and use auto:
for (auto itr = combinations.begin(); itr < combinations.end(); ++itr)
Or more simply:
for (auto combination : combinations)
Here combination is a std::vector<std::string>, so you can't just print that, you need to iterate through that as well:
for (auto combination : combinations)
{
for (auto c : combination)
{
std::cout << c << ' ';
}
std::cout << "\n";
}
I recently started to learn C++ programing, and watched many of your posts and answers with interest when my mind would lack the creativity. I have a few issues with this code right here. Basically it should show "n" words in alphabetical order. "n" being introduce by the user and the words as well. I get a weird error, could someone give me a few hints on what should i do?
#include <iostream>
#include <vector>
#include <string>
int main () {
int n=0;
std::string cuvant;
std::vector<std::string> lista_cuvinte;
std::cout<<" Cate cuvinte doriti sa comparati = "<< std::endl;
std::cin>> n;
for (int i=0; i<n; i++)
{
std::cout<<"cubantul al " << i + 1 <<" -lea = ";
std::cin>> cuvant;
lista_cuvinte.push_back(cuvant);
for (int i=0; i < n; i++)
{
for (int j=i + 1; j < n; j++)
{
if (lista_cuvinte.at(i) > lista_cuvinte.at(j))
{
std::string temp=lista_cuvinte.at(i);
lista_cuvinte[i]=lista_cuvinte.at(j);
lista_cuvinte[j]=temp;
i=i-1;
break;
std::cout<< temp << std::endl;
}
}
}
}
return 0;
}
You are doing a lot things wrong. Simply sorting starts before all data was read in in your code. Code after a break will never executed. And there is no output.
But you can achieve the same result much simpler by using sort from algorithm. I believe your code is only for learning, so it maybe makes sense to do it by hand. Normally it does not :-)
#include <iostream>
#include <vector>
#include <string>
int main () {
int n=0;
std::string cuvant;
std::vector<std::string> lista_cuvinte;
std::cout<<" Cate cuvinte doriti sa comparati = "<< std::endl;
std::cin>> n;
// read data
for (int i=0; i<n; i++)
{
std::cout<<"cubantul al " << i + 1 <<" -lea = ";
std::cin>> cuvant;
lista_cuvinte.push_back(cuvant);
}
// sort data
for (int i=0; i < n; i++)
{
for (int j=i + 1; j < n; j++)
{
if (lista_cuvinte.at(i) > lista_cuvinte.at(j))
{
std::string temp=lista_cuvinte.at(i);
lista_cuvinte[i]=lista_cuvinte.at(j);
lista_cuvinte[j]=temp;
i=i-1;
break;
}
}
}
// output data
for (int i=0; i<n; i++)
{
std::cout << lista_cuvinte[i] << std::endl;
}
return 0;
}
And with std::sort your code in the section sorting reduces to:
// sort data
std::sort( lista_cuvinte.begin(), lista_cuvinte.end());
Thats all!
As a hint to you for writing and finding errors in general: Please use a debugger. Your code simply throws an exception. Your debugger will catch it for you and you go in the backtrace to the point where the error occurs. In your code it was an access out of range from the array, because the data was not read in at this point of execution.
You are starting sorting before completing the input of the words. Your second for (int i=0... loop is inside your first one.