赞
踩
本文答案,部分参考于C++ Primer 习题集
https://www.jianguoyun.com/p/DTK5uJgQldv8CBjKv80D
tuple<int,int,int> ti{10,20,30};
tuple<string, vector<string>, pair<string, int>> t;
/* * This file contains code from "C++ Primer, Fifth Edition", by Stanley B. * Lippman, Josee Lajoie, and Barbara E. Moo, and is covered under the * copyright and warranty notices given in that book: * * "Copyright (c) 2013 by Objectwrite, Inc., Josee Lajoie, and Barbara E. Moo." * * * "The authors and publisher have taken care in the preparation of this book, * but make no expressed or implied warranty of any kind and assume no * responsibility for errors or omissions. No liability is assumed for * incidental or consequential damages in connection with or arising out of the * use of the information or programs contained herein." * * Permission is granted for this code to be used for educational purposes in * association with the book, given proper citation if and when posted or * reproduced.Any commercial use of this code requires the explicit written * permission of the publisher, Addison-Wesley Professional, a division of * Pearson Education, Inc. Send your request for permission, stating clearly * what code you would like to use, and in what specific way, to the following * address: * * Pearson Education, Inc. * Rights and Permissions Department * One Lake Street * Upper Saddle River, NJ 07458 * Fax: (201) 236-3290 */ #include <cassert> #include <utility> using std::pair; #include <string> using std::string; #include <tuple> using std::tuple; using std::get; using std::make_tuple; #include <vector> using std::vector; #include <numeric> using std::accumulate; #include <algorithm> using std::equal_range; #include <exception> #include <stdexcept> using std::domain_error; #include <iostream> using std::ostream; using std::istream; using std::cout; using std::endl; #include <fstream> using std::ifstream; #include "Sales_data.h" bool lt(const Sales_data &lhs, const Sales_data &rhs) { return lhs.isbn() < rhs.isbn(); } // need to leave this for as a traditional for loop because we // use the iterator to compute an index // matches has three members: an index of a store and iterators into that store's vector typedef tuple<vector<Sales_data>::size_type, vector<Sales_data>::const_iterator, vector<Sales_data>::const_iterator> matches; // files holds the transactions for every store // findBook returns a vector with an entry for each store that sold the given book vector<matches> findBook(const vector<vector<Sales_data>> &files, const string &book) { vector<matches> ret; // initially empty // for each store find the range of matching books, if any for (auto it = files.cbegin(); it != files.cend(); ++it) { // find the range of Sales_data that have the same ISBN auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn); if (found.first != found.second) // this store had sales // remember the index of this store and the matching range ret.push_back(make_tuple(it - files.cbegin(), found.first, found.second)); } return ret; // empty if no matches found } vector<Sales_data> build_store(const string &s) { Sales_data item; vector<Sales_data> ret; ifstream is(s); while (read(is, item)) ret.push_back(item); sort (ret.begin(), ret.end(), lt); // need sort for equal_range to work return ret; } void reportResults(istream &in, ostream &os, const vector<vector<Sales_data>> &files) { string s; // book to look for while (in >> s) { auto trans = findBook(files, s); // stores that sold this book if (trans.empty()) { cout << s << " not found in any stores" << endl; continue; // get the next book to look for } for (const auto &store : trans) // for every store with a sale // get<n> returns the specified member from the tuple in store os << "store " << get<0>(store) << " sales: " << accumulate(get<1>(store), get<2>(store), Sales_data(s)) << endl; } } int main(int argc, char **argv) { assert(argc > 1); // each element in files holds the transactions for a particular store vector<vector<Sales_data>> files; for (int cnt = 1; cnt != argc; ++cnt) files.push_back(build_store(argv[cnt])); ifstream in("../data/findbook.in"); // ISBNs to search for reportResults(in, cout, files); }
1.matches的类型改为pair,其中第二个成员还是一个pair,保存节目的起止迭代器.
2.findBook中构造返回值的部分,用make_pair构造一个pair,第一个参数与tuple版本一样,第二个参数直接用found
3.reportResult从findBook返回的matches中提取数据,进行输出的部分,get<0>(store),get<1>(store)和get<2>(store)改为store,first.store,second.first.和store.second.second
typedef pair<vector<Sales_date>::size_type,pair<vector<Sales_data>::const_iterator,vector<Sales_date>::const_iterator>> matches;
ret.push_back(make_pair(it-files.cbegin(),found));
os<<"sotre "<<sotre.first<<" sales: "<<accdumulate(sotre.second.first,storer.second.second,Sales_data(s))
<<endl;
本题只是简单使用搜索结果,pair和tuple都是简单直接的实现方式.
如果搜索结果还需进行复杂的计算,处理,定义一个类对其进行封装会更好.
Sales_data()是Sales_data的默认构造函数,对所有数据成员都采用值初始化,因此lsbn被初始化为空字符串.因此,再输出结果中,见看不到数目的isbn()
(a)bitvec为32位,第五位位1,剩余位位0
(b)bv位32位,0,2,4,6这4位位1,剩余位位0
© bv为8位.用bstr来对其初始化,若读入的字符串不是单纯的二进制字符串.程序会抛出invalid_argument异常.
#include<iostream>
#include<bitset>
using namespace std;
int main() {
unsigned bp = 2 | (11 < 2) | (1 << 5) | (1 << 8) | (1 << 13) | (1 << 21);
bitset<32> bv(bp);
cout << bv << endl;
bitset<32> bv1;
bv1.set(1); bv1.set(2); bv1.set(3); bv1.set(5);
bv1.set(8); bv1.set(13); bv1.set(21);
cout << bv1 << endl;
return 0;
}
输出结果如下:
00000000001000000010000100100010
00000000001000000010000100101110
如果使用整数来保存测验解答,那么对于10个问题的测验,只需一个短整形对象即可.如果改为100道题,则需要4个32位整数或是2个64位整数.而且修改的并不仅仅是数据结果,所有对整形数进行操作来修改解答和评分的代码都要相应修改,工作量很大.
采用bitset则有很明显的优势,当题目数改变时,我们只需改变bitset的规模,而操作bitset来完成答案,评分的代码则只需进行很小的修改.
最佳的方式是定义一个类模板,它有一个模板参数表示题目数.有一个bitset成员保存解答.然后定义一些成员函数来完成改答案,评分等操作,当题目数发生变化,我们只需实例化一个新版本.其他代码均无法改动.
此函数直接调用bitset的set操作即可,程序见下题.
regex r("[[:alnum]]+\\.(cpp|cxx|cc)$",regex::icase);
若pattern只是
" [^c]ei ",则只与" ?ei "形式的字符串匹配.其中?是除c之外的知乎,因此,输出的只是错误拼写的部分,而不是包含错误拼写的完整单词,例如:对" friend"只输出" rie".
在使用匹配时(在本题中,即for循环中输出匹配字符串)排除例外情况即可.
if(it->str()!="albeit"&&it->str()!="neighbor")
cout<<it->str()<<endl;
当子匹配未匹配时,其str()会返回空string,仍然可以合法使用
首先,将正则表达式改为:
"(\\()?(\\d{3})(\\)?([-.])(\\s)*)?(\\d{3}([-.](\\s)*)?(\\d{4}))"
表示间隔三部分的可以是一个".",一个“-”,或是多个空白符(\s).
然后要修改valid的判断逻辑
1 若有开始左括号,则第三个子匹配必须也匹配(有配对右括号),且第4个子匹配不能是分隔符,必须是空白符或是没有.
2 若无开始左括号,则也不能右右括号,且4,6两个子匹配必须一样------------同为".",或同为“-”,或同为空白序列(都不是".",“-”)
-----------------占位符-------------
"(\\d{5})((-?)(\\d{4}))?"
略
利用regex迭代器,只取第一个匹配即可.另一种方式是保存所有匹配的号码,但在输出时,只输出第一个号码.
sregex_iterator it(line.begin(),line.end(),r),end_it;
for(it++;it!=end_it;it++)
if(valid(*it))
info.phones.push_back("V"+it->str());
else info.phones.push_back("I"+it->str());
#include<iostream> #include<string> #include<regex> using namespace std; int main() { string zip = "(\\d{5})(-?)(\\d{4}))?"; regex r(zip); string s; string fmt = "$1-$2"; while (getline(cin, s)) { for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; += it) { if ((*it)[2].matched && (*it)[2].str()[0] != '-') cout << (*it).format(fmt) << endl; else cout << (*it).str() << endl; } } return 0; }
在循环内定义b和e,每个循环步都会用到默认的种子(0)重新初始化随机数引擎e,因此,调用b(e)永远得到的是特定随机数的第一个数,游戏的先行者永远是固定的.
而在循环外定义,则可保持引擎的状态.每次得到随机数序列中的下一个值.游戏的先行者会改变.
如果在循环内定义resp,则其生命周期仅在循环体内,而while循环条件判定不属于循环体.因此,在进行循环体条件判定时,resp已经被销毁,程序会产生编译错误.
用hexfloat指定浮点数并打印成16进制.用uppercase指定打印大写形式,
cout<<"hexadecimal: "<<hexfloat<<uppercase<<sqrt(2.0)<<'\n';
修改循环内逻辑,读取并打印文本后,并不打印换行.而是在判断未出现fail状态.也就是说,getline读取成功且未达到上限时才打印回车.这样就可以很多次读入的一行文本仍然打印成一行.
cout<<text;
if(!in.good())
if(in.gcount()==29)
in.clear();
else
break;
else cout<<endl;
参考书中本节内容实现即可
有一点需要注意,如果是在Windows平台使用gcc编译器,编译此程序,得到的目标程序在处理Winoows格式的文本文件(每行结尾是两个之路,CR-回车.LF-换行)时会产生seek定位不准的情况.处理UNIX格式的文件(行尾只有一个LF)则没有问题,用VC编译得到的目标程序则是相反的情况.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。