广义表 —— C++实现

广义表 —— 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;
		return ost;
  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值