C语言练习-day25

题目:假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,可以操作的序列称为合法序列,否则称为非法序列,写一个算法,判定所给的操作序列是否合法。

输入:一个一维的字符型数组(由I和O组成),以‘0’为结束。

输出:判断出入栈的序列是否合法,输出结果。

优化目标:无。

算法思想:依次逐一扫描入栈出栈序列(即由“I”和”O“组成的字符串),每扫描至任意位置均需检查出栈次数(即"O"的个数)是否小于入栈次数(即”I“的个数),若大于则为非法序列。扫描结束后,再判断入栈和出栈次序是否相同,若不等为非法序列,反之为合法序列。

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20

//判断出入栈操作序列是否合法
int Judge(char A[]){
	int i = 0;
	int j,k;
	j = k = 0;
	while(A[i]!='\0'){
		switch (A[i]) {
			case 'I':
				j++;
				break;
			case 'O':
				k++;
				if(k>j){
					printf("序列非法!");
					return -1;
				}
		}
		i++;
	}
	if(j!=k){
		printf("序列非法!");
		return -1;
	}
	else{
		printf("序列合法!");
		return 0;
	}
}

//输入进出栈序列
void Input(char A[]){
	printf("请输入进出栈的顺序(以0为结束):");
	int i = 0;
	char ch;
	scanf("%c",&ch);
	while(ch!='0'&&i<20){
		A[i] = ch;
		i++;
		scanf("%c",&ch);
	}
	A[i] = '\0';
}


int main(){
	char A[MAXSIZE];
	Input(A);
	Judge(A);
	
	
}

题目:设单链表的表头指针为L,结点结构为data和next两个域构成,其中data域为字符型,试设计计算算法判断该链表的全部n个字符是否中心对称。例如xyx,xyyx都是中心对称。

输入:带头结点的链表个元素的值,类型为char,以‘0’结束。

输出:判断该单链表是否是中心对称,输出结果。

优化目标:无。

算法思想:用栈来判断链表中的数量是否中心对称。让链表的前一半元素依次进栈。在处理链表的后一半元素时,当访问到链表的一个元素后,就从栈中弹出一个元素。两个元素比较,若相等则将链表中的下一个元素与栈中再弹出的元素比较,直至链表到尾。这时若栈为空栈,则得出链表中心对称的结论;否则当链表中的一个元素与栈中弹出元素不等时,结论为链表非中心对称。

#include<stdio.h>
#include<stdlib.h>

typedef struct LNode{
    char data;
    struct LNode *next;
}LNode,*LinkList;

//判断单链表是否是中心对称
int dc(LinkList L,int n){
	int i;
	char s[n/2];
	LNode *p = L->next;
	for(i = 0;i<n/2;i++){
		s[i] = p->data;
		p = p->next;
	}
	i--;
	if(n%2 == 1){
		p = p->next;
	}
	while(p!=NULL&&s[i] == p->data){
		i--;
		p = p->next;
	}
	if(i == -1){
		return 1;
	}
	else{
		return 0;
	}
	
}

//创建链表
void creatList(LinkList &L,int &n){
    LNode *s,*r;
    n = 0;
    char x;
    printf("请输入链表元素值(以0结束):");
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;
    r = L;
    scanf("%c",&x);
    while(x!='0'){
        s = (LNode *)malloc(sizeof(LNode));
        s->data = x;
        r->next = s;
        s->next = NULL;
        r = s;
        n++;
        scanf("%c",&x);
    }
}

//输出链表
void PrintList(LinkList L){
    LNode *p = L->next;
    printf("链表元素有:");
    while(p!=NULL){
        printf("%c   ",p->data);
        p = p->next;
    }
    printf("\n");
}



int main() {
	LinkList L;
	int n;
	creatList(L,n);
	PrintList(L);
	printf("%d    \n",n);
	int k = dc(L,n);
	if(k == 1){
		printf("链表中心对称");
	}
	else{
		printf("链表不中心对称");
	}
	return 0;
}

题目:假设一个算术表达式中包括圆括号,方括号和花括号3种类型的括号,编写一个算法来判别表达式中的括号是否配对,以字符’\0‘作为算术表达式的结束符。

输入:一个一维的字符型数组(含括号算术表达式),以‘0’为结束。

输出:判断该算术表达式的括号使用是否合法,输出结果。

优化目标:无。

算法思想:扫描每一个字符。遇到花、中,园的左括号时进栈,遇到花、中、圆的右括号时检查栈顶元素是否是对应的左括号,若是,退栈,否则配对错误。最后栈若不为空也为错误(即左括号多了)。

#include<stdio.h>
#include<stdlib.h>

#define Maxsize 20
 
//顺序栈
typedef struct{
	char data[Maxsize];
	int top;
}SqStack;
 
//初始化
void InitStack(SqStack &S){
	S.top = -1;
}
 
//判空
int StackEmpty(SqStack S){
	if(S.top == -1){
		return 1;
	}
	else{
		return 0;
	}
}
 
//进栈
int Push(SqStack &S, char e){
	if(S.top == Maxsize-1){
		printf("栈已满!");
		return 0;
	}
	S.data[++S.top] = e;
	return 1;
	
}
 
//出栈
int Pop(SqStack &S, char &e){
	if(S.top == -1){
		printf("栈已空!");
		return 0;
	}
	e = S.data[S.top--];
	return 1;
}
 
//获取栈顶元素
int GetTop(SqStack S, char &e){
	if(S.top == -1){
		printf("栈已空!");
		return 0;
	}
	e = S.data[S.top];
	return 1;
}

//判断括号匹配是否成功
void BracketsCheck(char A[]){
	SqStack S;
	InitStack(S);
	int i = 0;
	char e;
	while(A[i]!='\0'){
		switch (A[i]) {
			case '(':
				Push(S,'(');
				break;
			case '[':
				Push(S,'[');
				break;
			case '{':
				Push(S,'{');
				break;
			case ')':
				Pop(S,e);
				if(e!='('){
					printf("括号匹配失败!\n");
					return;
				}
				break;
			case ']':
				Pop(S,e);
				if(e!='['){
					printf("括号匹配失败!\n");
					return;
				}
				break;
			case '}':
				Pop(S,e);
				if(e!='{'){
					printf("括号匹配失败!\n");
					return;
				}
				break;
			default:
				break;
		}
		i++;
	}
	if(!StackEmpty(S)){
		printf("括号匹配失败!\n");
	}
	else{
		printf("括号匹配成功!\n");
	}
	
}

//输入算术表达式
void Input(char A[]){
	printf("请输入算术表达式的顺序(以0为结束):");
	int i = 0;
	char ch;
	scanf("%c",&ch);
	while(ch!='0'&&i<20){
		A[i] = ch;
		i++;
		scanf("%c",&ch);
	}
	A[i] = '\0';
}


int main(){
	char A[Maxsize];
	Input(A);
	BracketsCheck(A);
	
}

题目:假设火车调度站的入口处有n节硬座和软座车厢(分别用H和S表示)等待调度,试编写算法,输出对这n节车厢进行调度的操作(即入栈和出栈操作)序列,以使所有的软座车厢都调整到硬座车厢之前。

输入:一个一维的字符型数组(由H和S组成),以‘0’为结束。

输出:将软座和硬座的车厢序列调整好后,输出调整好的车厢序列。

优化目标:无。

算法思想:所有的硬座车厢全部入栈,车道中的车厢均为软座车厢。此时将栈道内的车厢调度出来,调整到软座车厢之后。

#include<stdio.h>
#include<stdlib.h>

#define Maxsize 20
 
//顺序栈
typedef struct{
	char data[Maxsize];
	int top;
}SqStack;
 
//初始化
void InitStack(SqStack &S){
	S.top = -1;
}
 
//判空
int StackEmpty(SqStack S){
	if(S.top == -1){
		return 1;
	}
	else{
		return 0;
	}
}
 
//进栈
int Push(SqStack &S, char e){
	if(S.top == Maxsize-1){
		printf("栈已满!");
		return 0;
	}
	S.data[++S.top] = e;
	return 1;
	
}
 
//出栈
int Pop(SqStack &S, char &e){
	if(S.top == -1){
		printf("栈已空!");
		return 0;
	}
	e = S.data[S.top--];
	return 1;
}

//将全部软座车厢调整到硬座车厢之前
void Train_Arrange(char A[]){
	SqStack S;
	InitStack(S);
	char *p = A,*q = A,e;
	while(*p){
		if(*p == 'H'){
			Push(S,*p);
		}
		else{
			*(q++) = *p;
		}
		p++;
	}
	while(!StackEmpty(S)){
		Pop(S,e);
		*(q++) = e;
	}
}

//输入当前软座和硬座的顺序
void Input(char A[]){
	printf("请输入当前软座和硬座的顺序(以0为结束):");
	int i = 0;
	char ch;
	scanf("%c",&ch);
	while(ch!='0'&&i<20){
		A[i] = ch;
		i++;
		scanf("%c",&ch);
	}
	A[i] = '\0';
}

//输出当前软座和硬座的序列
void Print(char A[]){
	int i = 0;
	printf("数组中数值为:");
	while(A[i]!='\0'){
		printf("%c  ",A[i]);
		i++;
	}
	printf("\n");
}

int main(){
	char A[Maxsize];
	Input(A);
	Print(A);
	Train_Arrange(A);
	Print(A);
	
}

今日总结:今天做了几道栈的题,感觉栈的应用还是很广泛的,例如,洗干净的盘子总是逐个往上叠放在已经洗好的盘子上面,而用时从上往下逐个取用。在程序设计中,如果需要按照保存数据时相反的顺序来使用数据,则可以利用栈来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值