no matching function for vector<string>::push_back(stringstream&) - c++

So I was writing an algorithm for a TopCoder problem and I got the following errors. I have tried my best to eliminate syntax errors but I can't seem to figure out what is warranting these errors. Can you help me out with it? I am not very experienced and I'm trying to learn.
tc1.cpp: In member function ‘std::vector<std::basic_string<char> > BinaryCode::decode(std::string)’:
tc1.cpp:46:20: error: no matching function for call to ‘std::vector<std::basic_string<char> >::push_back(std::stringstream&)’
tc1.cpp:46:20: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::value_type = std::basic_string<char>]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from ‘std::stringstream {aka std::basic_stringstream<char>}’ to ‘const value_type& {aka const std::basic_string<char>&}’
make: *** [tc1] Error 1
The code I've written is -
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
class BinaryCode
{
public:
vector<string> decode(string message)
{
int cntrl = 0;
vector<string> P;
bool poss = true;
int a = message.length();
int A[a+2], B[a+2];
for (int i=1; i<=a ; i++)
{
stringstream ss(message.substr(i,1));
ss >> B[i];
}
while (cntrl <2)
{
A[0] = A[a+1] = cntrl;
for (int i=0; i<=a; i++)
{
A[1] = B[2] - cntrl;
A[i+1] = B[i] - A[i] - A[i-1];
if (A[i+1]<0 || A[i+1])
{
poss = false;
}
}
if (!poss)
P.push_back("NONE");
else
{
stringstream s;
for (int i =0; i<a+2; i++)
s << (char)A[i];
P.push_back(s);
}
cntrl++;
}
return P;
}
};
int main()
{
BinaryCode ob;
string str;
cout << "Enter the encrypted string: " << endl;
cin >> str;
vector<string> vec = ob.BinaryCode::decode(str);
vector<string>::iterator it = vec.begin();
for (; it!= vec.end(); it++) {
cout << *it;
}
}
I'd be grateful if someone could point out what I'm doing wrong with this.

You are pushing a stringstream into a vector of strings. Change
P.push_back(s);
to
P.push_back(s.str());

Related

Permutations of a string --error: no matching function for call to ‘std::set<char>::insert(std::string&)’

I am not a professional c++ programmer. I have tried to write a program to display all possible permutations of a given input string assuming if the string contains duplicate characters. This the code I have written so far:
Latest update of my code (permutation.cpp):
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <list>
#include <set>
#include <iterator>
#include <sstream>
#include <cstdlib>
using namespace std;
//factorial function
int factorial(int n){
if (n==0) return 1;
else{
return n*factorial(n-1);
}
}
int main (int argc, char *argv[]) {
srand ( time(NULL) ); //initialize the random seed
char* text;
std::set<char> mySwapList;
if ( argc < 1 )
{
cout << endl << "Please write a word in the following of the command line" << endl << endl;
return 1;
}
else if ( argc != 2 ) // argc should be 2 for correct execution
{ // We print argv[0] assuming it is the program name
strcpy (text,argv[1]);
cout<<endl<<"usage: "<< argv[0] <<" to compute all the permutations \n"<<endl;
return 1;
}
int ss=sizeof(text);
int length = ss;
int k=0;
cout << "length of the word:"<<endl<< length<<endl;
int total=factorial(length);
while (k< total)
{
char arr[ss];
int index=0;
stringstream ssin(text);
while (ssin.good() && index<ss){
ssin>>arr[index];
++index;
}
std::list<char> word(arr, arr+ss);
std::list<char> mylist;
unsigned int j=0;
while (j < length)
{
int n=word.size();
int RandIndex = rand() % n;
std::list<char>::iterator vi= word.begin();
std::advance(vi,RandIndex);
std::list<char>::iterator iter= mylist.begin();
mylist.insert(iter,*vi);
word.remove(*vi);
j++;
}
char str[ss];
int ii=0;
for (std::list<char>::iterator ix=mylist.begin(); ix!=mylist.end(); ++ix)
{
str[ii]=*ix;
ii++;
}
string newWord = string(str);
for (std::set<char>::iterator iss=mySwapList.begin(); iss!=mySwapList.end(); ++iss)
{
string w(1,*iss);
if (newWord != w)
{
mySwapList.insert(newWord);
k++;
}
}
}
//Loop for printing the list
for(std::set<char>::iterator it = mySwapList.begin(); it != mySwapList.end(); ++it)
cout << *it << " ";
cout << endl;
return 0;
}
I get a a good deal of error messages when I compile the code, including:
Updated errors:
permutation.cpp: In function ‘int main(int, char**)’:
permutation.cpp:82:39: error: no matching function for call to ‘std::set<char>::insert(std::string&)’
mySwapList.insert(newWord);
^
permutation.cpp:82:39: note: candidates are:
In file included from /usr/include/c++/4.8/set:61:0,
from permutation.cpp:9:
/usr/include/c++/4.8/bits/stl_set.h:460:7: note: std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = char; _Compare = std::less<char>; _Alloc = std::allocator<char>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<char>; std::set<_Key, _Compare, _Alloc>::value_type = char]
insert(const value_type& __x)
^
/usr/include/c++/4.8/bits/stl_set.h:460:7: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘const value_type& {aka const char&}’
/usr/include/c++/4.8/bits/stl_set.h:497:7: note: std::set<_Key, _Compare, _Alloc>::iterator std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = char; _Compare = std::less<char>; _Alloc = std::allocator<char>; std::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<char>; std::set<_Key, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<char>; std::set<_Key, _Compare, _Alloc>::value_type = char]
insert(const_iterator __position, const value_type& __x)
^
/usr/include/c++/4.8/bits/stl_set.h:497:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/4.8/bits/stl_set.h:517:2: note: template<class _InputIterator> void std::set<_Key, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = char; _Compare = std::less<char>; _Alloc = std::allocator<char>]
insert(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.8/bits/stl_set.h:517:2: note: template argument deduction/substitution failed:
permutation.cpp:82:39: note: candidate expects 2 arguments, 1 provided
mySwapList.insert(newWord);
I can not figure out why I got the above errors. Any suggestion?
Based on the question title you want to convert string to list.
You can't do it directly but you can use string iterator:
#include <string>
#include <list>
int main(int argc, _TCHAR* argv[])
{
std::string strTest = "hello!";
std::list<char> list(strTest.begin(), strTest.end());
return 0;
}
Edit: But based on your code you don't need list at all. You can use std::string everywhere. It has insert and [] stuff. It is almost the same as vector<char> but with additional functionality.
You used undefined class members.
Try strcpy_s() to char* arrays.
Using vector as a container for strings at the end of the code for mySwapList solves the problem of accepting strings as well as being easy to access each component of the vector. Here is the debugged and working version of the original question:
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <list>
#include <set>
#include <iterator>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
using std::vector;
//factorial function
int factorial(int n){
if (n==0) return 1;
else{
return n*factorial(n-1);
}
}
int main () {
srand ( time(NULL) ); //initialize the random seed
std::string text;
vector<std::string> mySwapList;
std::ostream_iterator<char> output(cout," ");
cout << endl << "Please write a word in the following of the command line" << endl << endl;
cin >>text;
int ss=text.size();
int k=0;
cout << "length of the word:" << endl << ss<<endl<<"input value:\n" <<text<< endl;
int total=factorial(ss);
cout << "The number of final permutations :\n"<<total<<endl;
while (k< total)
{
char arr[ss];
int index=0;
stringstream ssin(text);
while (ssin.good() && index<ss){
ssin>>arr[index];
++index;
}
std::list<char> word;
//insert items from arr into word list
word.insert(word.begin(),arr, arr+ss);
//A tool to print lists
cout<<"word contains:\n "<<endl;
std::copy(word.begin(),word.end(),output);
cout << endl;
std::list<char> mylist;
unsigned int j=0;
while (j < ss)
{
int n=word.size();
int RandIndex = rand() % n;
std::list<char>::iterator vi= word.begin();
std::advance(vi,RandIndex);
word.erase(vi);
std::list<char>::iterator iter= mylist.begin();
mylist.insert(iter,*vi);
j++;
}
cout << "constructed permuted word:"<<endl;
std::copy(mylist.begin(),mylist.end(),output);
cout << endl;
char str[ss];
str[ss]='\0';
int ii=0;
for (std::list<char>::iterator ix=mylist.begin(); ix!=mylist.end(); ++ix)
{
str[ii]=*ix;
ii++;
}
string newWord = string(str);
cout << "New Word :"<< endl << newWord <<" size of string:\n"<< (sizeof(str)/sizeof(*str)) << endl;
if (k==0)
{
mySwapList.push_back(newWord);
k++;
}
else
{
int flag=0;
for (int i=0;i<mySwapList.size();i++)
{
if (mySwapList[i]==newWord)
flag=1;
}
if (flag!=1)
{
mySwapList.push_back(newWord);
k++;
}
}
}
//Loop for printing the vector mySwapList
for(unsigned int i=0; i<mySwapList.size();i++)
cout << mySwapList[i] << " ";
cout << endl;
return 0;
}

std::sort error using custom classes

I have looked through stackoverflow and added an overload operator to hopefully make it work with sort. Though I still get an explosion of an error saying something is wrong with sort.
Code:
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <algorithm>
class Student
{
private:
std::string name_;
int number_;
std::vector<int> grades_;
const int num_courses_;
static std::string gen_name() {
return std::to_string(rand());
}
static int gen_number() {
return rand() % (201600000 - 201100000 + 1) + 201100000;
}
static int gen_grade() {
return rand() % (100 - 70 + 1) + 70;
}
double compute_average() {
int marks = 0;
int count = 0;
for (std::vector<int>::iterator i = grades_.begin(); i != grades_.end(); i++, count++){
marks += *i;
}
return static_cast<double>(marks) / count;
}
public:
Student() : name_(gen_name()), number_(gen_number()), num_courses_(5)
{
for (int i = 0; i < num_courses_; ++i) {
grades_.push_back(gen_grade());
}
}
double getAvg() {
return compute_average();
}
friend std::ostream& operator<<(std::ostream& os, Student& s) {
os << "Name = " << s.name_ << "\tNumber = " << s.number_ << "\tAvg = " << s.compute_average();
return os;
}
std::string getName() {
return name_;
}
void print_grades(std::ostream& os) const
{
for (int i = 0; i < num_courses_; ++i) {
os << grades_[i] << ", ";
}
}
bool operator < (const Student& str) const
{
return (name_ < str.name_);
}
};
int main(int argc, char ** argv) {
srand(time(NULL));
if (argc == 2){
int numbOfStudents = atoi(argv[1]);
std::vector<Student> studentVec;
for (int i = 0; i < numbOfStudents; i++){
studentVec.push_back(Student());
}
std::sort(studentVec.begin(), studentVec.end());
for (std::vector<Student>::iterator xi = studentVec.begin(); xi != studentVec.end(); xi++) {
std::cout << *xi << std::endl;
}
}
else{
std::cout << "Usage: " << argv[0] << " {numb} " << std::endl;
}
return 0
}
The error comes when I run sort (I know it's sort since if I comment it out, it works properly). With the error code
In file included from /usr/include/c++/4.9/algorithm:62:0,
from main.cpp:5:
/usr/include/c++/4.9/bits/stl_algo.h: In instantiation of ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’:
/usr/include/c++/4.9/bits/stl_algo.h:1884:70: required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/4.9/bits/stl_algo.h:1970:55: required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/4.9/bits/stl_algo.h:4685:72: required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >]’
main.cpp:79:50: required from here
/usr/include/c++/4.9/bits/stl_algo.h:1851:17: error: use of deleted function ‘Student& Student::operator=(Student&&)’
*__first = _GLIBCXX_MOVE(__val);
I searched earlier which helped me get to the result of adding a '<' overload, though I still get an error. Can anyone help point out where the mistake is? Thank you. (I compile using g++ --std=c++11)
the member variable const int num_courses_; is const, which means it must be set in the initializer list of the constructor.
num_courses_ can't be set by the copy assignment operator Student& Student::operator=(Student&&), so it prevent the compiler from generating the copy assignment operator for that class. Since there's no copy assignment operator available, and the std::sort function needs it to work, the compilation fails and complains about the copy assignment operator not being available.
Simply remove the const and declare the variable as int num_courses_ and your code should work.

C++: Inserting pairs of class objects into a map

I am trying to insert into a map that contains a class name_t object as the key and a class scores_t object as the value. The name_t object should be a string, while the scores_t object is a vector of ints. I am getting errors when trying to do:
map.insert(std::pair<string, vector<int> >(n.get(), s.get()));
The program code is:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <map>
#include <functional>
#include <algorithm>
#include <numeric>
#include <iomanip>
using namespace std;
class name_t{
public:
void print_name(int);
bool operator<(const name_t &rhs) const;
void set(string first, string last);
string get() const { return name; }
//Add get/set functions for firstname and lastname
private:
string name;
string firstname;
string lastname;
};
void name_t::print_name(int n){
cout << left << setw(21) << setfill('.') << name << " ";
}
bool name_t::operator<(const name_t &rhs) const{
if(get()!=rhs.get()) return get() < rhs.get();
return false;
}
void name_t::set(string first, string last){
firstname = first;
lastname = last;
name = lastname + ", " + firstname;
}
class scores_t{
public:
void push_back(int);
void compute_stats();
void print_scores();
vector<int> get(){ return scores; }
//Add accessor functions for min, max, avg, n80
private:
vector<int> scores;
int min;
int max;
int avg, n80;
};
void scores_t::push_back(int num){
scores.push_back(num);
}
void scores_t::compute_stats(){
vector<int>::iterator it;
it = min_element(scores.begin(), scores.end());
min = *it;
it = max_element(scores.begin(), scores.end());
max = *it;
int init = 0;
avg = accumulate(scores.begin(), scores.end(), init)/scores.size();
n80 = count_if(scores.begin(), scores.end(), bind2nd(greater<int>(),80));
}
void scores_t::print_scores(){
cout << min << " " << max << " " << avg << " " << n80;
scores.clear();
}
int main(int argc, char* argv[]){
name_t n;
scores_t s;
ifstream fin;
string first, last;
int num, size, bsize=0;
string text;
map<name_t, scores_t> map;
fin.open(argv[1]);
while(getline(fin, text)){
stringstream ss(text);
while(ss >> first >> last){
n.set(first, last);
size = first.size() + last.size();
if(size > bsize){
bsize = size;
}
n.print_name(bsize);
while(ss >> num){
cout << num << " ";
s.push_back(num);
}
cout << ": ";
s.compute_stats();
map.insert(std::pair<string, vector<int> >(n.get(), s.get()));
s.print_scores();
}
cout << endl;
}
fin.close();
return 0;
}
I am getting these errors:
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8.2/bits/char_traits.h:39,
from /usr/include/c++/4.8.2/ios:40,
from /usr/include/c++/4.8.2/ostream:38,
from /usr/include/c++/4.8.2/iostream:39,
from Labstats1.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = std::basic_string<char>; _U2 = std::vector<int>; _T1 = const name_t; _T2 = scores_t]’:
Labstats1.cpp:106:64: required from here
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: error: no matching function for call to ‘name_t::name_t(const std::basic_string<char>&)’
: first(__p.first), second(__p.second) { }
^
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: note: candidates are:
Labstats1.cpp:13:7: note: name_t::name_t()
class name_t{
^
Labstats1.cpp:13:7: note: candidate expects 0 arguments, 1 provided
Labstats1.cpp:13:7: note: name_t::name_t(const name_t&)
Labstats1.cpp:13:7: note: no known conversion for argument 1 from ‘const std::basic_string<char>’ to ‘const name_t&’
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8.2/bits/char_traits.h:39,
from /usr/include/c++/4.8.2/ios:40,
from /usr/include/c++/4.8.2/ostream:38,
from /usr/include/c++/4.8.2/iostream:39,
from Labstats1.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: error: no matching function for call to ‘scores_t::scores_t(const std::vector<int>&)’
: first(__p.first), second(__p.second) { }
^
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: note: candidates are:
Labstats1.cpp:43:7: note: scores_t::scores_t()
class scores_t{
^
Labstats1.cpp:43:7: note: candidate expects 0 arguments, 1 provided
Labstats1.cpp:43:7: note: scores_t::scores_t(const scores_t&)
Labstats1.cpp:43:7: note: no known conversion for argument 1 from ‘const std::vector<int>’ to ‘const scores_t&’
I'm not too sure what these errors mean. Any help is appreciated. Thank you!
Your map data type is std::pair<name_t, scores_t>, but you are trying to insert a pair of a std::string and std::vector - since this is what your get() functions are returning.
To solve the immediate compilation error, just use correct data type in insertion.
However, there are other, more subtle issues with your code. For instance, your get() functions return members by value. This means, that a copy will be made every time the function is called - and it takes quite a bite of time to copy the vector or string. Instead, you should expose your members through a function returning const reference.
Also, it is a good practice for a wrapper class (your classes are essentially wrappers) to define constructor which would take an argument of the wrapped type. For instance, for your name_t you might want a constructor like following:
name_t::name_t(const std::string& name) : name(name) {}

Store strings in a vector and sort them

I want to make a class that stores strings from the console in a vector and then sorts them alphabetically using selection sort.
This is my code so far.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class Dictionary
{
public:
Dictionary();
void read(vector<int>&words);
void SelectionSort(vector <int> &num);
private:
//vector<string> line_vector;
string word;
//vector<string> words;
};
Dictionary:: Dictionary()
{
//line_vector = "<empty>";
string word = "<empty>";
}
void Dictionary:: read(vector<int>& words)
{
//vector<string> words;
string word;
while( cin >> word ) words.push_back(word);
}
////////////////////////////////////////////////////////////////////////////////////
void Dictionary:: SelectionSort(vector <int> &num)
{
int i, j, first, temp;
int numLength = num.size( );
for (i= numLength - 1; i > 0; i--)
{
first = 0; // initialize to subscript of first element
for (j=1; j<=i; j++) // locate smallest between positions 1 and i.
{
if (num[j] < num[first])
first = j;
}
temp = num[first]; // Swap smallest found with element in position i.
num[first] = num[i];
num[i] = temp;
}
return;
}
void print(vector<Dictionary>& a)
{
for (int i = 0; i < a.size(); i++)
cout << a[i];
cout << "\n";
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
Dictionary dict;
vector<Dictionary> str;
dict.read(str);
dict.SelectionSort(str);
dict.print(str);
return 0;
}
and these are the errors:
In member function 'void Dictionary::read(std::vector<int>&)':
31:46: error: no matching function for call to 'std::vector<int>::push_back(std::string&)'
31:46: note: candidates are:
In file included from /usr/include/c++/4.9/vector:64:0,
from 3:
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::value_type = int]
push_back(const value_type& __x)
^
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note: no known conversion for argument 1 from 'std::string {aka std::basic_string<char>}' to 'const value_type& {aka const int&}'
/usr/include/c++/4.9/bits/stl_vector.h:931:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::value_type = int]
push_back(value_type&& __x)
^
One of the error lines seems very helpful:
/usr/include/c++/4.9/bits/stl_vector.h:913:7: note:
no known conversion for argument 1
from
'std::string {aka std::basic_string<char>}'
to
'const value_type& {aka const int&}'
If you pass an argument that doesn't match the expected type for a function, then C++ will try to find any conversion from the passed type into the expected type. The conversion include 1-argument constructors and cast operators. See http://www.cplusplus.com/doc/tutorial/typecasting/
This particular error is indicating that the passed argument cannot be converted to an int.

No match for 'operator<' when trying to use set iterator in for loop

I am writing a program that reads in all of the lines of the bible from a file 'bible.txt.' It then processes each line into individual words and stores each word in a set and a multiset. It then finds which words are used between 800 and 1000 times and stores those words in a vector. However, when I try to create an interator to go through the set of words, I receive the error:
word_count.cpp: In function ‘void sort_words()’:
word_count.cpp:93:62: error: no match for ‘operator<’ in ‘p < words.std::set<_Key,
_Compare, _Alloc>::end [with _Key = std::basic_string<char>, _Compare = std::less<std::basic_string<char> >, _
Alloc = std::allocator<std::basic_string<char> >, std::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<std::basic_string<char> >]()’
Here is the line that it has a problem with:
for (set<string>::iterator p = words.begin(); p < words.end(); ++p)
Here is the full code:
#include <iostream>
#include <string>
#include <fstream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;
class wordWithCount {
public:
string word;
int count;
wordWithCount(string w, int c) : word(w), count(c){}
bool operator<(const wordWithCount& right) const {
if (count != right.count) return count < right.count;
return word < right.word;
}
};
set<string> words;
multiset<string> multiwords;
vector<string> lines;
vector<wordWithCount> selectedWords;
void readLines(char *filename)
{
string line;
ifstream infile;
infile.open(filename);
if (!infile)
{
cerr << filename << " cannot open";
return;
}
getline(infile, line);
while (!infile.eof())
{
lines.push_back(line);
getline(infile, line);
}
infile.close();
}
void process_string (vector<string> lines) {
for (int i = 0; i < lines.size(); i++) {
string line = lines[i];
int found = line.find_first_not_of(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
while (found != string::npos)
{
string word = line.substr(0, found);
if (word.length() > 0)
{
words.insert(word);
multiwords.insert(word);
}
line = line.substr(found + 1);
found = line.find_first_not_of(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
}
}
}
void sort_words() {
int low = 800;
int high = 1000;
for (set<string>::iterator p = words.begin(); p < words.end(); ++p)
{
int count = multiwords.count(*p);
if (count >= low && count <= high)
selectedWords.push_back(wordWithCount(*p, count));
}
sort(selectedWords.begin(), selectedWords.end());
}
void print_words() {
for (int i = 0; i < selectedWords.size(); i++)
{
cout << selectedWords[i].word << "\t" << selectedWords[i].count;
}
}
int main() {
readLines("bible.txt");
process_string(lines);
sort_words();
print_words();
return 0;
}
for (set<string>::iterator p = words.begin(); p != words.end(); ++p)
Try p != words.end(); instead.