Using the find() function with sets - c++

I have just encountered this chapter in my book and I dont really understand how find() works. I tried to create a simple function to check how the find() function works, but I am getting a multitude of errors in my code.
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> setA(1,2);
int item;
cout << "Enter a number: ";
cin >> item;
int setIter;
setIter = setA.find(item);
if (setIter != setA.end())
{
cout << "It's in the list." << endl;
}
return 0;
}

Here is the correct implementation of your program...
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> setA;
setA.insert(1); // use insert function
setA.insert(2);
set<int>::iterator setIter; // take set iterator
int item;
cout << "Enter a number: ";
cin >> item;
setIter = setA.find(item);
if (setIter != setA.end())
{
cout << "It's in the list." << endl;
}
return 0;
}
You are making two mistakes in your program. First you are initializing set using constructor which does not work so you have to use insert function of set. Secondly you are taking iterator as an int which is not correct. Iterator is basically a pointer of set type. So you have to take the iterator of set

Your code has two issues- first is the usage of constructor and the other is assigning set iterator returned by set.find() to an int. Here is the corrected code:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> setA({1,2});
int item;
cout << "Enter a number: ";
cin >> item;
set<int>::iterator setIter = setA.find(item);
if (setIter != setA.end())
{
cout << "It's in the list." << endl;
}
return 0;
}

Related

Having trouble with std::string::compare() return values in c++

Relatively new to c++.
Having trouble understanding an issue I am having with the compare() function returning 1 instead of 0.
I have a program which reads a text file containing an arbitrary number of questions and answers for a quiz. It is formatted as such:
Q: How many days in a week?
A: seven
I have three files, main.cpp, Quiz.cpp, and Quiz.h:
main.cpp:
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include "Quiz.h"
using namespace std;
int main(int argc, char* argv[]){
srand(unsigned(time(0)));
vector<Quiz> quizVector;
ifstream inputQuiz;
inputQuiz.open(argv[1]);
string q, a;
int questionCount = 0;
if(inputQuiz.is_open()){
getline(inputQuiz, q);
getline(inputQuiz, a);
while(!inputQuiz.eof()){
Quiz *instance = new Quiz(q, a);
quizVector.push_back(*instance);
questionCount++;
getline(inputQuiz, q);
getline(inputQuiz, a);
}
}
random_shuffle(quizVector.begin(), quizVector.end());
string userInput;
for(int i = 0; i < questionCount; i++){
cout << quizVector[i].getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
if(quizVector[i].getAnswer().compare("A: " + userInput) == 0){
cout << "Correct." << endl;
}
else{
cout << "Incorrect." << endl;
}
}
return 0;
}
Quiz.cpp:
#include <string>
#include "Quiz.h"
int Quiz::score = 0;
std::string Quiz::getQuestion(){
return question;
}
std::string Quiz::getAnswer(){
return answer;
}
Quiz.h:
#ifndef QUIZ_H
#define QUIZ_H
class Quiz{
private:
std::string question {""};
std::string answer {""};
public:
Quiz() = default;
Quiz(std::string q, std::string a) : question {q}, answer {a} {}
std::string getQuestion();
std::string getAnswer();
};
#endif
My problem lies within main.cpp:
for(int i = 0; i < questionCount; i++){
cout << quizVector[i].getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
if(quizVector[i].getAnswer().compare("A: " + userInput) == 0){
cout << "Correct." << endl;
}
else{
cout << "Incorrect." << endl;
}
}
When I input the correct answer corresponding to each question, compare() does not return 0, but consistently returns 1. There are no leading or trailing spaces at the start or ends of each line in the text file. Am I misunderstanding how getline() or compare() works? Is it something else? Any help is appreciated!
I see a number of problems with this code:
std::random_shuffle() is deprecated in C++14 and removed in C++17, use std::shuffle() instead.
you are not validating that argv contains an input parameter before using it.
Your use of eof() in the while loop is wrong. For instance, if the last question/answer pair in the file is terminated by EOF instead of a line break, getline() will still return the question/answer to you, but it will also set the eofbit flag on the stream, which will cause eof() to return true and thus you will skip saving the last pair into the vector. The stream is not technically in a failed state yet in this situation (see the diagram at https://en.cppreference.com/w/cpp/io/basic_ios/eof), so you shouldn't skip the last pair if it terminates with EOF rather than a line break.
Your while loop is leaking memory.
you don't need questionCount at all, use quizVector.size() instead. Or better, a range-for loop.
you don't really need to use compare() at all, you can use operator== instead. But, if you do use compare(), you should take into account that it is case-sensitive (as is operator==). You should also take advantage of the fact that compare() lets you specify an index to start comparing from, so you can ignore the A: prefix in the stored answer (alternatively, you could just strip off the Q: and A: prefixes when storing the question/answer in Quiz's constructor). Otherwise, you can use your compiler's strcmpi() function instead (if it offers one).
Try something more like this instead:
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <random>
#include <cctype>
#include "Quiz.h"
using namespace std;
string toLowercase(string s) {
transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return tolower(c); }
);
return s;
}
int main(int argc, char* argv[]){
if (argc < 2){
cerr << "Please specify a file to open!" << endl;
return 0;
}
ifstream inputQuiz(argv[1]);
if (!inputQuiz.is_open()) {
cerr << "Can't open the file!" << endl;
return 0;
}
vector<Quiz> quizVector;
string q, a, userInput;
while (getline(inputQuiz, q) && getline(inputQuiz, a)) {
quizVector.emplace_back(q, a);
}
random_device rd;
mt19937 g(rd());
shuffle(quizVector.begin(), quizVector.end(), g);
for(auto &quiz : quizVector){
cout << quiz.getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
userInput = toLowercase(userInput);
a = toLowercase(quiz.getAnswer());
if (a == ("a: " + userInput)) {
// or:
// if (a.compare(2, string::npos, userInput) == 0) {
// or, if you strip off "A:" beforehand:
// if (a == userInput) {
cout << "Correct." << endl;
}
else {
cout << "Incorrect." << endl;
}
}
return 0;
}

Sorting array of objects in c++

I'm a newbie and this is my first question. So I am working for a task organizer and I want to organize list of tasks by their "urgency" value. Here is my code:
#include <iostream>
#include <math.h>
#include <vector>
#include <stdlib.h>
#include <list>
using namespace std;
struct Task {
public:
string name;
float deadline, estimated;
int urgency;
int getUrgency() {
urgency = ceil(deadline - estimated);
return urgency;
}
};
void newTask(Task task[], int n1) {
for (int i = 0; i < n1; i++)
{
system("cls");
cout << "Input task name: ";
cin >> task[i].name;
cout << "Input task deadline (in hours): ";
cin >> task[i].deadline;
cout << "Input task estimated work time (in hours): ";
cin >> task[i].estimated;
}
}
void printAll(Task task[], int n1) {
system("cls");
cout << "Name\tDeadline\tEstimated\tUrgency\n";
for (int i = 0; i < n1; i++)
{
cout << task[i].name << "\t" << task[i].deadline << "\t\t" << task[i].estimated << "\t\t" << task[i].getUrgency() << endl;
}
}
int main() {
int n;
cout << "How many work do you have? ";
cin >> n;
//Create number of object based on input n
std::vector<Task> p(n);
newTask(p.data(), n);
std::list<Task> taskList;
printAll(p.data(), n);
cin.ignore();
return 0;
}
I want to add a function that sorts the list of tasks by their "urgency" value. What kind of function should I use?
In your case you can use the std::sort function, defined in <algorithm> header, on the p vector defining a custom compare function:
std::sort (p.begin(), p.end(), sortTaskByUrgency);
where sortTaskByUrgency() is defined as:
bool sortTaskByUrgency(const Task& lhs, const Task& rhs)
{
return lhs.getUrgency() < rhs.getUrgency();
}
Using the above function in your sample code getUrgency() must be const:
int getUrgency() const { return ceil(deadline - estimated); }
removing useless int urgency public member.
I would try using std::sort. It will sort in place any iterable object (array, vector, etc...). A common std::sort function call has the following arguments: The first argument is an iterator/pointer to the beginning of the collection, the second argument is an iterator/pointer to the end of that same collection, and the third argument is a function callback that determines how the data is sorted. You can see an example implementation here

Vector of strings works correctly before sorting, but afterwards it can't do anything

I was working on a problem which required me to sort vector of strings at certain point. It caused me a lot of problems so I decided to extract the problematic part and I can't figure out what seems to be the problem.
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
bool myComp(string a, string b){
return a<b;
}
int main(){
vector<string> students(50000);
int i = 0;
while(true){
string input;
getline(cin, students[i]);
if(!students[i].empty()){
i++;
}
else{
break;
}
}
cout << students[2] << endl << students[1] << endl;
sort(students.begin(), students.end());
cout << students[2] << endl << students[1];
return 0;
}
At first I thought that input was wrong (problem specifically requests to read until empty line), but it turned out that program works correctly up to moment of sorting. I would be very grateful if anyone was to clear this out for me I am banging my head for more than an hour.
The obvious issue with your code is that you have a vector of 50000 strings. You then try an sort that vector of 50000 strings. It seems obvious that you really want the size of the vector to equal the number of strings input. The easy way to do that is to grow the vector as you input strings. Use the push_back method for that.
Here's some code
vector<string> students; // initial size of vector is zero
int i = 0;
while(true){
string input;
getline(cin, input); // read into the input variable
if (input.empty()) // break if input is empty
break;
students.push_back(input); // add the input to the vector
}
Now with the vector sized correctly you should find sorting it to be no problem
cout << students[2] << endl << students[1] << endl;
sort(students.begin(), students.end());
cout << students[2] << endl << students[1];
The problem is using incorrect arguments in the call of std::sort.
sort(students.begin(), students.end());
The vector students contains 50000 elements
vector<string> students(50000);
It seems you mean
#include <iterator>
//...
sort(students.begin(), std::next( students.begin(), i ));
or
sort(students.begin(), std::next( students.begin(), i ), myComp );
where myComp should be defined at least like
bool myComp( const string &a, const string &b){
return a<b;
}
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> students;
students.reserve(50000); // want to avoid `students` reallocation for first
// 50'000 entries but size is still zero (`0`)
std::string line;
// read until end-of-input or empty line
while(std::getline(std::cin, line) && !line.empty())
students.push_back(line); // no reallocation for first 50'000 entries!
if(students.size() < 3)
{
std::cerr << "Need at least three students for example\n";
return EXIT_FAILURE;
}
std::cout << students[2] << '\n' << students[1] << '\n';
std::partial_sort( // Only pick out three "smallest" strings for example
students.begin(), // no need to sort more than necessary with 50'000 :-)
std::next(students.begin(), 3),
students.end());
std::cout << students[2] << '\n' << students[1] << std::endl;
return EXIT_SUCCESS;
}
You have written a comparator function myComp() but you haven't used it. I'd suggest using it as the third parameter for sort() and see if things get better. i.e.;
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
bool myComp(string a, string b){
return a<b;
}
int main(){
vector<string> students(50000);
int i = 0;
while(true){
string input;
getline(cin, students[i]);
if(!students[i].empty()){
i++;
}
else{
break;
}
}
cout << students[2] << endl << students[1] << endl;
sort(students.begin(), students.end(), myComp);
cout << students[2] << endl << students[1];
return 0;
}

How Do I Print a Vector of Tuples?

So I'm trying to make a vector that contains tuples containing two ints, and I'm acquiring the ints from a text file source. To make sure I have the vector I want, I'm trying the print out my contents, but the output is not showing me anything. I'm not sure if it's because of my code, and where I put my text file. I'm just stuck at this point. If anything could help me with this, I'd appreciate it very much. Thanks
using namespace std;
int main()
{
ifstream file("source.txt");
typedef vector<tuple<int, int>> streets;
streets t;
int a, b;
if (file.is_open())
{
while (((file >> a).ignore() >> b).ignore())
{
t.push_back(tuple<int, int>(a, b));
for (streets::const_iterator i = t.begin();i != t.end();++i)
{
cout << get<0>(*i) << endl;
cout << get<1>(*i) << endl;
}
cout << get<0>(t[0]) << endl;
cout << get<1>(t[1]) << endl;
}
}
file.close();
system("pause");
return 0;
Here's my text file and where I placed it
enter image description here
Here's my output from debugging, if that's important
You should use a loop, that will print one tuple at a time.
Complete minimal example:
#include <iostream>
#include <tuple>
#include <vector>
#include <fstream>
using namespace std;
int main(void) {
std::ifstream infile("source.txt");
vector<tuple<int, int>> streets;
int a, b;
while (infile >> a >> b)
{
streets.push_back(tuple<int, int>(a, b));
}
infile.close();
for(auto& tuple: streets) {
cout << get<0>(tuple) << " " << get<1>(tuple) << endl;
}
return 0;
}
Output:
1 2
3 4
5 6
7 8

List Iterator Not incrementable - Runtime Error

I am getting a List Iterator Not incrementable on the code below after adding a stringstream for movieName and am unsure as how to go about solving the error. I am trying to read in from a file and add the items into a list then itterate through the list and add eash word from the title of the movie into another list. Any help would be appreciated!
#include <iostream>
#include <string>
#include <list>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
list <string> movieList;
list <string>::iterator iterMovie;
list <string> *titleWordList = new list <string>;
list <string>::iterator iterTitleWord;
ifstream inFile;
inFile.open("JamesBond.txt");
if (!inFile)
{
cout << "Could not find the specified file.";
}
else
{
movieList.clear();
string movieName;
while(getline(inFile,movieName))
{
movieList.push_back((movieName));
/*
for each(string movieName in movieList)
{
titleWordList->push_back(movieName);
}
*/
stringstream ss(movieName);
while (ss >> movieName)
{
titleWordList->push_back(movieName);
}
}
}
if (movieList.empty())
{
cout << "No Data Found!" << endl;
}
else
{
cout << "Writing Output: \n\n";
for (iterMovie=movieList.begin(); iterMovie !=movieList.end(); ++iterMovie)
{
cout << *iterMovie << endl;
}
for (iterTitleWord=movieList.begin(); iterTitleWord != movieList.end(); ++iterMovie)
{
cout << *iterTitleWord << endl;
cout << &titleWordList;
}
}
}
In the second for there is a copy paste error, it should be ++iterTitleWord instead of ++iterMovie.
Also, as #Greg suggested, iterTitleWord=movieList.begin() and iterTitleWord != movieList.end() should be iterTitleWord=titleWordList->begin() and iterTitleWord != titleWordList->end() respectively.