Stack STL with 2 params - c++

Im implementing a B-tree in C++,I have a stack which saves pairs . my problem is, how i put in this stack because push only accept 1 argument. thanks

Use std::pair provided by the standard library.
You can create them with the function make_pair.
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
int myInt = 1;
string myString("stringVal");
stack<pair<string, int> > myStack;
myStack.push(make_pair(myString, myInt));
return 1;
}

#include <stack>
#include <utility>
#include <iostream>
using namespace std;
int main() {
stack <pair<int,int> > s;
s.push( make_pair( 1, 2 ) );
pair <int, int> p = s.top();
cout << p.first << " " << p.second << endl;
}

#include <utility>
// ...
stack<pair<string,string> > s;
s.push(make_pair("roses", "red"));

int main()
{
stack <pair<int,int> > s;
s.push({1,2});
cout << s.top().first << " " << s.top().second;
}

Related

How could/should I print text strings above number columns in C++?

I would like to print the strings at the top of columns with a 1 x 3 array.
I have edited this simple function several times, and this produces the least errors. New to C++, reading Deital Chap 6 Recursive.
What am I missing? I started with half brackes around strings, and brackets seemed to produce less errors.
Here is the code:
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main() {
array a[1][3] = ["Car" "Hours" "Charge"]
cout<< a << endl;
}
Terminal produces errors as such:
parking_charges_6_12.cpp: In function ‘int main()’:
parking_charges_6_12.cpp:8:7: error: missing template arguments before ‘a’
8 | array a[1][3] = ["Car" "Hours" "Charge"]
^
This should work:
#include <array>
#include <iostream>
#include <string>
int main(){
std::array<std::string, 3> headlines = {"Car", "Hours", "Charge"};
for( auto const& elem : headlines ){
std::cout << elem << "\t";
}
}
It should be curly braces {} in the initializer, not []. And you need a comma between each element.
On the other hand, in later C++ revisions array can detect the type and number of elements, so you don't have to give that.
#include <iostream>
#include <array>
using namespace std;
int main() {
array a = {"Car", "Hours", "Charge"};
for (auto& item : a)
cout<< item << endl;
}
How about something like this:
#include<iostream>
using namespace std;
int main() {
string data[3] = {"Car", "Hours", "Charge"};
for (int i = 0; i < 3; i++)
cout << data[i] << " ";
}
Obviously it is not using the array header, but it's a working example. If you do need to use the array header, you can try something like :
#include <array>
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
int main() {
array<string, 3> ar3 = {"Car", "Hours", "Charge"};
cout << ar3.size() << endl;
for (auto i : ar3)
cout << i << ' ';
return 0;
}
You can see it working online here

why my cpp code can't run?(about char*[])

this is my code
the error is Segmentation fault,and i can't understand why
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char* szword[100];
int i = 0;
do
{
cin >> szword[i];
cout << szword[i];
i++;
}while(strcmp(szword[i - 1], "done"));
cout << i + 1;
return 0;
}
For starters neither declaration from headers <cstdio> and <string> is used in your program. So you should remove these directives
#include <cstdio>
#include <string>
You declared an initialized array with the element type char *. Thus this statement
cin >> szword[i];
invokes undefined behavior because the pointer szword[i] has indeterminate value.
Moreover this call even if the argument of the operator will be correct
cin >> szword[i];
can fail. You should check whether it was successful. And I think there is no great sense to output the string "done".
Also in this statement
cout << i + 1;
you are outputting a value that is greater than the number of inputted strings.
If to use character arrays then your program could look the following way
#include <iostream>
#include <cstring>
int main()
{
const size_t N = 100;
char szword[N][N];
size_t i = 0;
while ( std::cin.getline( szword[i], sizeof( szword[i] ) ) &&
std::strcmp( szword[i], "done" ) != 0 )
{
std::cout << szword[i++] << '\n';
}
std::cout << i << '\n';
return 0;
}
The program output might look like
Hello
World
2
This below code works fine, if you want to use char *, for C++ string you can use the C++ version
C Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char *tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(strcmp(tmp, "done"));
cout << i + 1;
return 0;
}
C++ Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
string tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(tmp != "done"));
cout << i + 1;
return 0;
}

sort in lexicographic order in map C++

I am using STL map in C++ for counting the frequency of words in a text file and words must be sort in lexicographic order. Input data is given as a text file. Ive already read and added them in map but i got a problem with sorting.
Example, i have { "Abc", "abc", "bag", "Boom", "great"}. When i added them in map, i got
Abc 1 Boom 1 abc 1 bag 1 great 1
but expected result is
Abc 1 abc 1 Boom 1 bag 1 great 1
#include <iostream>
#include <cstring>
#include <map>
#include <fstream>
using namespace std;
typedef map<string, int> word_count;
int main(){
word_count wc;
fstream f_in;
f_in.open("test.in");
string x;
while( !f_in.eof()){
f_in >> x;
wc[x]++;
}
f_in.close();
return 0;
}
Here is my code for reading input. Any help for my problem? Thanks
The OP wants a custom sort order that's subtly different from the standard lexicographical order. A map with a custom sort order can be achieved by passing in a custom Compare (Compare is the third template parameter of map):
#include <algorithm>
#include <cctype>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <vector>
using std::string;
using std::transform;
using std::map;
using std::cout;
struct Compare {
bool operator() (const string& s0, const string& s1) const {
// construct all lowercase versions of s0 and s1
string str0(s0.length(),' ');
string str1(s1.length(),' ');
transform(s0.begin(), s0.end(), str0.begin(), tolower);
transform(s1.begin(), s1.end(), str1.begin(), tolower);
if (!str0.empty() and !str1.empty() and str0.front()==str1.front()) {
// do a standard lexicographic sort if the first character is the same
return s0 < s1;
}
else {
// otherwise, do a case-insensitive lexicographic sort using the lowercased strings
return str0 < str1;
}
}
};
typedef map<string, int, Compare> word_count;
int main(){
word_count wc;
auto words = { "Abc", "abc", "bag", "Boom", "great"};
for (auto word : words)
wc[word]++;
for(auto elem : wc)
cout << elem.first << " " << elem.second << '\n';
return 0;
}
This indeed produces the desired output:
Abc 1
abc 1
Boom 1
bag 1
great 1
Try out a live version of the code online
By default, the third template parameter of a map is less<key> (in this case, less<string>), which will sort strings in the standard lexicographical A-z order.
Here is a complete example with file reading included, and using the base sorting functionality of std::map.
#include <iostream>
#include <cstring>
#include <map>
#include <fstream>
typedef std::map<std::string, int> word_count;
int main(int argc, char** argv){
if(argc < 2){
std::cout << "Please provide a file name." << std::endl;
return 1;
}
word_count wc;
std::ifstream inputfile(argv[1]);
if (inputfile.is_open()){
std::string x;
while(inputfile >> x){
wc[x]++;
}
inputfile.close();
}else {std::cout << "Program aborted: unable to open input file" << std::endl; return 1;}
for(auto word: wc){
std::cout << word.first << "\t" << word.second << std::endl;
}
return 0;
}

C++11 search an std::map with composite key

I want to implement a function (findn) below that search on the std::map to find an element. However in my case the key is composite value, it is an <int,int>
How do I use the std::map.find here?
#include <iostream>
#include <map>
#include <utility>
#include <string>
using namespace std;
std::map<std::pair<int, int>, std::string> studentMap;
int insert(int i, int j, std::string name) {
if( !studentMap.insert( std::make_pair ( std::make_pair(i,j), name)).second ) {
std::cout << "game not added" << std::endl;
} else {
std::cout << "game added" << std::endl;
}
return 0;
}
void findn(int i, int j) {
// how to find when we have composite key?
}
int main() {
insert(1,1,"test");
insert(1,1,"tes");
insert(1,2,"test 2");
std::cout << studentMap.size() << std::endl;
findn(1,1);
}
This would do the work:
auto it = mymap.find(std::make_pair(i,j));

Run through a vector of member functions in boost for_each

I try to learn boost lambda expressions, and this is a thing that doesn't work out.
How can I run in the for_each a selected member of Holder?
#include <iostream>
#include <string>
#include <boost/assign.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace std;
using namespace boost::assign;
using namespace boost::lambda;
class Holder
{
public:
void vRun1(std::string s){ cout << "vRun1 " << s << endl; }
void vRun2(std::string s){ cout << "vRun2 " << s << endl; }
void vRun3(std::string s){ cout << "vRun3 " << s << endl; }
};
// --------------------
std::map< std::string, mem_fun_ref_t<void, Holder> > replacer;
insert(replacer)
("buh", std::mem_fun_ref(&Holder::vRun1))
("mar", std::mem_fun_ref(&Holder::vRun2))
("heu", std::mem_fun_ref(&Holder::vRun3));
Holder hol;
How do I call here the functions I have registered in the map<>?
for_each(replacer.begin(), replacer.end(), /* bind(_1, hol, it.first) */ );
The result should be
vRun1 buh
vRun2 mar
vRun3 heu
It looks as though you are overcomplicating it slightly. I'd use boost::function<> like so:
See it live on http://liveworkspace.org/code/b2c5a38d8c3499eefb6330a839a89d0a
#define BOOST_RESULT_OF_USE_DECLTYPE
#include <iostream>
#include <string>
#include <map>
#include <boost/function.hpp>
#include <boost/foreach.hpp>
#include <boost/phoenix.hpp>
using namespace std;
class Holder {
public:
void vRun1(std::string s){ cout << "vRun1 " << s << endl; }
void vRun2(std::string s){ cout << "vRun2 " << s << endl; }
void vRun3(std::string s){ cout << "vRun3 " << s << endl; }
};
typedef std::map< std::string, boost::function<void(Holder&, std::string)> > Replacer;
int main()
{
Replacer replacer;
replacer["a"] = &Holder::vRun1;
replacer["b"] = &Holder::vRun2;
replacer["c"] = &Holder::vRun3;
Holder hol;
for (Replacer::const_iterator it=replacer.begin(); it != replacer.end(); ++it)
{
(it->second)(hol, it->first);
}
Alternatively:
std::cout << "Using BOOST_FOREACH:\n";
BOOST_FOREACH(Replacer::value_type& pair, replacer)
{
(pair.second)(hol, pair.first);
}
Or even:
std::cout << "Using Boost Phoenix:\n";
namespace phx = boost::phoenix;
using namespace phx::arg_names;
std::for_each(replacer.begin(), replacer.end(),
phx::bind(
phx::bind(&Replacer::value_type::second, arg1),
phx::ref(hol),
phx::bind(&Replacer::value_type::first, arg1)));
}
Outputs
vRun1 a
vRun2 b
vRun3 c
Using BOOST_FOREACH:
vRun1 a
vRun2 b
vRun3 c
Using Boost Phoenix:
vRun1 a
vRun2 b
vRun3 c
This works for me:
#include <iostream>
#include <string>
#include <boost/assign.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/function.hpp>
using namespace boost::lambda;
class Holder
{
public:
void vRun1(std::string s){ std::cout << "vRun1 " << s << std::endl; }
void vRun2(std::string s){ std::cout << "vRun2 " << s << std::endl; }
void vRun3(std::string s){ std::cout << "vRun3 " << s << std::endl; }
};
// --------------------
typedef std::map <std::string,
boost::function<void(Holder&, std::string)> > Replacer_t;
Replacer_t replacer;
typedef Replacer_t::value_type ReplacerValue_t;
int main()
{
boost::assign::insert(replacer)
(std::string("buh"), &Holder::vRun1)
(std::string("mar"), &Holder::vRun2)
(std::string("heu"), &Holder::vRun3);
Holder hol;
for_each(replacer.begin(),
replacer.end(),
bind(protect(bind(bind(&ReplacerValue_t::second,_2),
_1,
bind(&ReplacerValue_t::first,_2))),
boost::ref(hol), _1));
}
This took about 2 hours of fighting with boost::lambda. In C++11 I would write it in 30 seconds, so update your compilers accordingly.