0
点赞
收藏
分享

微信扫一扫

算法27:最长回文子序列长度——范围模型

书呆鱼 2023-06-02 阅读 70

文章目录

练习18.11

what中如果抛出异常,需要try catch捕获,再调用what,一直循环,直达内存耗尽。

练习18.12

Query.h

#ifndef QUERY_H_
#define QUERY_H_

#include <string>
#include <iostream>
#include "Query_base.h"
#include "WordQuery.h"
#include "TextQuery.h"

namespace chapter15
{
	class Query
	{
		friend Query operator~(const Query&);
		friend Query operator|(const Query&, const Query&);
		friend Query operator&(const Query&, const Query&);
	public:
		Query(const std::string&);
		chapter10::QueryResult eval(const chapter10::TextQuery &t) const { return q->eval(t); }
		std::string rep() const { std::cout << "Query::rep()" << std::endl; return q->rep(); }
	private:
		Query(std::shared_ptr<Query_base> query) : q(query) { std::cout << "Query(std::shared_ptr<Query_base> query)" << std::endl; }
		std::shared_ptr<Query_base> q;
	};

	std::ostream& operator<<(std::ostream &os, const Query &query)
	{
		return os << query.rep();
	}

	inline Query::Query(const std::string &s) : q(new WordQuery(s)) { std::cout << "Query::Query(const std::string &s)" << std::endl; }
}

#endif

TextQuery.h

#ifndef TEXTQUERY_H_
#define TEXTQUERY_H_

#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
#include <algorithm>
#include <iterator>
#include "StrBlob.h"

namespace chapter10
{
	class QueryResult;

	class TextQuery
	{
	public:
		using line_no = std::vector<std::string>::size_type;
		TextQuery(std::ifstream&);
		QueryResult query(const std::string&) const;
	private:
		StrBlob file;
		std::map<std::string, std::shared_ptr<std::set<line_no>>> word_map;
	};

	class QueryResult
	{
		friend std::ostream& print(std::ostream&, const QueryResult&);
	public:
		QueryResult(std::string s, std::shared_ptr<std::set<TextQuery::line_no>> p, StrBlob f) : sought(s), lines(p), file(f) { }
		std::set<StrBlob::size_type>::iterator begin() const { return lines->begin(); }
		std::set<StrBlob::size_type>::iterator end() const { return lines->end(); }
		// std::shared_ptr<StrBlob> get_file() const { return std::make_shared<StrBlob>(file); }
		const StrBlob& get_file() const { return file; }
	private:
		std::string sought;
		std::shared_ptr<std::set<TextQuery::line_no>> lines;
		StrBlob file;
	};

	TextQuery::TextQuery(std::ifstream &ifs)
	{
		std::string text_line;

		while(std::getline(ifs, text_line))
		{
			file.push_back(text_line);
			int line_number = file.size() - 1;
			std::istringstream line(text_line);
			std::string text_word;
			while(line >> text_word)
			{
				std::string word;
				std::copy_if(text_word.begin(), text_word.end(), std::back_inserter(word), isalpha);
				// std::cout << word << std::endl;
				auto &wm_lines = word_map[word];
				if(!wm_lines)
					wm_lines.reset(new std::set<line_no>);
				wm_lines->insert(line_number);
			}
		}
	}

	QueryResult TextQuery::query(const std::string &sought) const
	{
		static std::shared_ptr<std::set<TextQuery::line_no>> nodata(new std::set<TextQuery::line_no>);
		auto loc = word_map.find(sought);
		if(loc == word_map.end())
			return QueryResult(sought, nodata, file);
		else
			return QueryResult(sought, loc->second, file);
	}

	std::ostream &print(std::ostream &os, const QueryResult &qr)
	{
		os << qr.sought << " occurs " << qr.lines->size() << " " /*<< make_plural(qr.lines->size(), "time", "s")*/ << std::endl;
		for(auto num : *qr.lines)
		{
			ConstStrBlobPtr p(qr.file, num);
			os << "\t(line " << num + 1 << ") " << p.deref() << std::endl;
		}
			
		return os;
	}
}

#endif

练习18.13

在需要在其所在的文件中可见,在其所在的文件外不可见时;
static只能用于变量与函数,不可用于用户自定义的类型。

练习18.14

namespace mathLib {
	namespace MatrixLib {
		class matrix { /* ... */ };
		matrix operator* (const matrix &, const matrix &);
		// ...
	}
}

请问你应该如何在全局作用域中声明该运算符?

mathLib::MatrixLib::matrix mathLib::MatrixLib::operator*(const matrix&, const matrix&);

练习18.15

using指示引入的名字的作用域远比using声明引入的名字的作用域复杂。它具有将命名空间成员提升到包含命名空间本身和using指示的最近作用域的能力。对于using声明来说,我们指示简单地领名字在局部作用域有效。

using指示是令整个命名空间的所有内容变得有效。通常情况下,命名空间中会含有一些不能出现在局部作用域的定义,因此using指示一般被看作是出现在最近的外层作用域中。

练习18.16

namespace Exercise {
	int ivar = 0;
	double dvar = 0;
	const int limit = 1000;
}
int ivar = 0;
//位置1
void main() {
	//位置2
	double dvar = 3.1416;
	int iobj = limit + 1;
	++ivar;
	++::ivar;
}
namespace Exercise{
	int ivar = 0;
	double dvar = 0;
	const int limit = 1000;
}
int ivar = 0;

using Exercise::ivar;	//1
using Exercise::dvar;
using Exercise::limit;

// using namespace Exercise;	//3

void mainp(){
	// using Exercise::ivar;	//2
	// using Exercise::dvar;
	// using Exercise::limit;

	// using namespace Exercise;	//4

	double dvar = 3.1416;
	int iobj = limit + 1;
	++ivar;
	++::ivar;
}

int main()
{
	return 0;
}

练习18.17

练习18.18

void swap(T v1, T v2)
{
	using std::swap;
	swap(v1.mem1, v2.mem1);
	//交换类型的其他成员
}

前者使用string版本的swap;后者使用实例化为int的swap。

练习18.19

将只使用标准库的swap,如果v1.mem1和v2.mem1为用户自定义类型,将无法使用用户定义的针对该类型的swap。

练习18.20

namespace primerLib {
	void compute();
	void compute(const void *);
}
using primerLib::compute;
void compute(int);
void compute(double, double = 3.4);
void compute(char*, char* = 0);
void f()
{
	compute(0);
}

候选函数:全部;
可行函数:
void compute(int)(最佳匹配)
void compute(double, double = 3.4)(int->double)
void compute(char*, char* = 0)(0->nullptr)
void compute(const void *)(0->nullptr)
改变后:
void compute(const void *)为最佳匹配。

举报

相关推荐

最长回文子序列

0 条评论