Set and comparator - c++

I am trying to understand the behavior of this following piece of code.
#include <iostream>
#include <string>
#include <set>
using namespace std;
struct cmp {
bool operator() (int a, int b) const {
cout<<"This is a-->"<<a<<" "<<endl;
cout<<"This is b-->"<<b<<" "<<endl;
return a < b;
}
};
int main() {
set<int, cmp> s;
s.insert(1);
s.insert(10);
//s.insert(11);
//s.insert(100);
for (int x : s)
cout << x << ' ';
return 0;
}
The output that I am getting for this is
This is a-->10
This is b-->1
This is a-->1
This is b-->10
This is a-->10
This is b-->1
1 10
I understand what this code does is that it sorts the elements of the set in ascending order but why is the comparator is being called 3 times? And why in the first case a is 10 but in the second case a is 1 and again in the third case it is 10?
And when I modify the code slightly to store the elements in the decreasing order, like below
#include <iostream>
#include <string>
#include <set>
using namespace std;
struct cmp {
bool operator() (int a, int b) const {
cout<<"This is a-->"<<a<<" "<<endl;
cout<<"This is b-->"<<b<<" "<<endl;
return a > b;
}
};
int main() {
set<int, cmp> s;
s.insert(1);
s.insert(10);
//s.insert(11);
//s.insert(100);
for (int x : s)
cout << x << ' ';
return 0;
}
Then why is the comparator function is being called only twice as seen in the output?
This is a-->10
This is b-->1
This is a-->10
This is b-->1
10 1
It will be of great help if anyone can shed some light on this.

Related

Accessing functions of a class not working

I've just started learning C++ and am complete newbie, sorry in advance if the question will sound stupid
I have my program to solve Two Sum problem:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> twoSum(const vector<int>& a, int target) {
unordered_map<int, int> valueToIndex;
for (int i = 0; i < (int)a.size(); i++) {
auto it = valueToIndex.find(target - a[i]);
if (it != valueToIndex.end()) {
return { it->second,i };
}
valueToIndex[a[i]] = i;
}
throw invalid_argument("sum not found");
}
};
int main()
{
vector<int> a{ 11,22,33,44,55 };
int target_value = 55;
Solution A;
A.twoSum(a,target_value);
return 0;
}
When I try to compile my program using test input values console returns nothing
What could be the issue?
Thanks!
Firstable, if you have a function that returns something, you need to get that return.
In your example, like that
vector<int> myResult = A.twoSum(a,target_value);
Then you can use that result like that.
for (const auto &value : myResult)
std::cout << value << std::endl;

C++ Vectors in a Class

i am working on a worksheet i have for university and the question asks me to "Allow a user to enter 10 numbers from the keyboard into an array" however we have been told that we need to use classes and vectors for this task. When i run my code i get an error stating: "Expression: Vector subscript out of range"
can anyone help?
Array.h
#include <iostream>
#include <vector>
using namespace std;
class Array
{
private:
vector<int> lists;
public:
void fillArray();
void printForwards();
void halfandHalf();
void shiftArrayRight();
Array();
Array(vector<int>);
};
Array.cpp
#include "Array.h"
Array::Array()
{
lists[10];
}
Array::Array(vector<int> lists)
{
this->lists = lists;
}
void Array::fillArray()
{
for (int i = 0; i < 10; i++)
{
cin >> lists[i];
}
}
void Array::printForwards()
{
for (int i = 0; i < 10; i++)
{
cout << lists[i];
}
}
Source.cpp
#include <iostream>
#include "Array.h"
using namespace std;
int main()
{
Array list1,list2;
//fill array 1
list1.fillArray();
//fill array 2
list2.fillArray();
// print array 1
list1.printForwards();
//print array 2
list2.printForwards();
system("pause");
return 0;
}
Thanks in advance
lists[10]; is not going to create a vector of size 10. It is going to try and access the 11th element of an empty vector. If you wanted to create a vector of size 10 then you can use
Array::Array() : lists(std::vector<int>(10, 0)) {}
I would also suggest you change
Array::Array(vector<int> lists)
{
this->lists = lists;
}
To
Array::Array(vector<int> lists) lists(lists) {}
You should also change your for loops to use the vector size() instead of a hard coded value
void Array::fillArray()
{
for (int i = 0; i < lists.size(); i++) // uses size()
{
cin >> lists[i];
}
}
void Array::printForwards()
{
for (int i = 0; i < lists.size(); i++) // uses size()
{
cout << lists[i];
}
}
Or if you have C++11 or higher you can use a ranged based for loop like
void Array::fillArray()
{
for (auto& e : lists)
{
cin >> e;
}
}
void Array::printForwards()
{
for (const auto& e : lists)
{
cout << e;
}
}

I get 20 errors in the algorithm file when trying to sort a struct vector. I don't know what is wrong?

This is my code
#include <stdio.h>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <set>
#include <struct.h>
#include <vector>
#include <functional>
using namespace std;
struct points {
int x,y;
};
bool operator<(const points &p1, const points &p2) {
return p1.x<p2.x;
};
vector<points> a(1000000);
int i,n,closest;
int main() {
scanf("%d\n",&n);
for (i=0; i<n-1; i++) {
scanf("%d %d\n",&a[i].x,&a[i].y);
}
sort(0,n-1,a);
return 0;
}
The errors that I get mostly state "Indirection requires pointer operand ('int' invalid). What could be wrong? I'm trying to sort the structs within the vector. I have used operator overload.
That's not how you use std::sort! Replace:
sort(0, n-1, a);
with:
sort(a.begin(), a.end());
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
struct points {
int x,y;
};
bool operator<(const points &p1, const points &p2) {
return p1.x<p2.x;
};
vector<points> a;
int i,n,closest;
int main() {
cin >> n;
for (i=0; i<n; i++) {
points p;
cin >> p.x >> p.y;
a.push_back(p);
}
sort(a.begin(), a.end());
for(i=0; i<n; i++)
cout << a[i].x << ',' << a[i].y << endl;
return 0;
}

comparing functions in c++, short way?

I've been recently working on a program which consists basically of 24 variations of one function(below). Everything gets executed perfectly apart from the part where I try to compare functions(with eachother). I found out that it is possible to be done by writing 24 if-else statements, yet I am certain there is a shorter way. I've also tried with vectors but no luck for now. Thanks for any help!
one of 24 functions:
int funk1()
{
ifstream myfile ("file.txt");
string line;
int i;
class1 obj1;
obj1.atr1= "Somename";
obj1.atr2="GAATTC";
while (getline(myfile, line))
{
i = countSubstring(line, obj1.atr2);
obj1.sum += i;
};
cout<<obj1.sum<<": "<<obj1.atr1<<"\n";
return obj1.sum;
}
The main function:
int main(){
funk1();
funk2();
funk3();
funk4();
funk5();
funk6();
funk7();
funk8();
funk9();
funk10();
funk11();
funk12();
funk13();
funk14();
funk15();
funk16();
funk17();
funk18();
funk19();
funk20();
funk21();
funk22();
funk23();
funk24();
//This is one way to do it
if (funk18() > funk1())
{
cout<<funk18<<" is the biggest";
}
//...
}
Here is a clean and elegant c++11 solution:
#include <iostream>
#include <functional>
#include <vector>
#include <limits>
#include <algorithm>
using namespace std;
using MyFunc = std::function<int()>;
int f1() { return 1; }
int f2() { return 15;}
int f3() { return 3; }
int main() {
std::vector<MyFunc> my_functions = {f1, f2, f3};
int max = std::numeric_limits<int>::min();
for (auto const &f : my_functions) {
max = std::max(max, f());
}
cout << max << endl;
return 0;
}
if you want to store the results from functions instead, you could do:
std::vector<int> my_results;
my_results.reserve(my_functions.size());
for (auto const &f : my_functions) {
my_results.push_back(f());
}
auto max_it = std::max_element(std::begin(my_results), std::end(my_results));
cout << *max_it << endl;

c++ vector causes array subscript error. Debugger shows error CXX0004

I am implementing a floyd-warshall algorithm in MS VS 2010. I am using the vector container. These seemingly innocent lines:
#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <string>
#include <limits>
using namespace std;
const double inf = numeric_limits<double>::infinity();
struct node{
int value;
//path not used here
//node *predecessor;
};
struct edge{
int source;
int target;
double weight;
};
vector<edge> EDGES;
cause a problem visible at the debugger when I stop at a breakpoint at the very start of main() body: Instead of having EDGES as the beautiful menu it should, I get a red exclamination mark at the name, and CXX0004: Error: Syntax error. Trying to run the program causes debug assertion: vector subscript out of range. The exact same lines work fine in a similar program I've made. What's wrong?
Here is the whole code:
#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <string>
#include <limits>
using namespace std;
const double inf = numeric_limits<double>::infinity();
struct node{
int value;
//path not used here
//node *predecessor;
};
struct edge{
int source;
int target;
double weight;
};
vector<edge> EDGES;
vector<node> V;
vector< vector< vector< double > > > R;
int u;//source
unsigned Ecount,Vcount;
void insert_from_keyboard(void)
{
unsigned i,j;
cout<<"Keyboard insertion selected. Enter vertex count: ";
cin>>Vcount;
V.resize(Vcount);
for(i=0;i<Vcount;i++)
V[i].value=i+1;//naming nodes, start from 1
R.resize(Vcount+1);
for(i=0;i<Vcount+1;i++)
{
R[i].resize(Vcount);
for(j=0;j<Vcount;j++)
R[i][j].resize(Vcount,inf);
}
cout<<"Nodes 1 to "<<Vcount<<" created.\nEnter edge count: ";
cin>>Ecount;
EDGES.resize(Ecount);
cout<<"Enter "<<Ecount<<" triplets representing directed edges (source, target, weight): ";
for(i=0;i<Ecount;i++)
cin>>EDGES[i].source>>EDGES[i].target>>EDGES[i].weight;
return;
}
bool floyd_warshall(void)
{
unsigned i,j,k;
for(i=0;i<Vcount;i++)
R[0][i][i] = 0;
for(i=0;i<Ecount;i++)
R[0][EDGES[i].source-1][EDGES[i].target-1] = EDGES[i].weight;
for(i=1;i<Vcount+1;i++)
for(j=0;j<Vcount;j++)
for(k=0;k<Vcount;k++)
R[i][j][k]= R[i-1][j][k] > R[i-1][j][i] + R[i-1][i][k] ? R[i-1][j][i] + R[i-1][i][k] : R[i-1][j][k];
for(i=0;i<Vcount;i++)
for(j=0;j<Vcount;j++)
if ( R[i][j][j]<0 )
return false;
return true;
}
void printR()
{
//printing routine, should not bother....
//the log function is used to calculate maximum length of numbers, used for formatting...
unsigned l,i,j, wl=5, wd=8;//width for printing whitespacEDGES l for L(...), d for data
for(l=0;l<Vcount+1;l++)
{
cout<<"R("<<setw(wl)<<l+1<<"):\n\n";
for(i=0;i<Vcount;i++)
{
cout<<setw(5+wl+wd/2)<<R[l][i][0];
for(j=1;j<Vcount;j++)
cout<<setw(wd)<<R[l][i][j];
cout<<endl;
}
cout<<"\n\n";
}
}
void insert_from_file(string filename)
{
unsigned i,j;
ifstream f (filename.c_str());
f>>Vcount>>Ecount;
V.resize(Vcount);
for(i=0;i<Vcount;i++)
V[i].value=i+1;//naming nodes, start from 1
R.resize(Vcount+1);
for(i=0;i<Vcount+1;i++)
{
R[i].resize(Vcount);
for(j=0;j<Vcount;j++)
R[i][j].resize(Vcount,inf);
}
EDGES.resize(Ecount);
for(i=0;i<Ecount;i++)
f>>EDGES[i].source>>EDGES[i].target>>EDGES[i].weight;
f.close();
cout<<"Insert from file "<<filename<<" successful\n\n";
}
int main(void)
{
//insert_from_keyboard();
insert_from_file("A22.txt");
bool result =floyd_warshall();
printR();
cout<<"Result of algorithm: "<<(result ? "TRUE, no negative" : "FALSE, negative" )<<" cycles encountered.\n";
system("PAUSE");
return 0;
}