个人认为,结合网上对《Essential c++》的评论,它不适合初学者:
(1)过于精炼,很多内容不会细讲
(2)中文版翻译较生硬,逻辑不够连贯清晰
(3)课后作业有答案,但是没提供网上可编译的源码(网站开梯无法访问),手敲完可能一堆BUG;或者是片段式的答案,即不是完整代码
看的我一脸懵,第5章的代码就不敲了,后续看情况
目录
4.1
4.2
4.3
要求
造轮子 -- stack
建立 stack.h 和 stack.cpp
编写 stack.cpp 函数,练习操作 Stack 的所有公开接口,并加以编译执行
在 stack.h 中定义 push(), pop(), peek()等函数
在 stack.cpp 中运用 Stack 类提供的接口,从标准输入设备依次读入一些字符串,并将它们 push 到 stack 中,直到读到文件末尾 (EOF),或是 stack 已满
代码
stack.h
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
#include
#include
#include
#include
using namespace std;
class Stack {
public:
bool push( const string& ); // 声明 push 函数,将字符串压入栈中
bool pop( string &elem ); // 声明 pop 函数,从栈中弹出字符串
bool peek( string &elem ); // 声明 peek 函数,获取栈顶元素
bool empty() const { return _stack.empty(); } // 判断栈是否为空
bool full() const { return _stack.size() == _stack.max_size(); } // 判断栈是否已满
int size() const { return _stack.size(); } // 获取栈中元素的数量
private:
vector _stack; // 栈的存储结构,使用 vector 实现
};
bool Stack::push( const string &elem ) {
if ( full() ) return false; // 如果栈已满,返回 false
_stack.push_back( elem ); // 向栈中添加元素
return true;
}
bool Stack::peek( string &elem ) {
if ( empty() ) return false; // 如果栈为空,返回 false
elem = _stack.back(); // 获取栈顶元素
return true;
}
bool Stack::pop( string &elem ) {
if ( empty() ) return false; // 如果栈为空,返回 false
elem = _stack.back(); // 获取栈顶元素
_stack.pop_back(); // 弹出栈顶元素
return true;
}
#endif // STACK_H_INCLUDED
stack.cpp
// stack.cpp
#include
#include
#include "stack.h"
using namespace std;
int main()
{
Stack st; // 创建一个 Stack 对象
string str;
while ( cin >> str && !st.full() ) // 当用户输入字符串且栈未满时,循环执行
st.push( str ); // 将读取的字符串压入栈中
if (st.empty()) { // 如果栈为空,则输出提示信息并返回 0
cout << '\n' << "no strings were read!\n";
return 0;
}
st.peek (str); // 获取栈顶元素,保存在 str 中
if (st.size() == 1 && str.empty()) { // 如果栈中只有一个元素且栈顶元素为空字符串,则输出提示信息并返回 0
cout << '\n' << "no strings were read\n";
return 0;
}
cout << '\n' << "Read in "<< st.size() << " strings!\n"
<< "The strings, in reverse order: \n"; // 输出读取的字符串总数和反序排列后的提示信息
while (st.size()) // 当栈不为空时,循环执行
if (st.pop(str)) // 从栈中弹出字符串,并输出
cout << str << ' ';
cout << '\n' << "There are now "<< st.size()
<< " elements in the stack!\n"; // 输出栈中剩余元素的数量
return 0;
}
输入输出
输入完后,换行,ctrl + Z,表示 EOF(Linux就ctrl + D)
A way a lone a last a loves a long the
^Z
Read in 11 strings!
The strings, in reverse order:
the long a loves a last a lone a way A
There are now 0 elements in the stack!
坑
count()函数的类内声明和类外实现,注意不要写成 bool,否则只会返回 occurs 1 times
要求
扩展 Stack 功能,以支持 find() 和 count() 两个操作
find() 会查看某值是否存在而返回 true 或 false
count() 返回某字符串出现次数
重新实现 4.1 的 .cpp,让它调用这2个函数
以同名的泛型算法来实现这两个函数
为了调用2个泛型算法,需要 global scope(全局作用域)运算符 ::
解释
::count()
表示调用全局命名空间中的count()
函数,而不是Stack
类中定义的同名函数。在这种情况下,::
作为区分局部函数和全局函数的作用域限定符,可以指定使用全局命名空间中的函数。如果没有加上::
,则编译器会根据它找到的第一个同名函数进行调用,这可能会导致意料之外的结果
代码
stack.h
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
#include
#include
#include
#include
using namespace std;
class Stack {
public:
bool push( const string& ); // 声明 push 函数,将字符串压入栈中
bool pop( string &elem ); // 声明 pop 函数,从栈中弹出字符串
bool peek( string &elem ); // 声明 peek 函数,获取栈顶元素
bool empty() const { return _stack.empty(); } // 判断栈是否为空
bool full() const { return _stack.size() == _stack.max_size(); } // 判断栈是否已满
int size() const { return _stack.size(); } // 获取栈中元素的数量
// 4.2 拓展
bool find( const string &elem ) const;
int count( const string &elem ) const;
private:
vector _stack; // 栈的存储结构,使用 vector 实现
};
bool Stack::push( const string &elem ) {
if ( full() ) return false; // 如果栈已满,返回 false
_stack.push_back( elem ); // 向栈中添加元素
return true;
}
bool Stack::peek( string &elem ) {
if ( empty() ) return false; // 如果栈为空,返回 false
elem = _stack.back(); // 获取栈顶元素
return true;
}
bool Stack::pop( string &elem ) {
if ( empty() ) return false; // 如果栈为空,返回 false
elem = _stack.back(); // 获取栈顶元素
_stack.pop_back(); // 弹出栈顶元素
return true;
}
// 4.2 拓展
bool Stack::find( const string &elem ) const
{
vector::const_iterator end_it = _stack.end();
return ::find(_stack.begin(), end_it, elem ) != end_it; // 全局作用域 ::
}
int Stack::count( const string &elem ) const
{
return ::count(_stack.begin(), _stack.end(), elem );
}
#endif // STACK_H_INCLUDED
stack.cpp
// stack.cpp
#include
#include
#include "stack.h"
using namespace std;
int main()
{
Stack st; // 创建一个 Stack 对象
string str;
while ( cin >> str && !st.full() ) // 当用户输入字符串且栈未满时,循环执行
st.push( str ); // 将读取的字符串压入栈中
if (st.empty()) { // 如果栈为空,则输出提示信息并返回 0
cout << '\n' << "no strings were read!\n";
return 0;
}
st.peek (str); // 获取栈顶元素,保存在 str 中
if (st.size() == 1 && str.empty()) { // 如果栈中只有一个元素且栈顶元素为空字符串,则输出提示信息并返回 0
cout << '\n' << "no strings were read\n";
return 0;
}
cout << '\n' << "Read in "<< st.size() << " strings!\n";
cin.clear(); // 清除 end-of-file 设定
cout << "what word to search for? ";
cin >> str;
bool found = st.find(str);
int count = found ? st.count(str) : 0;
cout << str << ( found ? " is " : " isn\'t " ) << "in the stack. ";
if (found)
cout << "It occurs "<< count << " times\n";
return 0;
}
输入输出
A way a lone a last a loved a long the
^Z
Read in 11 strings!
what word to search for? a
a is in the stack. It occurs 4 times
#include
using namespace std;
// 定义一个全局封装类 globalWrapper
class globalWrapper {
public:
// (静态成员函数)返回测试通过的数量
static int tests_passed() { return _tests_passed; }
// 返回已运行的测试数量
static int tests_run() { return _tests_run; }
// 返回版本号
static int version_number() { return _version_number; }
// 返回版本时间戳
static string version_stamp() { return _version_stamp; }
// 返回程序名称
static string program_name() { return _program_name; }
// 设置测试通过的数量
static void tests_passed(int nval) { _tests_passed = nval; }
// 设置已运行的测试数量
static void tests_run(int nval) { _tests_run = nval; }
// (静态成员函数)设置版本号
static void version_number(int nval) { _version_number = nval; }
// 设置版本时间戳
static void version_stamp(const string& nstamp) { _version_stamp = nstamp; }
// 设置程序名称
static void program_name(const string& npn) { _program_name = npn; }
private:
static string _program_name; // (静态成员变量)存储程序名称
static string _version_stamp; // 存储版本时间戳
static int _version_number; // 存储版本号
static int _tests_run; // 存储已运行的测试数量
static int _tests_passed; // 存储测试通过的数量
};
string globalWrapper::_program_name; // 初始化静态成员变量 _program_name
string globalWrapper::_version_stamp;
int globalWrapper::_version_number;
int globalWrapper::_tests_run; // 初始化静态成员变量 _tests_run
int globalWrapper::_tests_passed;