【C语言】【数据结构】栈的应用(进制转换、括号匹配检验、行编辑程序、表达式求值)

栈的应用——进制转换、括号匹配检验、行编辑程序、表达式求值
顺序栈的基本操作

进制转换:对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数。

int main()
{
	SqStack S;
	int x, e;
	
	printf("输入一个非负的十进制整数:\n");
	if(InitStack(S) != 1) printf("Creatd Error!\n");
	scanf("%d", &x);
	while(x)
	{
		Push(S, x%8);
		x = x/8;
	}
	while(S.base != S.top)
	{
		Pop(S,e);
		printf("%d", e);
	}
}

括号匹配检验:假设表达式中允许包含两种括号:圆括号和方括号,其嵌套的顺序随意,即()或[([][])]等为正确的格式,[(]或([())或(()])均为不正确的格式。输入一个包含上述括号的表达式,检验括号是否配对。

void check()
{ // 对于输入的任意一个字符串,检验括号是否配对
	SqStack s;
	SElemType ch[80],*p,e;
	if(InitStack(s)) // 初始化栈成功
	{
		printf("请输入表达式\n");
		gets(ch);
		p=ch;
		while(*p) // 没到串尾
		switch(*p)
		{
			case '(':
			case '[':	Push(s, *p); p++;
						break; // 左括号入栈,且p++
			case ')':
			case ']':	if(!StackEmpty(s)) // 栈不空
						{
							Pop(s, e); // 弹出栈顶元素
							if(*p==')'&&e!='('|| *p==']'&&e!='[') 	
									// 弹出的栈顶元素与*p不配对
							{
								printf("isn't matched pairs\n");
								exit(ERROR);
							}
							else
							{
								p++;
								break; // 跳出switch语句
							}
						}
						else // 栈空
						{
							printf("lack of left parenthesis\n");
							exit(ERROR);
						}
			default:	p++; // 其它字符不处理,指针向后移
		}
		if(StackEmpty(s)) // 字符串结束时栈空
			printf("matching\n");
		else
			printf("lack of right parenthesis\n");
	}
}

行编辑程序:接受用户从终端输入的程序或数据,在输入过程中,允许用户输入出差错,并在发现有误时可以及时更正。例如:当用户发现刚刚键入的一个字符是错的时,可以补进一个退格符“#”,以表示前一个字符无效;如果发现当前键入的行内差错较多或难以补救,则可以键入一个退行符“@”,以表示当前行中的字符均无效。

void LineEdit()
{
	SqStack s;
	char ch,c;
	int n,i;
	InitStack(s);
	scanf("%d",&n);
	ch=getchar();		//把回车get了 
	for(i=1;i<=n;i++)
	{
		ch=getchar();
		while(ch!='\n')
		{
			switch(ch)
			{
				case '#':	Pop(s,c);
							break; 			// 仅当栈非空时退栈
				case '@':	ClearStack(s);
							break; 			// 重置s为空栈
				default :	Push(s,ch); 	// 有效字符进栈
			}
			ch = getchar();		 // 从终端接收下一个字符
		}
		StackTraverse(s,visit); 	// 将从栈底到栈顶的栈内字符输出
		ClearStack(s); 			// 重置s为空栈
	}
	DestroyStack(s);
}

表达式求值:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。要求输出表达式的值。

unsigned char op[7] = {'+', '-', '*', '/', '(', ')', '='};
unsigned char opcmp[7][7] = {'>', '>', '<', '<', '<', '>', '>',
 							'>', '>', '<', '<', '<', '>', '>',
 							'>', '>', '>', '>', '<', '>', '>',
 							'>', '>', '>', '>', '<', '>', '>',
 							'<', '<', '<', '<', '<', '=', ' ',
 							'>', '>', '>', '>', ' ', '>', '>',
 							'<', '<', '<', '<', '<', ' ', '='};

SqStack OPTR, OPND;		//OPTR寄存运算符,OPND寄存操作数或运算结果

Status In(char c, unsigned char op[])	//检验是否为运算符
{
	int i;
	for(i=0; i<7; i++)
	{
		if(c==op[i]) return OK;
	}
	return ERROR;
}

char Precede(char c1, char c2)		//比较两个相邻运算符的优先关系
{
	int i,j;
	for(i=0; i<7; i++)
		if(c1 == op[i]) break;
	for(j=0; j<7; j++)
		if(c2 == op[j]) break;
	return opcmp[i][j];
}

void Operate(char a1, char theta1, char b1)		//计算
{
	int i;
	char outcome;
	for(i=0; i<4; i++)
		if(theta1 == op[i]) break;
	switch(i)
	{
		case 0: outcome = a1 + b1 - '0'; break;
		case 1: outcome = a1 - b1 + '0'; break;
		case 2: outcome = (a1-'0') * (b1-'0') + '0'; break;
		case 3: outcome = (a1-'0') / (b1-'0') + '0'; break;
	}
	Push(OPND, outcome);
}

int main()
{
	char c, e, x, theta;
	char a, b;
	
	if(!InitStack(OPTR) || !InitStack(OPND)) printf("Created Error!\n");
	Push(OPTR, '=');
	c = getchar();
	while(c!='=' || GetTop(OPTR, e)!='=')
	{
		if(!In(c, op))
		{
			Push(OPND, c);
			c = getchar();
		}
		else
		{
			switch(Precede(GetTop(OPTR, e) , c))
			{
				case'<': Push(OPTR, c); c = getchar(); break;
				case'=': Pop(OPTR, x); c = getchar(); break;
				case'>': Pop(OPTR, theta); 
						Pop(OPND, b); Pop(OPND, a); 
						Operate(a, theta, b); break;
			}
		}
	}
	printf("%c", GetTop(OPND, e));
} 

你可能感兴趣的:(数据结构,C,数据结构,栈)