5.栈的应用-数制转换和括号匹配

1.理论

前面说过了栈的应用非常之广,这主要得益于它后进先出的特性,程序设计中许多地方都用到了这一特性。

总的来说,使用栈可以将当前无法处理和无法确定的暂存到栈中,当满足某一个条件时再出栈,而且这个过程是可以迭代的。可以将栈的解决问题思路描述如下:要解决某个大问题,必须先解决一个小问题,暂时不能解决大问题则将大问题压栈,再着手解决小问题发现还要解决更小的问题,将这个小问题再压栈,再着手解决更小的问题,如此迭代下去,直到某个小问题是我们能够解决的,解决它,反向出栈一步步解决更大的问题直到解决大问题。

在这里,先使用栈完成两个简单应用:数制转换和括号匹配。

 2.数值转换

在计算过程中,常遇到将一种进制表达的数转换成另一种进制表达的数,这里我们完成将10进制转换成其它进制的功能。转换过程很简单,和我们实际手动计算一样,使用待转换的数对待转换成的进制求余,每次的余数入栈,直到整个数计算完成,这时候,反向出栈打印的结果为转换成的数。

实际程序如下

/**
 *功能:将一个10进制数转换成指定进制的数
 *参数:nNum--待转换的10进制数
 *	   nTo--要转换成的进制(如2、8、16)
 *	   pData--包含转换完成的数据的字符串
 *返回:无
 *其他:2014/04/15 By Jim Wen Ver1.0
**/
void Tansform(int nNum, const int nTo, char *pData)
{
	JWArray *pArray;
	int e;
	int i;

	//创建一个栈
	pArray = JWArrayCreate(20, 5);

	//不断地将nNum/nTo的余数压栈
	while (nNum)
	{
		JWArrayPush(pArray, (nNum%nTo));
		printf("%d", nNum%nTo);

		nNum = nNum / nTo;
	}

	//不断的出栈构成转换完成后的字符串数组
	i = 0;
	while(JWARRAY_FALSE == JWArrayIsEmpty(pArray))
	{
		JWArrayPop(pArray, &e);

		pData[i++] = (char)(e + 48);
	}
	pData[i] = '\0';

	JWArrayDestroy(pArray);
}

3.括号匹配

括号匹配在编译的语法分析、代码编辑器的自动匹配等地方都要用到。

这里我简化了括号匹配,计算一个指定字符串中匹配的括号对数,匹配不合法(缺少括号、括号不匹配等等)返回-1。依次读取字符串并和当前栈顶元素比较,左括号压栈,
右括号时匹配则弹出栈顶元素视为一次有效匹配,否则匹配不合法。最后检查栈是够为空,如果不为空则说明还有未匹配的括号,匹配不合法。

/**
 *功能:计算一个指定字符串中匹配的括号对数,匹配不合法(缺少括号、括号不匹配等等)返回-1
 *参数:pString--指定字符串中
 *返回:指定字符串中匹配的括号对数,匹配不合法(缺少括号、括号不匹配等等)返回-1
 *其他:2014/04/15 By Jim Wen Ver1.0
**/
int Match(char *pString)
{
	JWArray *pArray;
	int nMatchCount;
	int e;

	//创建一个栈
	pArray = JWArrayCreate(20, 10);

	//依次读取字符串并和当前栈顶元素比较,左括号压栈,
	//右括号时匹配则弹出栈顶元素视为一次有效匹配,否则匹配不合法
	nMatchCount = 0;
	while (pString[0] != '\0')
	{
		switch (pString[0])
		{
		case '{':
		case '[':
		case '(':
			JWArrayPush(pArray, (int)pString[0]);
			break;

		case '}':
			if (JWARRAY_FALSE == JWArrayGetTop(pArray, &e) || '{' != (char)e)//栈为空或不匹配
			{
				return -1;		//匹配不合法
			}
			else//匹配
			{
				JWArrayPop(pArray, NULL);

				nMatchCount++;
			}
			break;

		case ']':
			if (JWARRAY_FALSE == JWArrayGetTop(pArray, &e) || '[' != (char)e)//栈为空或不匹配
			{
				return -1;		//匹配不合法
			}
			else//匹配
			{
				JWArrayPop(pArray, NULL);

				nMatchCount++;
			}
			break;

		case ')':
			if (JWARRAY_FALSE == JWArrayGetTop(pArray, &e) || '(' != (char)e)//栈为空或不匹配
			{
				return -1;		//匹配不合法
			}
			else//匹配
			{
				JWArrayPop(pArray, NULL);

				nMatchCount++;
			}
			break;
		}

		pString += 1;
	}

	//最后检查栈不为空则匹配依然不合法
	if(JWARRAY_TRUE != JWArrayIsEmpty(pArray))
	{
		return -1;
	}

	JWArrayDestroy(pArray);

	return nMatchCount;
}


4.测试程序

测试程序界面如下


测试结果以对话框形式弹出

完整的源代码下载链接

原创,转载请注明来自http://blog.csdn.net/wenzhou1219


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值