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 << " }";
}