C++程序设计原理与实践 习题答案 第十二章 第12章习题答案

12.3

#include"../../std_lib_facilities.h"


void to_low(char* s)
{
	static const int dif = 'a' - 'A';

	while (*s != '\0')
	{
		if (*s >= 'A' && *s <= 'Z')
			*s += dif;
		s++;
	}
}

int main()
try
{
	char s[] = { "Hello, World!" };
	cout << s << endl;
	to_low(s);
	cout << s << endl;

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << endl;
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

12.4

#include<iostream>


char* mystrdup(const char* s)
//将C风格字符串复制到自由空间上分配的内存中
{
	size_t size{ 0 };
	while (s[size] != '\0')
		size++;
	char* dup_s = new char[size + 1];		//+1是给空字符0留位置
	char* temp_s = dup_s;
	while ((*temp_s = *s) != '\0')
	{
		temp_s++;
		s++;
	}
	return dup_s;
}

int main()
{
	char s[] = { "Hello, World!" };
	char* t = mystrdup(s);
	std::cout << s << std::endl;
	std::cout << t << std::endl;

	return 0;
}

12.5 字符串匹配,用到KMP算法

#include<iostream>

//这道题用了KMP算法

void build_match(const char* pattern, int* match)
{
	int m{ 0 };
	while (pattern[m] != '\0')
		m++;
	int i{ 0 }, j{ 0 };
	match[0] = -1;
	for (j = 1; j < m; ++j)
	{
		i = match[j - 1];
		while (i >= 0 && pattern[i + 1] != pattern[j])
			i = match[i];
		if (pattern[i + 1] == pattern[j])
			match[j] = i + 1;
		else
			match[j] = -1;
	}
}

char* findx(char* s, const char* x)
{
	int n{ 0 }, m{ 0 };
	while (s[n] != '\0')
		n++;
	while (x[m] != '\0')
		m++;
	if (n < m)
		return nullptr;
	int* match = new int[m];
	build_match(x, match);

	int i{ 0 }, j{ 0 };
	while (i < n && j < m)
	{
		if (s[i] == x[j])
		{
			++i;
			++j;
		}
		else if (j > 0)
			j = match[j - 1] + 1;
		else
			++i;
	}
	return (j == m) ? (s + i - m) : nullptr;
}

int main()
{
	char s[] = { "Hello, World!" };
	char x[] = "o,";
	char* t = findx(s, x);
	std::cout << s << std::endl;
	std::cout << t << std::endl;
}

12.6

#include"../../std_lib_facilities.h"

#define KB 1024

int main()
{
	double cnt{ 0 };
	while (1)
	{
		int* p = new int[4 *KB];
		cnt += 4 * KB;
		cout << "Allocated: " << cnt << endl;
	}
	return 0;
}

12.7

#include"../../std_lib_facilities.h"

#define MAX 100
int main()
{
	char* arr = new char[100];
	char* t;
	char ch;
	for (t = arr; cin.get(ch) && ch != '!'; *t++ = ch)
		continue;
	*t = '\0';
	cout << arr << endl;
	return 0;
}

12.8

#include"../../std_lib_facilities.h"

int main()
{
	string str;
	char ch;
	while (cin.get(ch) && ch != '!')
		str += ch;
	cout << str << endl;
	return 0;
}

12.9

#include"../../std_lib_facilities.h"

void stack_grow(int i)
{
	//利用递归的方法测试栈生长方向
	if (i > 3)
		return;
	int a{ 1 };
	int b{ 2 };
	cout << i << ':';
	cout << "\t&a == " << &a << endl;
	cout << "\t&b == " << &b << endl;
	stack_grow(i + 1);
}

void heap_grow(int i)
{
	//利用递归的方法测试栈生长方向
	if (i > 3)
		return;
	int* p = new int[100];
	cout << "p"<< i << ": " << p << endl;
	heap_grow(i + 1);
	delete[] p;
}

int main()
{
	//测试栈生长方向
	cout << "Growth director of stack\n";
	stack_grow(1);
	//测试自由空间生长方向
	cout << "Growth director of heap\n";
	heap_grow(1);

	return 0;
}

12.10

可以输入比数组分配的空间更多的字符,但可能会触发断点,我的编译器是VS2019。

#include"../../std_lib_facilities.h"

#define MAX 10
int main()
{
	char* arr = new char[MAX];
	char* t;
	char ch;
	for (t = arr; cin.get(ch) && ch != '!'; *t++ = ch)
		continue;
	*t = '\0';
	cout << arr << endl;
	return 0;
}

12.11

#include"../../std_lib_facilities.h"

class Link {
public:
	string value;
	
	Link(const string& v, Link* p = nullptr, Link* s = nullptr)
		:value{ v }, pred{ p }, succ{ s } { }

	Link* insert(Link* n);	//在此对象之前插入n
	Link* add(Link* n);		//在此对象之后插入n
	Link* erase();			//将此对象从链表中删除
	Link* find(const string& s);	//在链表中查找s
	const Link* find(const string& s) const;	//在const链表中查找s
	Link* advance(int n);		//在链表中移动n个位置
	Link* next() const { return succ; }
	Link* prev() const {return pred; }
private:
	Link* pred;
	Link* succ;
};


void print_all(Link* p);


int main()
try
{
	Link* norse_gods = new Link{ "Thor" };
	norse_gods = norse_gods->insert(new Link{ "Odin" });
	norse_gods = norse_gods->insert(new Link{ "Zeus" });
	norse_gods = norse_gods->insert(new Link{ "Freia" });
	cout << "Norse gods:\n";
	print_all(norse_gods);
	cout << '\n';

	Link* greek_gods = new Link{ "Hera" };
	greek_gods = greek_gods->insert(new Link{ "Athena" });
	greek_gods = greek_gods->add(new Link{ "Mars" });
	greek_gods->add(new Link{ "Poseidon" });
	cout << "greek gods:\n";
	print_all(greek_gods);
	cout << '\n';

	//修改战争之神的名字
	Link* p1 = greek_gods->find("Mars");
	if (p1)
		p1->value = "Ares";

	//将Zeus移到正确的神殿
	Link* p2 = norse_gods->find("Zeus");
	if (p2)
	{
		if (p2 == norse_gods)
			norse_gods = p2->advance(1);
		p2->erase();
		greek_gods->add(p2);
	}
	cout << "Norse gods:\n";
	print_all(norse_gods);
	cout << '\n';
	cout << "greek gods:\n";
	print_all(greek_gods);
	cout << '\n';

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << endl;
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

Link* Link::insert(Link* n)
//在此对象之前插入n
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	n->succ = this;
	n->pred = pred;
	if (pred)
		pred->succ = n;
	pred = n;
	return n;
}

Link* Link::add(Link* n)
//在此对象之后插入n
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	n->pred = this;
	n->succ = succ;
	if (succ)
		succ->pred = n;
	succ = n;
	return this;
}

Link* Link::erase()
//将此对象从链表中删除;返回该对象的后继
{
	if (this == nullptr)
		return nullptr;
	if (pred)
		pred->succ = succ;
	if (succ)
		succ->pred = pred;
	return succ;
}

Link* Link::find(const string& s)
//在链表中查找s
{
	Link* p = this;
	while (p)
		if (p->value == s)
			break;
		else
			p = p->succ;
	return p;
}

const Link* Link::find(const string& s) const
//在const链表中查找s
{
	const Link* p = this;
	while (p)
		if (p->value == s)
			break;
		else
			p = p->succ;
	return p;
}

Link* Link::advance(int n)
//在链表中移动n个位置
{
	Link* p = this;
	if (n < 0)
	{
		while (n++)
			p = p->pred;
	}
	else if (n > 0)
		while (n--)
			p = p->succ;
	return p;
}


//辅助函数
void print_all(Link* p)
{
	cout << "{ ";
	while (p)
	{
		cout << p->value;
		if (p = p->next())
			cout << ", ";
	}
	cout << " }";
}

12.12

两个版本分别用于非 const 链表和 const 链表。

12.13

#include"../../std_lib_facilities.h"

struct God {
	string name;
	string mythology;
	string mount;
	string weapon;
};

class Link {
public:
	God god;

	Link(const God& g, Link* p = nullptr, Link* s = nullptr)
		:god{ g }, pred{ p }, succ{ s } { }

	Link* insert(Link* n);	//在此对象之前插入n
	Link* add(Link* n);		//在此对象之后插入n
	Link* add_order(Link* n);	//按字典序将n放置在正确位置中
	Link* erase();			//将此对象从链表中删除
	Link* find(const string& s);	//在链表中查找s
	const Link* find(const string& s) const;	//在const链表中查找s
	Link* advance(int n);		//在链表中移动n个位置
	Link* next() const { return succ; }
	Link* prev() const { return pred; }
private:
	Link* pred;
	Link* succ;
};


void print_all(Link* p);


int main()
try
{
	Link* norse_gods = new Link{ God{"Thor", "Norse","",""} };
	norse_gods = norse_gods->add_order(new Link{ God{"Odin", "Norse","Eight-legged flying horse called Sleipner",""} });
	norse_gods = norse_gods->add_order(new Link{ God{"Freia", "Norse", "",""} });
	print_all(norse_gods);
	cout << '\n';

	Link* greek_gods = new Link{ God{"Hera","Greek","",""} };
	greek_gods = greek_gods->insert(new Link{ God{"Athena","Greek","",""} });
	greek_gods = greek_gods->add_order(new Link{ God{"Ares" ,"Greek", "", ""} });
	greek_gods->add_order(new Link{ God{"Zeus","Greek","",""} });
	greek_gods->add_order(new Link{ God{"Poseidon","Greek","","Trident"} });
	print_all(greek_gods);
	cout << '\n';

	

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << endl;
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

Link* Link::insert(Link* n)
//在此对象之前插入n
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	n->succ = this;
	n->pred = pred;
	if (pred)
		pred->succ = n;
	pred = n;
	return n;
}

Link* Link::add(Link* n)
//在此对象之后插入n
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	n->pred = this;
	n->succ = succ;
	if (succ)
		succ->pred = n;
	succ = n;
	return this;
}

Link* Link::add_order(Link* n)
//按字典序将n放置在正确位置中;返回在前的元素
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	Link* header = this;
	
	if (n->god.name < header->god.name)
	{
		n->pred = pred;
		n->succ = this;
		pred = n;
		header = n;
	}
	else if (n->god.name > header->god.name)
	{
		Link* p;
		for (p = this; p->succ && n->god.name > p->succ->god.name; p = p->next())
			continue;
		n->succ = p->succ;
		n->pred = p;
		if (p->succ)
			p->succ->pred = n;
		p->succ = n;
	}
	return header;
}

Link* Link::erase()
//将此对象从链表中删除;返回该对象的后继
{
	if (this == nullptr)
		return nullptr;
	if (pred)
		pred->succ = succ;
	if (succ)
		succ->pred = pred;
	return succ;
}

Link* Link::find(const string& name)
//在链表中查找s
{
	Link* p = this;
	while (p)
		if (p->god.name == name)
			break;
		else
			p = p->succ;
	return p;
}

const Link* Link::find(const string& name) const
//在const链表中查找s
{
	const Link* p = this;
	while (p)
		if (p->god.name == name)
			break;
		else
			p = p->succ;
	return p;
}

Link* Link::advance(int n)
//在链表中移动n个位置
{
	Link* p = this;
	if (n < 0)
	{
		while (n++)
			p = p->pred;
	}
	else if (n > 0)
		while (n--)
			p = p->succ;
	return p;
}


//辅助函数
void print_all(Link* p)
{
	cout << "{ ";
	God g;
	while (p)
	{
		g = p->god;
		cout << "( " << g.name << ", "
			<< g.mythology << ", "
			<< g.mount << ", "
			<< g.weapon << " )";
		if (p = p->next())
			cout << '\n';
	}
	cout << " }";
}

12.14

#include"../../std_lib_facilities.h"

class Link {
public:
	string value;

	Link(const string& v, Link* s = nullptr)
		:value{ v }, succ{ s } { }

	//Link* insert(Link* n);	//在此对象之前插入n,单项链表做不到
	Link* add(Link* n);		//在此对象之后插入n
	Link* erase(Link* header);			//将此对象从链表中删除
	Link* find(const string& s);	//在链表中查找s
	const Link* find(const string& s) const;	//在const链表中查找s
	Link* advance(int n);		//在链表中移动n个位置
	Link* next() const { return succ; }
	Link* prev(Link* header)const;
private:
	Link* succ;
};


void print_all(Link* p);


int main()
try
{
	Link* norse_gods = new Link{ "Thor" };
	norse_gods = norse_gods->add(new Link{ "Odin" });
	norse_gods = norse_gods->add(new Link{ "Zeus" });
	norse_gods = norse_gods->add(new Link{ "Freia" });
	cout << "Norse gods:\n";
	print_all(norse_gods);
	cout << '\n';

	Link* greek_gods = new Link{ "Hera" };
	greek_gods = greek_gods->add(new Link{ "Athena" });
	greek_gods = greek_gods->add(new Link{ "Mars" });
	greek_gods->add(new Link{ "Poseidon" });
	cout << "greek gods:\n";
	print_all(greek_gods);
	cout << '\n';

	//修改战争之神的名字
	Link* p1 = greek_gods->find("Mars");
	if (p1)
		p1->value = "Ares";

	//将Zeus移到正确的神殿
	Link* p2 = norse_gods->find("Zeus");
	if (p2)
	{
		if (p2 == norse_gods)
			norse_gods = p2->advance(1);
		p2->erase(norse_gods);
		greek_gods->add(p2);
	}
	cout << "Norse gods:\n";
	print_all(norse_gods);
	cout << '\n';
	cout << "greek gods:\n";
	print_all(greek_gods);
	cout << '\n';

	return 0;
}
catch (runtime_error& e)
{
	cerr << "Runtime error: " << e.what() << endl;
	return 1;
}
catch (...)
{
	cerr << "Exception occured!\n";
	return 2;
}

/*
Link* Link::insert(Link* n)
//在此对象之前插入n,单向链表做不到这点
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	n->succ = this;
	n->pred = pred;
	if (pred)
		pred->succ = n;
	pred = n;
	return n;
}
*/

Link* Link::add(Link* n)
//在此对象之后插入n
{
	if (n == nullptr)
		return this;
	if (this == nullptr)
		return n;
	n->succ = succ;
	succ = n;
	return this;
}

Link* Link::erase(Link* header)
//将此对象从链表中删除;返回该对象的后继
{
	if (this == nullptr || header == nullptr)
		return nullptr;
		
	Link* pred = prev(header);
	if (pred)
		pred->succ = succ;
	
	return succ;
}

Link* Link::find(const string& s)
//在链表中查找s
{
	Link* p = this;
	while (p)
		if (p->value == s)
			break;
		else
			p = p->succ;
	return p;
}

const Link* Link::find(const string& s) const
//在const链表中查找s
{
	const Link* p = this;
	while (p)
		if (p->value == s)
			break;
		else
			p = p->succ;
	return p;
}

Link* Link::advance(int n)
//在链表中移动n个位置
{
	Link* p = this;
	if (n < 0)
		error("advance: argument can not be negative");
	else if (n > 0)
		while (n--)
			p = p->succ;
	return p;
}

Link* Link::prev(Link* header) const
{
	if (this == nullptr || header == nullptr)
		return nullptr;
	if(header == this)
		return nullptr;
	Link* p;
	for (p = header; p->succ != this; p = p->succ)
		continue;
	return p;
}


//辅助函数
void print_all(Link* p)
{
	cout << "{ ";
	while (p)
	{
		cout << p->value;
		if (p = p->next())
			cout << ", ";
	}
	cout << " }";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值