21:将合法性检查与元素获取的返回语句分离开来,代码更清晰易读,当执行到第二条语句时,已确保p是存在的vector,curr是合法的位置,可安全地获取元素并返回。这种清晰的结构也更有利于修改不同的处理逻辑。
22:将构造函数定义为const即可
23:知识点1:大多数的应用应该使用标准库容器,而不是使用动态分配的数组
知识点2:用new分配的动态数组会返回一个元素类型的指针,而并未得到数组类型的对象
知识点3:动态数组并不是数组类型,不能调用begin()和end()函数,详见106页
知识点4:释放动态数组时,需要在指针名前加 [ ] ,数组中的元素按照逆序销毁
知识点5:字符串字面常量不同于普通的局部变量,具有static duration lifetime,这整个程序的生命周期中都将存在
#include<iostream> #include<string> #include<fstream>#include<list>#include<vector> #include<map> #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件using namespace std;int main(int argc, char**argv) { char *s1 = "abc"; char *s2 = "efg";//字符串字面常量,字符串末尾有空格 string si = "a"; string sl = "b";//标准库string对象 char *p = new char[strlen(s1)+strlen(s2)+1];//必须指明要分配对象的个数 strcpy(p,s1);//复制 strcat(p,s2);//接上 cout<<p<<endl; strcpy(p,(si+sl).c_str());//必须转换为c类型字符串(c中无string类型) cout<<p<<endl; delete [] p; return 0;}24:长度超出后,自动会补上长度:动态数组!
#include<iostream> #include<string> #include<fstream>#include<list>#include<vector> #include<map> #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件using namespace std;int main(int argc, char**argv) { string a; cin>>a; char *p = new char[2]; strcpy(p,a.c_str()); cout<<p<<endl; delete [] p;//一定要记得delete return 0;}25:
delete [] pa;26:知识点1:new内存分配与对象构造组合在了一起,而allocator将内存分配和对象构造分离,它提供一种类型感知的内存分配方法,它分配的内存时原始的、未构造的知识点2:利用allocator分配内存之后。必须在经过construnct进行构造对象,两个参数分别为:创建对象位置的指针,元素类型的值知识点3:对构造后的元素进行destory操作,销毁对象,deallocator
#include<iostream> #include<string> #include<fstream>#include<list>#include<vector> #include<map> #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件#include<memory>using namespace std;int main(int argc, char**argv) { // string *const p = new string[10];//构造十个空const string// string s;// string *q = p;// while (cin>>s && q != p+10)// {// *q++ = s;// }// const size_t size = q-p;// delete [] p; string s; allocator<string> alloc; auto p = alloc.allocate(10);//用的是(),只分配内存 auto q = p; while (cin>>s && q != p+10) { alloc.construct(q++,s);//创建对象并幅值 } while(q != p) { alloc.destroy(--q);//逐个销毁对象,destory接受一个指针 } alloc.deallocate(p,10);//分配多少内存,释放多少 return 0;}27:主函数.cpp
#include "Chapter12.h"#include <iostream>using namespace std;void runQueries(std::ifstream& infile){ TextQuery tq(infile); while (true) { cout << "enter Word to look for, or q to quit: "; string s; if (!(cin >> s) || s == "q") break; PRint(cout, tq.query(s)) << endl; }}int main(){ ifstream file("1.txt"); runQueries(file);}头文件.h
#ifndef Cccc//第一次包含本头文件时,#ifndef判断为真,预处理器将处理后面的内容直到#endif,此时的预处理变量Cccc已定义#define Cccc//第二次包含本头文件时,#ifndef判断为假,预处理器将忽略后面的内容#include <string>#include <fstream>#include <map>#include <set>#include <vector>#include <iostream>#include <sstream>using namespace std;class QueryResult;class TextQuery {public: using LineNo = vector<string>::size_type; TextQuery(std::ifstream&); QueryResult query(const string&) const;private: shared_ptr<vector<string>> input; std::map<string, shared_ptr<std::set<LineNo>>> result;};class QueryResult {public: friend std::ostream& print(std::ostream&, const QueryResult&);public: QueryResult(const string& s, shared_ptr<std::set<TextQuery::LineNo>> set, shared_ptr<vector<string>> v) : word(s), nos(set), input(v) { }private: string word; shared_ptr<std::set<TextQuery::LineNo>> nos; shared_ptr<vector<string>> input;};std::ostream& print(std::ostream&, const QueryResult&);TextQuery::TextQuery(std::ifstream& ifs) : input(new vector<string>){ LineNo lineNo{0}; for (string line; std::getline(ifs, line); ++lineNo) { input->push_back(line); std::istringstream line_stream(line); for (string text, word; line_stream >> text; word.clear()) { // avoid read a word followed by punctuation(such as: word, ) std::remove_copy_if(text.begin(), text.end(), std::back_inserter(word), ispunct); // use reference avoid count of shared_ptr add. auto& nos = result[word]; if (!nos) nos.reset(new std::set<LineNo>); nos->insert(lineNo); } }}QueryResult TextQuery::query(const string& str) const{ // use static just allocate once. static shared_ptr<std::set<LineNo>> nodate(new std::set<LineNo>); auto found = result.find(str); if (found == result.end()) return QueryResult(str, nodate, input); else return QueryResult(str, found->second, input);}std::ostream& print(std::ostream& out, const QueryResult& qr){ out << qr.word << " occurs " << qr.nos->size() << (qr.nos->size() > 1 ? " times" : " time") << std::endl; for (auto i : *qr.nos) out << "/t(line " << i + 1 << ") " << qr.input->at(i) << std::endl; return out;}#endif//只要简单的加上就好了,无视C++中的作用域规则,作用是防止头文件被重复包含28:#include <iostream> #include<fstream>#include<sstream>#include <string> #include <vector>#include<memory>#include<list>#include<map>#include<set>#include<iterator>#include<initializer_list>using namespace std; int main(int argc,char **argv) { ifstream in("1.txt"); string line; vector<string> vec1; while (getline(in,line)) { vec1.push_back(line); } for (size_t i = 0; i < vec1.size(); ++i) { cout<<vec1[i]<<endl; }//输出文本,做检验 map<string,set<int>> map1; string s; cout<<"请输入查找的单词(输入q退出):"; while((cin>>s) && (s != "q")) { for (size_t i = 0; i < vec1.size(); ++i) { istringstream word(vec1[i]); string m; while(word>>m) { if (s == m) { map1[s].insert(i); break; } } } cout<<s<<" occours "<<map1[s].size()<<" times "<<endl; auto it1 = map1[s].begin(); for (it1; it1 != map1[s].end(); ++it1) { cout<<" "<<"(line "<<*it1<<") "<<vec1[*it1]<<endl; } } return 0;}补充:利用lambda表达式,可以将while更好的表达,很有用的小技巧!!!
while([&]()->bool{cout<<"请输入查找的单词(输入q退出):";return (cin>>s) && (s != "q");}())29:do while()是先执行循环体再判断条件,while()是先判断条件再执行循环体,哪个在实际中逻辑更加符合,就用哪个。此题明显do while()更符合30:同27题
新闻热点
疑难解答
图片精选