Essential C++--Exercise of Chpt.3
前言
本文用于记录阅读书籍《Essential C++》Chpt.3后完成课后习题。
正文(Code)
3.1 Using Map plus Set plus Vector
写一个读取文本文件的程序,将文件中的每个单字存入map
。map
的key
便是刚才所说的单字,map
的value
则是该单字在文本文件中的出现次数。再定义一份由“排除字眼”组成的set
,其中包含诸如a
、an
、or
、the
、end
和but
之类的单字。将某单字放入map
之前,先确定该单字并不在“排除子集”中。一旦文本文件读取完毕,请显示一份单字清单,并显示各单字的出现次数。你甚至可以再加以扩展,在显示单字之前,允许用户查询某个单字是否出现与文本文件中。
#include <iostream>
#include <string>
#include <iterator>
#include <fstream>
#include <map>
#include <set>
using namespace std;
#define IN_FILE_PATH ("./in_file.txt") // input file path
int init_map(ifstream &in_file, map<string,int> &usr_map)
{
string str_tmp;
int count;
while(in_file >> str_tmp)
{
usr_map[str_tmp]++;
}
#if 0 // debug: print map info
map<string,int>::iterator it;
it = usr_map.begin();
while(it != usr_map.end())
{
cout << "key: " << it->first << '\t'
<< "count: " << it->second << endl;
it++;
}
#endif
return 0;
}
int init_test_set(set<string> &usr_set)
{
string str_arr[6] = {"a", "an", "or", "the", "and", "but"};
for(int i = 0; i < 6; i++)
{
usr_set.insert(str_arr[i]);
}
#if 0 // debug: print set info
set<string>::iterator it;
it = usr_set.begin();
while(it != usr_set.end())
{
cout << "key: " << *it << endl;
it++;
}
#endif
return 0;
}
bool get_another_try(void)
{
char c_in;
cout << "try it? (Y/y:yes N/n:no): ";
cin >> c_in;
cout << "get input: " << c_in << endl;
bool bTry = false;
if ('Y' == c_in || 'y' == c_in)
{
bTry = true;
}
else
{
bTry = false;
if ('N' != c_in && 'n' != c_in)
{
cout << "invalid input: " << c_in << endl;
return -1;
}
}
return bTry;
}
int get_string(string &str)
{
cout << "pls input string: ";
cin >> str;
//cout << "get input string: " << str << endl;
return 0;
}
int main()
{
int r;
// read in_file
ifstream in_file(IN_FILE_PATH);
if (!in_file)
{
cout << "open file failed!" << endl;
return -1;
}
// init map
map<string, int> m_usr;
r = init_map(in_file, m_usr);
if (r != 0)
{
return -1;
}
// init test set
set<string> set_usr;
r = init_test_set(set_usr);
if (r != 0)
{
return -1;
}
// test code...
string str_tmp;
while(get_another_try())
{
r = get_string(str_tmp);
if (0 != r)
{
continue;
}
set<string>::iterator it = set_usr.begin();
while (it != set_usr.end())
{
if (*it == str_tmp)
{
break;
}
it++;
}
if (it != set_usr.end())
{
cout << "find string[" << str_tmp << "] from set" << endl;
continue;
}
int count = m_usr.count(str_tmp);
if (0 == count)
{
cout << "not found string[" << str_tmp << "], add one!" << endl;
}
else
{
cout << "find one! get count[" << count << "] from map by string: " << str_tmp << endl;
}
}
cout << "user exit!" << endl;
return 0;
}
3.2 Read from File And Process with Function Object
读取文本文件内容—和练习3.1一样—一并将内容储存于vector
。以字符串长度为依据,对vector
排除。定义一个function object
并传给sort()
;这一function object
接受两个字符串,当第一字符串的长度小于第二字符串的长度时,就返回true
。最后,打印排序后的vector
内容。
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
#define IN_FILE_PATH ("./in_file.txt")
class Test
{
public:
bool operator()(string a, string b) const
{
return (a.size() < b.size());
}
};
int main()
{
ifstream in_file(IN_FILE_PATH);
if (!in_file)
{
cout << "open file failed!" << endl;
return -1;
}
string str_tmp;
vector<string> s_vec;
while(in_file >> str_tmp)
{
s_vec.push_back(str_tmp);
}
cout << "------before sort!------" << endl;
vector<string>::iterator it = s_vec.begin();
while(it != s_vec.end())
{
cout << "vec_val: " << *it << endl;
it++;
}
sort(s_vec.begin(), s_vec.end(), Test());
cout << "------after sort!------" << endl;
it = s_vec.begin();
while(it != s_vec.end())
{
cout << "vec_val: " << *it << endl;
it++;
}
return 0;
}
3.3 Check with Map
定义一个map
,以家庭姓氏为key
,value
则是家庭所有小孩的名字。令此map
至少容纳六笔数据。允许用户根据姓氏来查询,并得以打印map
内的每一笔数据。
#include <iostream>
#include <string>
#include <map>
#include <iterator>
using namespace std;
int init_family_map(map<string,string> &usr_map)
{
string first_name[6] = {"zhao", "qian", "sun", "li", "zhou", "wu"};
string second_name[6] = {"11", "22", "33", "44", "55", "66"};
for(int i = 0; i < 6; i++)
{
usr_map[first_name[i]] = second_name[i];
}
#if 0 // debug: print map info
map<string, string>::iterator it = usr_map.begin();
while(it != usr_map.end())
{
cout << "first_name: " << it->first << ", "
<< "second_name: " << it->second << endl;
it++;
}
#endif
return 0;
}
bool get_another_try(void)
{
char c_in;
bool bTry;
cout << "try it? (Y/y:yes N/n:no): ";
cin >> c_in;
if ('Y' == c_in || 'y' == c_in)
{
bTry = true;
}
else
{
bTry = false;
if ('N' != c_in && 'n' != c_in)
{
cout << "invalid input: " << c_in << endl;
return -1;
}
}
return bTry;
}
int main()
{
int r;
map<string,string> map_usr;
// init map
r = init_family_map(map_usr);
if (0 != r)
{
cout << "init family map failed!" << endl;
return -1;
}
string first_name;
while(get_another_try())
{
cout << "pls input first name: ";
cin >> first_name;
if (map_usr.count(first_name) != 0)
{
cout << "find first_name[" << first_name << "], "
<< "second_name[" << map_usr[first_name] << "]" << endl;
}
else
{
cout << "not found first_name: " << first_name << "from map" << endl;
}
}
cout << "user exit!" << endl;
return 0;
}
3.4 Istream_iterator And Ostream_iterator
编写一个程序,利用istream_iterator
从标准输入设备读取一连串整数。利用ostream_iterator
将其中的奇数写至某个文件,每个数值皆以空格分隔。再利用ostream_iterator
将偶数写到另一个文件,每个数值单独放在一行中。
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
#define IN_JISHU_FILE_PATH ("./3.4_jishu.txt")
#define IN_OUSHU_FILE_PATH ("./3.4_oushu.txt")
int main()
{
istream_iterator<int> is(cin);
istream_iterator<int> eof;
vector<int> i_vec;
copy(is, eof, back_inserter(i_vec));
#if 0 // debug: print vector info
vector<int>::iterator it = i_vec.begin();
while(it != i_vec.end())
{
cout << "get: " << *it << endl;
it++;
}
#else
ofstream out_jishu_file(IN_JISHU_FILE_PATH);
ofstream out_oushu_file(IN_OUSHU_FILE_PATH);
ostream_iterator<int> os_jishu(out_jishu_file, " ");
ostream_iterator<int> os_oushu(out_oushu_file, " ");
vector<int>::iterator it = i_vec.begin();
while(it != i_vec.end())
{
if (*it % 2 == 0)
{
os_oushu = *it;
}
else
{
os_jishu = *it;
}
it++;
}
#endif
return 0;
}
结语
个人阅读书籍《Essential C++》之余创建此专栏,用于记录完成每一章节后附录的exercise。如有问题,请各位不吝指正。