17.1、17.2
#include
#include
#include
#include
int main()
{
using namespace std;
tuple ti{ 10,20,30 };
cout << get<0>(ti) << " " << get<1>(ti) << " " << get<2>(ti) << endl;
tuple, pair> top;
system("pause");
return 0;
}
#pragma once
#include
#include
#include
#include
#include
#include "textquery.h"
#include
#include
#include
TextQuery::TextQuery(std::ifstream &ifile) :file(new std::vector)
{
std::string line;
while (std::getline(ifile, line))
{
file->push_back(line);
std::stringstream sstr(line);
std::string word;
while (sstr >> word)
{
//std::shared_ptr> &sptr = ms[word];
auto &sptr = ms[word];
if (!sptr)
sptr.reset(new std::set<_type>);
sptr->insert(file->size() - 1);
}
}
}
TextQuery::QueryResult TextQuery::query(const std::string &s)const
{
static std::shared_ptr> nodata(new std::set<_type>);
auto iter = ms.find(s);
if (iter == ms.end())
return QueryResult(s, nodata, file);
else
return QueryResult(s, iter->second, file);
}
TextQuery::QueryResult TextQuery::query_tuple(const std::string &s)
{
static std::shared_ptr> nodata(new std::set<_type>);
auto iter = ms.find(s);
if (iter == ms.end())
return QueryResult(s, nodata, file);
else
return QueryResult(s, iter->second, file);
}
#include
#include
#include "textquery.h"
std::ostream &operator<<(std::ostream &os, const TextQuery::QueryResult &q)
{
os << std::get<0>(q) << "\n";
for (auto &x : *std::get<1>(q))
os << x << " ";
os << "\n";
for (auto &x : *std::get<2>(q))
os << x << " ";
return os;
}
int main(int agrc,char **argv)
{
using namespace std;
ifstream ifile(argv[1]);
if (!ifile)
{
cout << "open file error!";
exit(1);
}
TextQuery b(ifile);
cout<
原来的方法比较好
tuple用于快速生成,但却难以重构,可用于快速的测试
17.4、17.5、17.6
#pragma once
#include
#include
class Sales_data
{
friend Sales_data operator+(const Sales_data& lhs, const Sales_data& rhs);
friend std::ostream &operator << (std::ostream& os, const Sales_data& s);
friend std::istream &operator >> (std::istream& is, Sales_data& s);
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::ostream &print(std::ostream&, const Sales_data&);
friend std::istream &read(std::istream&, Sales_data&);
public:
Sales_data() = default;
Sales_data(const std::string &s) : bookNo(s) { }
Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(p*n){}
Sales_data(const Sales_data &s) :bookNo(s.bookNo), units_sold(s.units_sold), revenue(s.revenue){}
Sales_data(Sales_data&& s) :bookNo(s.bookNo), units_sold(s.units_sold), revenue(s.revenue){}
~Sales_data() {}
Sales_data(std::istream &);
std::string isbn() const { return bookNo; }
Sales_data& combine(const Sales_data&);
Sales_data& operator =(const Sales_data& rhs);
Sales_data& operator =(const std::string& rhs);
Sales_data& operator +=(const Sales_data& rhs);
explicit operator std::string() const { return bookNo; }
explicit operator double() const { return revenue; }
double avg_price() const;
private:
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
inline Sales_data operator+(const Sales_data& lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;
sum += rhs;
return sum;
}
std::ostream &operator << (std::ostream& os, const Sales_data& item);
std::istream &operator >> (std::istream& is, Sales_data& s);
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
#include
#include "Sales_data.h"
using std::istream; using std::ostream;
Sales_data::Sales_data(std::istream &is)
{
read(is, *this);
}
double Sales_data::avg_price() const {
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
Sales_data &Sales_data::operator =(const Sales_data &rhs)
{
this->bookNo = rhs.bookNo;
this->revenue = rhs.revenue;
this->units_sold = rhs.units_sold;
return *this;
}
Sales_data &Sales_data::operator =(const std::string &rhs)
{
*this = Sales_data(rhs);
return *this;
}
Sales_data &Sales_data::operator +=(const Sales_data &rhs)
{
this->revenue += rhs.revenue;
this->units_sold += rhs.units_sold;
return *this;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
istream &read(istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " "<< item.revenue << " " << item.avg_price();
return os;
}
std::ostream &operator <<(std::ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " "<< item.revenue << " " << item.avg_price();
return os;
}
std::istream &operator >>(std::istream &is, Sales_data &s)
{
double price;
is >> s.bookNo >> s.units_sold >> price;
if (is)
s.revenue = s.units_sold * price;
else
s = Sales_data();
return is;
}
#include
#include
#include
#include
#include //equal_range
#include
#include //accumulate
#include
#include "Sales_data.h"
typedef std::tuple::size_type, std::vector::const_iterator, std::vector::const_iterator> matches;
typedef std::pair::size_type, std::pair::const_iterator, std::vector::const_iterator>>matches_pair;
inline bool compareIsbn(const Sales_data &ls, const Sales_data &rs)
{
return ls.isbn() < rs.isbn();
}
std::vector findbook(const std::vector> &f, const std::string &book)//17.4
{
std::vector ret;
for (auto it = f.cbegin(); it != f.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
if (found.first != found.second)
ret.push_back(make_tuple(it - f.cbegin(), found.first, found.second));
}
return ret;
}
std::vector findbook_pair(const std::vector> &f, const std::string &book)//17.5
{
std::vector ret;
for (auto it = f.cbegin(); it != f.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
if (found.first != found.second)
ret.push_back(make_pair(it - f.cbegin(), make_pair(found.first, found.second)));
}
return ret;
}
struct matches_struct//17.6
{
std::vector::size_type st;
std::vector::const_iterator first;
std::vector::const_iterator second;
matches_struct(std::vector::size_type s, std::vector::const_iterator fi, std::vector::const_iterator se) :st(s), first(fi), second(se) {}
};
std::vector findbook_struct(const std::vector> &f, const std::string &book)
{
std::vector ret;
for (auto it = f.cbegin(); it != f.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);
if (found.first != found.second)
ret.push_back(matches_struct(it - f.cbegin(), found.first, found.second));
}
return ret;
}
void reportRestults(std::istream &is, std::ostream &os, const std::vector> &f)
{
std::string s;
while (is >> s)
{
auto tran = findbook(f, s);
if (tran.empty())
{
std::cout << s << " not found in any stores" << std::endl;
continue;
}
for (const auto &x : tran)
os << "store " << std::get<0>(x) << " sales: " << std::accumulate(std::get<1>(x), std::get<2>(x), Sales_data(s)) << std::endl;
}
}
std::vector *write_sales(std::fstream &f)
{
Sales_data temp;
auto ptr = new std::vector;
while (read(f, temp))
{
ptr->push_back(temp);
}
return ptr;
}
int main(int argc,char **argv)
{
using namespace std;
fstream f1(argv[1]), f2(argv[2]), f3(argv[3]);
if (!f1&&!f2&&!f3)
{
cerr << "error!";
exit(1);
}
std::vector> file;
file.push_back(*write_sales(f1));
file.push_back(*write_sales(f2));
file.push_back(*write_sales(f3));
reportRestults(cin, cout, file);
system("pause");
return 0;
}
更倾向于tuple,相对于其他版本,它更方便
17.8
创建的是使用Sales_data默认构造函数创建的对象
这样的结果就是书名为空,其他数据为0
17.9
a、00000000 00000000 00000000 00000000 00000000 00000000 00000000 00100000
b、00000000 00001111 01101001 10110101
c、视输入的内容而定,但是输入的字符非0或1那么就会抛出invalid_argument异常
17.10
#include
#include
int main()
{
using namespace std;
int v[] = { 1,2,3,5,8,13,31 };
bitset<32> bit1;
for (auto x : v)
bit1.set(x);
bitset<32> bit2;
for (size_t i = 0; i < bit1.size(); ++i)
bit2[i] = bit1[i];
cout << bit1 << endl << bit2;
system("pause");
return 0;
}
#pragma once
#include
#include
#include
template
class Bit //17.11
{
std::bitset bit;
public:
Bit() = default;
Bit(std::string &s) :bit(s) {}
void updata(size_t n, bool b) //17.12
{
bit.set(n, b);
}
template //17.13
friend size_t text(const Bit &lb, const Bit &rb);
template
friend std::ostream &operator<<(std::ostream &os, const Bit &b);
};
template
size_t text(const Bit &lb, const Bit &rb)
{
auto temp = lb.bit^rb.bit; //得出答错的题目
temp.flip(); //翻转所有
return temp.count(); //返回答对的题目
}
template
std::ostream &operator<<(std::ostream &os, const Bit &b)
{
os << b.bit;
return os;
}
#include
#include
#include
int main()
{
using namespace std;
try {
regex reg("[^cei");
}
catch (regex_error e){
cout << e.what() << "\ncode: " << e.code() << endl;
}
system("pause");
return 0;
}
#include
#include
#include
int main()
{
using namespace std;
regex reg("[[:alpha:]]*[^c]ei[[:alpha:]]*",regex::icase);//17.15
string str;
smatch m;
while (cin >> str&&str!="q")
{
if (regex_search(str, m, reg))
cout << str << " is ok" << endl;
else
cout << str << " is not ok" << endl;
}
reg = "[^c]ei";//17.16 好像...并没有什么变化
while (cin >> str&&str != "q")
{
if (regex_search(str, m, reg))
cout << str << " is ok" << endl;
else
cout << str << " not is ok" << endl;
}
system("pause");
return 0;
}
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
using namespace std;
ifstream file(argv[1]);
if (!file)
{
cerr << "open file error!";
exit(1);
}
string p("[^c]ei");
p = "[[:alpha:]]*" + p + "[[:alpha:]]*";
regex reg(p, regex::icase);
string temp, str;
while (getline(file, temp))
str = str + temp + "\n";
vector vec{ "albeit","beige","feint","heir","reign","their",
"counterfeit","foreign","inveigh","rein","veil","deign",
"forfeit","inveigle","seize","veineiderdown","freight",
"leisure","skein","weigheight","heifer","neigh","sleigh",
"weighteither","height","neighbour","sleight","weirfeign",
"heinous neither surfeit weird" };
for (sregex_iterator it(str.begin(), str.end(), reg), end_it; it != end_it; ++it)
{
if (find(vec.begin(), vec.end(), it->str()) != vec.end())//17.8
continue;
cout << it->str();
system("pause");
auto pos = it->prefix().length();
cout << it->prefix().str().substr(pos > 40 ? pos - 40 : 0) << "[> " << it->str() << "<]" << it->suffix().str().substr(0, 40) << endl;
}
system("pause");
return 0;
}
17.19
m4和m6都是分隔符,两者必须是相同的字符,如果一方不匹配或两者不相同,那么就为true
17.20
#include
#include
#include
bool valid(const std::smatch &m);
int main()
{
using namespace std;
string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
regex reg;
try {
reg.assign(phone);
}
catch (regex_error e) {
cout << e.what() << "\ncode: " << e.code();
}
smatch m;
string s;
while (getline(cin, s)&&s!="q")
{
for (sregex_iterator it(s.begin(), s.end(), reg), end_it; it != end_it; ++it)
{
if (valid(*it))
cout << "valid: " << it->str() << endl;
else
cout << "not valid: " << it->str() << endl;
}
}
system("pause");
return 0;
}
bool valid(const std::smatch &m)
{
if (m[1].matched)//如果存在"("左括号
// ")"右括号必须存在,和区号分隔符不存在,或区号分隔符为空格
return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
else //如果不存在"("左括号
// ")"右括号必须不存在,和区号分隔符与号码分隔符必须相同
return !m[3].matched&&m[4].str() == m[6].str();
}
#include
#include
#include
#include
#include
#include
struct PersonInfo {
std::string name;
std::vector phones;
};
bool valid(const std::smatch &m);
bool read_record(std::istream &is, std::vector &people);
void format_record(std::ostream &os, const std::vector &people);
int main()
{
using namespace std;
vector people;
string filename;
cout << "enter input file name:";
cin >> filename;
ifstream fin(filename);
if (read_record(fin, people))
{
cout << "enter output file name:";
string outname;
cin >> outname;
ofstream fout(outname, ofstream::trunc); //覆盖文件:trunc
format_record(fout, people);
}
else
cout << "open file error:" << filename << endl;
system("pause");
return 0;
}
bool valid(const std::smatch &m)
{
if (m[1].matched)
return m[3].matched && (m[4].matched == 0 || m[4] == " ");
else
return !m[3].matched&&m[4].str() == m[6].str();
}
bool read_record(std::istream &is, std::vector &people)
{
if (is)
{
std::string line, word;
while (getline(is, line)) //读取一行到line
{
PersonInfo info;
std::istringstream record(line); //关联流到line,把record绑定到要读取的行line
record >> info.name; //把流中第一个字符串输入到name,这一行的第一个,也就是名字
while (record >> word)
info.phones.push_back(word);//把名字后面的电话号码保存
people.push_back(info); //添加一个联系人
}
return true;
}
else
return false;
}
void format_record(std::ostream &os, const std::vector &people)
{
std::string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})";
std::regex reg;
try {
reg.assign(phone);
}
catch (std::regex_error e)
{
std::cout << e.what() << "\ncode: " << e.code() << std::endl;
}
std::smatch m;
for (const auto &x : people)
{
std::ostringstream formatted, badNums;
for (const auto &n : x.phones)
{
for (std::sregex_iterator it(n.begin(), n.end(), reg), end_it; it != end_it; ++it)
{
if (!valid(*it))
badNums << " " << n; //将数据放入流,暂时保存
else
formatted << " " << n;
}
}
if (badNums.str().empty())
os << x.name << " " << formatted.str() << std::endl; //将流中的数据以string的形式放入os流中
else
std::cerr << "file error: " << x.name << " invalid number " << badNums.str() << std::endl;
}
}
#include
#include
#include
bool valid(const std::smatch &m);
int main()
{
using namespace std;
string phone = "(\\()?(\\d{3})(\\))?([[:blank:]]*)?(\\d{3})([[:blank:]]*)?(\\d{4})"; //([[:blank:]])匹配0-哪个空格或制表符
regex reg;
try {
reg.assign(phone);
}
catch (regex_error e) {
cout << e.what() << "\ncode: " << e.code();
}
smatch m;
string s;
while (getline(cin, s)&&s!="q")
{
for (sregex_iterator it(s.begin(), s.end(), reg), end_it; it != end_it; ++it)
{
if (valid(*it))
cout << "valid: " << it->str() << endl;
else
cout << "not valid: " << it->str() << endl;
}
}
system("pause");
return 0;
}
bool valid(const std::smatch &m)
{
if (m[1].matched)//如果存在"("左括号
// ")"右括号必须存在,和区号分隔符不存在,或区号分隔符为空格
return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
else //如果不存在"("左括号
// ")"右括号必须不存在,和区号分隔符与号码分隔符必须相同
return !m[3].matched&&m[4].str() == m[6].str();
}
17.23
#include
#include
#include
int main()
{
using namespace std;
string s = "(\\d{5})([-])?(\\d{4})?";
string num;
regex reg(s);
smatch m;
while (getline(cin, num) && num != "q")
{
for (sregex_iterator it(num.begin(), num.end(), reg), end_it; it != end_it; ++it)
{
if ((*it)[3].matched)
cout << it->str();
else
cout << it->str(1);
cout << endl;
}
}
system("pause");
return 0;
}
#include
#include
#include
int main()
{
using namespace std;
string phone = "(\\()?(\\d{3})(\\))?([[:blank:]]*)?(\\d{3})([[:blank:]]*)?(\\d{4})";
regex reg;
try {
reg.assign(phone);
}
catch (regex_error e) {
cout << e.what() << "\ncode: " << e.code();
}
string fmt = "$2.$5.$7";
smatch m;
string s;
while (getline(cin, s) && s != "q")
{
cout << regex_replace(s, reg, fmt) << endl;
}
system("pause");
return 0;
}
#include
#include
#include
int main()
{
using namespace std;
string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string fmt = "$2.$5.$7";
regex r(pattern);
string s;
while (getline(cin, s))
{
smatch result;
regex_search(s, result, r);
if (!result.empty())
{ //prefix输出匹配前的字符 //format(fmt)输出匹配的格式的字符串
cout << result.prefix() << result.format(fmt) << endl;
}
else
{
cout << "木有匹配的" << endl;
}
}
system("pause");
return 0;
}
#include
#include
#include
int main()
{
using namespace std;
string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
string fmt = "$2.$5.$7";
regex r(pattern);
string s;
while (getline(cin, s))
{
smatch result;
regex_search(s, result, r);
if (!result.empty())
{ //prefix输出匹配前的字符 //suffix输出匹配的字符串后面的字符
cout << result.prefix() << result.suffix()<< endl;
}
else
{
cout << "木有匹配的" << endl;
}
}
system("pause");
return 0;
}
#include
#include
#include
int main()
{
using namespace std;
string p = "(\\d{5})(\\d{4})";
regex reg(p);
string fmt = "$1-$2";
smatch m;
string n;
while (getline(cin, n) && n != "q")
{
cout << regex_replace(n, reg, fmt, regex_constants::match_flag_type::format_no_copy);
}
system("pause");
return 0;
}
17.28、17.29、17.30
#include
#include
#include
unsigned ran() //17.28
{
std::default_random_engine e;
std::uniform_int_distribution u;
return u(e);
}
unsigned ran(unsigned s)//7.29
{
std::default_random_engine e(s);
std::uniform_int_distribution u;
return u(e);
}
unsigned ran(unsigned s, int f, int l)//17.30
{
std::default_random_engine e(s);
std::uniform_int_distribution u(f, l);
return u(e);
}
int main()
{
using namespace std;
unsigned f, l;
cout << ran() << endl;
cout << ran(time(0));
cout << "enrer seed:";
cin >> f >> l;
cout << ran(time(0), f, l);
system("pause");
return 0;
}
结果每次都相同。
因为引擎返回相同的随机数序列,所以必须在循环外声明引擎对象,否则每次循环都会创建一个新的引擎(随机数序列不变),而每次都会输出引擎的序列
17.32
resp不在作用域,找不到resp对象
如果在循环里创建resp:
do{
string resp;
}while(...);
在这里,while的前面循环体已经退出,释放所有在循环体定义的对象,所以resp已经不存在
17.33
#include
#include
#include
#include
#include
#include
#include
int main()
{
using namespace std;
cout << unitbuf;//17.34
cout << boolalpha << (5 < 4 ? true : false) << noboolalpha << endl;
cout << showpos << showbase << hex << 1000 << " " << oct << 1000
<< " " << dec << 1000 << noshowbase << noshowpos << endl;
cout << uppercase << 3.14159 << " " << hex << 1000 << dec
<< nouppercase << endl;
cout << setfill('#') << setw(10) << internal << showpos << 1024
<< noshowpos << nounitbuf << ends << endl << flush;
cout << setw(10) << left <> noskipws;
while (cin >> ch&&ch != 'q')
cout << ch;
cin >> skipws;
cout << endl;
cout << uppercase;//17.35
cout << "default format: " << 100 * sqrt(2.0) << '\n'
<< "scientific: " << scientific << 100 * sqrt(2.0) << '\n'
<< "fixed decimal: " << fixed << 100 * sqrt(2.0) << '\n'
<< "hexidecimal: " << uppercase << hexfloat << 100 * sqrt(2.0) << '\n'
<< "use defaults: " << defaultfloat << 100 * sqrt(2.0)
<< endl;
cout << setfill(' ');//17.36
cout << left << setw(20) << "default format:" << setw(25) << right << 100 * sqrt(2.0) << '\n'
<< left << setw(20) << "scientific:" << scientific << setw(25) << right << 100 * sqrt(2.0) << '\n'
<< left << setw(20) << "fixed decimal:" << setw(25) << fixed << right << 100 * sqrt(2.0) << '\n'
<< left << setw(20) << "hexidecimal:" << setw(25) << uppercase << hexfloat << right << 100 * sqrt(2.0) << '\n'
<< left << setw(20) << "use defaults:" << setw(25) << defaultfloat << right << 100 * sqrt(2.0)
<< "\n\n";
system("pause");
return 0;
}
17.37
#include
#include
int main(int argv, char **argc)
{
using namespace std;
ifstream ifile(argc[1]);
if (!ifile)
{
cout << "open file error!";
exit(1);
}
char ar[100];
do {
ifile.getline(ar, 10);//当行超出10个字符时停止
cout << ar << ' ';
} while (ifile);
ifile.close();
system("pause");
return 0;
}
#include
#include
int main(int argv, char **argc)
{
using namespace std;
ifstream ifile(argc[1]);
if (!ifile)
{
cout << "open file error!";
exit(1);
}
char ar[100];
do {
ifile.getline(ar, 100,' ');
cout << ar << ' ';
} while (ifile);
ifile.close();
system("pause");
return 0;
}
#include
#include
#include
int main(int argc, char **argv)
{
using namespace std;
fstream iofile(argv[1],fstream::ate|fstream::in|fstream::out);//以只读、只写和文件指针跳到文件尾的方式打开
if (!iofile)
{
cerr << "open file error!";
exit(1);
}
auto end_mark = iofile.tellg();//返回当前文件指针的位置
iofile.seekg(0, fstream::beg);//文件指针跳到文件头,偏移0
size_t cnt = 0;
string line;
while (iofile&&iofile.tellg() != end_mark&&getline(iofile,line))//确定当前文件io流可用与文件当前位置不是原文件尾
{
cnt += line.size() + 1;//增加当前行的长度,+1表示换行符也算
auto mark = iofile.tellg();//保存当前文件指针
iofile.seekp(0, fstream::end);//文件指针跳到文件尾
iofile << cnt;//写入长度
if (mark != end_mark)//确定原位置不是原文件尾
iofile << " ";
iofile.seekg(mark);
}
iofile.seekp(0, fstream::end);
iofile << "\n";
iofile.close();
system("pause");
return 0;
}
2016年4月17日22:42:51 最折磨人的事情不过于你的床在你不知情的情况下被不认识的人睡了,还弄得一团糟