Browse Source

learning cpp primer 5th

dengxinyi 7 years ago
parent
commit
5e5f30e500

BIN
c/C++Primer/ch12/chapter12


+ 16 - 0
c/C++Primer/ch12/chapter12.cpp

@@ -0,0 +1,16 @@
+#include "textquery.h"
+
+#include <iostream>
+
+using std::cin;
+using std::cout;
+using std::endl;
+using std::string;
+using std::vector;
+
+int main() {
+  std::ifstream ifs("novel.txt");
+  TextQuery t1 = TextQuery(ifs);
+  print(cout, t1.query("is"));
+  return 0;
+}

+ 7 - 0
c/C++Primer/ch12/compile.sh

@@ -0,0 +1,7 @@
+if [ x$1 == x ]; then
+    echo "usage \"$0 [cpp file name]\""
+    exit 1
+else
+    filename=$(basename $1 .cpp)
+    clang++ $filename.cpp -std=c++11 -O2 -Wall -o $filename
+fi

+ 29 - 0
c/C++Primer/ch12/novel.txt

@@ -0,0 +1,29 @@
+Henry led the way through the streets until we came to the anchorage basin beyond the docks.
+He was talkative enough, but my head ached from the blow I had received from the man of peace, and I paid little attention to the fellows words.
+
+We passed a large American ship that had been captured by the English during the war and sold.
+She loomed up grandly from the small craft lying near, her long, tapering masts still showing the unmistakable Yankee rigging, and her yards having yet a vestige of the white American cloth which has since been a pleasant feature of all our craft.
+Her paint was worn off, however, and upon her decks a mongre l crew chattered away like a pack of monkeys.
+I halted a moment and looked at her in disgust.
+
+"What ship is that?" I asked.
+
+The Independence of Boston.
+She were taken by the English line ship St. Marys off Cape St. Roque.
+She were stove up some.
+See that big piece spliced into her stern where she was shot 19away.
+Her mainyards fished in two places. Took two whole broadsides to fetch her to, they say.
+That trim-lookin craft beyond her is the one were headin fer, --the one laying head on with the foreyards cockbilled.
+
+We went toward the vessel indicated, and I soon saw what indeed appeared to be a fine craft. She was large, probably five hundred tons, but she was barque rigged, with her mainmast stepped well aft. Her foreyards were lifted to starboard and her main were braced to all angles, giving her the appearance of having been suddenly deserted by her crew after making port. Upon the spars the white canvas lay bent and furled, the clews standing out a foot or two clear of the bunt, and the gaskets hove in taut as brass bands. Her black sides showed a good freeboard, but I thought little of this, as nearly all vessels bound to the westward were going pretty light at that time. She was coppered, and the top band was a good half-fathom clear of the water. She was pierced for six guns on a side, and had several more ports painted along the bulwarks on the main-deck, as was the custom of the day. At a distance she might have been taken for a vessel of twenty or more guns. Her build was English, but her rig was Scandinavian, and I noticed her poop was painted white everywhere except on deck, after the Yankee fashion.
+
+20Three heavy boats were slung amidships on booms. Forward of these a galley was built or lashed upon the deck, and from its window appeared the black head of an African.
+We went close to the waters edge and Henry hailed.
+
+Th-war-bull-yah! Ahoy! he bellowed.
+
+Whats her name? I asked.
+
+Ha-Yah-Wah, ahoy! he bellowed again in answer, and the nigger in the galley waved a white rag in reply.
+
+May the sharks eat me, you dock wrastler, but thats a queer name for a fine ship! How do you call her? I asked.

+ 128 - 0
c/C++Primer/ch12/strblob.h

@@ -0,0 +1,128 @@
+#ifndef STRBLOB_H
+#define STRBLOB_H
+
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <memory>
+
+
+class StrBlobPtr;
+
+
+class StrBlob {
+friend class StrBlobPtr;
+
+public:
+  typedef std::vector<std::string>::size_type size_type;
+  StrBlob();
+  StrBlob(std::initializer_list<std::string> il);
+
+  void push_back(const std::string &s) { data->push_back(s); }
+  void pop_back();
+
+  std::string &front();
+  const std::string &front() const;
+  std::string &back();
+  const std::string &back() const;
+
+  StrBlobPtr begin();
+  StrBlobPtr begin() const;
+  StrBlobPtr end();
+  StrBlobPtr end() const;
+
+  size_type size() const { return data->size(); }
+  bool empty() const { return data->empty(); }
+private:
+  std::shared_ptr<std::vector<std::string>> data;
+  void check(size_type i, const std::string &msg) const;
+}; // !StrBlob
+
+// functions of StrBlob
+inline StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
+
+inline StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {}
+
+inline void StrBlob::check(size_type i, const std::string &msg) const {
+  if (i >= data->size())
+    throw std::out_of_range(msg);
+}
+
+inline const std::string &StrBlob::front() const {
+  check(0, "front on empty StrBlob");
+  return data->front();
+}
+inline std::string &StrBlob::front() {
+  check(0, "front on empty StrBlob");
+  return data->front();
+}
+
+inline const std::string &StrBlob::back() const {
+  check(0, "back on empty StrBlob");
+  return data->back();
+}
+inline std::string &StrBlob::back() {
+  check(0, "back on empty StrBlob");
+  return data->back();
+}
+
+
+class StrBlobPtr {
+public:
+  StrBlobPtr() : curr(0) {}
+  StrBlobPtr(StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) {}
+  StrBlobPtr(const StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) {}
+
+  std::string &deref() const;
+  StrBlobPtr &incr();
+
+  bool equal(const StrBlobPtr &);
+
+private:
+  std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string &msg) const;
+  std::weak_ptr<std::vector<std::string>> wptr;
+  std::size_t curr;
+}; // !StrBlobPtr
+
+// functions of StrBlobPtr
+inline std::string &StrBlobPtr::deref() const {
+  auto p = check(curr, "deref pass end");
+  return (*p)[curr];
+}
+
+inline StrBlobPtr &StrBlobPtr::incr() {
+  ++curr;
+  return *this;
+}
+
+inline bool StrBlobPtr::equal(const StrBlobPtr &sbp) {
+  return (*this).curr == sbp.curr;
+}
+
+inline std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string &msg) const {
+  auto ret = wptr.lock();
+  if (!ret)
+    throw std::runtime_error("unbound StrBlob");
+  if (i >= ret->size())
+    throw std::out_of_range(msg);
+  return ret;
+}
+
+// functions of StrBlob
+StrBlobPtr StrBlob::begin() {
+  return StrBlobPtr(*this);
+}
+StrBlobPtr StrBlob::begin() const {
+  return StrBlobPtr(*this);
+}
+
+StrBlobPtr StrBlob::end() {
+  return StrBlobPtr(*this, data->size());
+}
+StrBlobPtr StrBlob::end() const {
+  return StrBlobPtr(*this, data->size());
+}
+
+#endif // !STRBLOB_H

+ 80 - 0
c/C++Primer/ch12/textquery.h

@@ -0,0 +1,80 @@
+#ifndef TEXTQUERY_H
+#define TEXTQUERY_H
+
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <string>
+#include <memory>
+#include <map>
+#include <set>
+
+class QueryResult;
+
+class TextQuery {
+public:
+  using LineNo = std::vector<std::string>::size_type;
+
+  TextQuery() = default;
+  TextQuery(std::ifstream &);
+
+  QueryResult query(const std::string &) const;
+
+private:
+  std::shared_ptr<std::vector<std::string>> file;
+  std::map<std::string, std::shared_ptr<std::set<LineNo>>> wm;
+};
+
+TextQuery::TextQuery(std::ifstream &ifs) : file(new std::vector<std::string>) {
+  if (ifs) {
+    LineNo n(0);
+    for (std::string line; getline(ifs, line); ++n) {
+      file->push_back(line);
+      std::istringstream iss(line);
+      for (std::string text, word; iss >> text; word.clear()) {
+        std::remove_copy_if(begin(text), end(text), back_inserter(word), ispunct);
+        auto &lines = wm[word];
+        if (!lines)
+          lines.reset(new std::set<LineNo>);
+        lines->insert(n);
+      }
+    }
+  } else
+      throw std::runtime_error("cannot read file from fstream");
+}
+
+
+class QueryResult {
+friend std::ostream &print(std::ostream &, const QueryResult &);
+public:
+  QueryResult(const std::string &s,
+              std::shared_ptr<std::set<TextQuery::LineNo>> l,
+              std::shared_ptr<std::vector<std::string>> f) :
+    sought(s), lines(l), file(f) {}
+
+private:
+  std::string sought;
+  std::shared_ptr<std::set<TextQuery::LineNo>> lines;
+  std::shared_ptr<std::vector<std::string>> file;
+};
+
+std::ostream &print(std::ostream &os, const QueryResult &qr) {
+  os << "\"" << qr.sought << "\" is in " << qr.lines->size() << " lines.\n";
+  for (auto n : *qr.lines)
+    os << "\tno." << n + 1 << "\t: " << *(qr.file->begin() + n) << "\n";
+  return os;
+}
+
+QueryResult TextQuery::query(const std::string &s) const {
+  static std::shared_ptr<std::set<LineNo>> nodata(new std::set<LineNo>);
+  auto loc = wm.find(s);
+  if (loc == wm.end())
+    return QueryResult(s, nodata, file);
+  else
+    return QueryResult(s, wm.at(s), file);
+}
+
+
+#endif // !TEXTQUERY_H

+ 8 - 0
c/C++Primer/compile-run.sh

@@ -0,0 +1,8 @@
+if [ x$1 == x ]; then
+    echo "usage \"$0 [cpp file name]\""
+    exit 1
+else
+    filename=$(basename $1 .cpp)
+    clang++ $filename.cpp -std=c++11 -O2 -Wall -o $filename
+    ./$filename
+fi