一道堆栈的题

5 篇文章 0 订阅

假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,可以操作的序列称为合法序列,否则称为非法序列。

1) 下面所示的序列中哪些是合法的?

a. IOIIOIOO     b. IOOIOIIO     c. IIIOIOIO     d. IIIOOIOO

2) 通过对1)的分析,写出一个算法,判定所给的操作序列是否合法。若合法,返回 true,否则返回false(假定被判定的操作序列已存入一维数组中)。

 

解答: 
1) A、D合法,而B、C不合法。在B中,先入栈1次,再连续出栈2次,错误。在 C中,入栈和出栈次数不一致,会导致最终的栈不空。A、D均为合法序列,请自行模拟。注意:在操作过程中,入栈次数一定大于或等于出栈次数;结束时,栈一定为空。 

2) 设被判定的操作序列已存入一维数组A中。算法的基本设计思想:依次逐一扫描入栈出栈序列(即由"I"和"O"组成的字符串),每扫描至任一位置均需检查出栈次数(即 “O”的个数)是否小于入栈次数("I"的个数),若大于则为非法序列。扫描结束后,再判断入栈和出栈次数是否相等,若不相等则不合题意,为非法序列。

public class Main {
	public static void main(String[] args) {
		String str = "IIIOIOOOIOIO";
		char[] ch = str.toCharArray();
		
		int j = 0;
		
		for (int i=0;i<ch.length;i++) {
			if (ch[i] == 'I') {
				j++;
			} else {
				j--;
				if (j<0) {
					//说明出错了。
					System.out.print("非法序列");
					System.exit(0);
				}
			}
		}
		
		if (j!=0) {
			System.out.print("非法序列");
		} else {
			System.out.print("合法序列");
		}
	}
}

另解:入栈后,栈内元素个数加1;出栈时判断栈是否为空,为空说明非法序列。所有入栈出栈都操作完后,判断栈中是否还有未出栈的数据,如果有则为非法序列,否则说明合法。

#define StackSize 10
typedef char DataType;

//数组栈结构
typedef struct {
    DataType data[StackSize];
    int top;//栈顶位置
}SeqStack;

//顺序表栈
//置空栈
void initStack(SeqStack * s){
    s->top = -1;
}
//判栈空
bool stackEmpty(SeqStack * s){
    return s->top < 0;
}
//判栈满
bool stackFull(SeqStack * s){
    return s->top == StackSize-1;
}
//入栈
void push(SeqStack * s,DataType x){
    if (stackFull(s)) {
        printf("stack overflow");
    } else {
        s->top = s->top+1;
        s->data[s->top] = x;
    }
}
//出栈
DataType pop(SeqStack * s){
    if (stackEmpty(s)) {
        printf("stack is empty");
        exit(0);
    } else {
        return s->data[s->top--];
    }
}
//取栈顶元素(不改变栈顶指针)
DataType getTop(SeqStack * s){
    if (stackEmpty(s)) {
        printf("stack is empty");
        exit(0);
    } else {
        return s->data[s->top];
    }
}

int main(int argc, const char * argv[]) {
    char *p = "IOIIOIOO";
    SeqStack stack;
    //置空栈
    initStack(&stack);
    for (int i=0; i<strlen(p); i++) {
        if (p[i] == 'I') {
            //入栈
            push(&stack, 'I');
        } else {
            if (stackEmpty(&stack)) {
                cout << "非法序列" << endl;
                exit(0);
            } else {
                pop(&stack);
            }
        }
    }
    
    //判断栈是否已经清空了
    if (stackEmpty(&stack)) {
        cout << "合法序列" << endl;
    } else {
        cout << "非法序列" << endl;
    }
    return 0;
}

 

 

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值