广义表 —— C++ 实现
苦b南信带带二计软院本科生开始做数据结构作业辣!!
题目:编程实现 广 义 表:
A=(), B=(a,(b,c,d))
C=(e),D=(A,B,C,f)
(1)复制广义表B
(2)求广义表D深度。
欧K,开始应付作业8
什么?应付作业?那怎么能对得起大学辛苦的栽培!?还有严蔚敏奶奶辛苦写的课本!?
于是决定搞个 带 工 程
那么首先考虑的是从用户(开发人员)的角度,如何创建(初始化)广义表,b**du一下康康
char* tblstr = "(a,b,c,(d,e,f))";
table tbl = initTbl(tblstr);
康康题目D项,显然这样不行,因为不能用已存在的表去初始化新表。
那咋整???
诶,既然说要搞个带工程,干脆一步到位,于是想到了我们熟悉的printf:
int printf(const char *format, ...);
看到没,那仨点儿,这就让printf函数不仅能够接受任意个数的参数,还能够接受不同类型的参数。高级吧
这其实是C语言当中的 变 参 宏
是这样的,…只是一种语法,放在函数参数表中,表示该函数可以接受任意个数、类型的参数。众所周知,函数接受参数以后实参会被压进栈里,也就是按照一定的顺(栈)序(先进后出)被放在了一起。但这仅仅是使我们传参的时候能让函数接受可变个数的参数,那么我们如何将它们读取出来呢?
这里就要借助:
#include <cstdarg>
的帮助辣!!!\(>_<)/
头文件cstdarg为我们读取出那些可变的参数提供了工 具
啊,这里我们就不多讲,讲讲我们用到的几个:
va_list
va_start
va_arg
va_end
你会看到类似于printf、scanf这些函数在…之前都会有一个参数,这是必需的。为什么呢,我们知道,刚才也说了,函数实参会被压进栈,那么,倘若我们知道了第一个实参的地址,是否就可以顺 藤 摸 瓜找到下一个实参?Fortunately,这确实可行!
va_list相当于一种指针类型,在利用变参宏取参时,我们要先定义这个指针,例如:
va_list args; //va_list 标识符;
然后呢我们要对它进行初 始 化。但是仅仅将第一个函参的地址传给它是不行的,因为这一套工具的实现可能还涉及到更多的细节,于是我们用它提供的va_start进行初始化。例如,如果你的函数原型为:
void fun(type arg0, ...);
那么你应该写
va_start(args, arg0); //利用第一个参数 arg0 能够带来的相关有用线索去初始化实参读取指针args
初始化完了之后呢你就可以用va_arg通过这个指针读取参数了:
//假设你要读取一个int类型的参数赋值给变量a
int a;
a = va_arg(args, int); //通过变参读取指针 args 读取一个int参数
嗯,用完args这个指针之后别忘了调用
va_end(args);
去关闭这个指针。
欧K,要用到的变 参 宏我们废话就不多讲了。有了变参宏,我们就可以用类似于printf、scanf那样的方式去初始化一个广义表了:
/*
A=(),
B=(a,(b,c,d))
C=(e),
D=(A,B,C,f)
*/
tableZ<char_32bit> A("");
tableZ<char_32bit> B("%e, (%e, %e, %e)", 'a', 'b', 'c', 'd');
tableZ<char_32bit> C("%e", 'e');
tableZ<char_32bit> D("%t, %t, %t, %e", &A, &B, &C, 'f');
//类似于printf第一个参数“格式化控制字符串”, 我们定义构造函数的第一个参数为“层次化控制字符串”
//它包含以下要素:
//占位符%e 我们定义为 element, 此占位符接受一个数据元素
//占位符%t 我们定义为 table, 此占位符接受一个子表
//圆括弧 我们定义为新建与完结一个子表层次
诶,你看 char_32bit 是什么呀,顾名思义这是一个32位的字符类型。为啥要这样啊?因为。。。
哦霍,char在通过…的时候会自动升级(到int或者unsigned int)
为了解决这个问题我们不得不定义了一个
class char_32bit
{
protected:unsigned int value;
public:char_32bit& operator = (const char c)
{
value = (unsigned int)c;}
public:char_32bit& operator = (const char_32bit& another)
{
value = (unsigned int)another.value;}
public:char_32bit(const char c):value((unsigned int) c){
}
public:bool operator == (const char_32bit& another) const
{
return value == another.value;}
public:bool operator == (const char c) const
{
return value == (unsigned int)c;}
public:operator char (void) const
{
return (char)value;}
public:friend ostream& operator << (ostream& ost, const char_32bit& c)
{
ost<<(char)c.value;