给定出栈序列和入栈序列,求出栈入栈顺序

亚马逊在线测评题:

大牛写的代码,学习一下编码风格

/* Enter your code here. Read input from STDIN. Print output to STDOUT */
import java.util.Scanner;
import java.util.StringTokenizer;

public class Solution 
{
	public String calculateOperationSequence(int[] originalArray, int[] resultArray) 
	{
		int[] numStackState = new int[originalArray.length];//0 have not pushed, 1 have pushed, 2 have poped
		for (int i = 0; i < numStackState.length; ++i) {
			numStackState[i] = 0;
		}
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < resultArray.length; ++i) {
			int indexInOriginal = -1;
			for (int j = 0; j < originalArray.length; ++j) {
				if (originalArray[j] != resultArray[i]) {
					if (numStackState[j] == 0) {
						result.append("push");
						result.append(originalArray[j]);
						result.append("|");
						numStackState[j] = 1;
					}
				} else if (originalArray[j] == resultArray[i]) {
					if (numStackState[j] == 0) {
						result.append("push");
						result.append(originalArray[j]);
						result.append("|");
						numStackState[j] = 1;
					} else if (numStackState[j] == 2) {
						return "None";
					}
					indexInOriginal = j;
					break;
				}
			}
			if (indexInOriginal == -1) {
				return "None";
			}
			for (int j = indexInOriginal + 1; j < originalArray.length; ++j) {
				if (numStackState[j] == 1) {
					return "None";
				}
			}
			result.append("pop");
			result.append(resultArray[i]);
			result.append("|");
			numStackState[indexInOriginal] = 2;
		}
		return result.substring(0, result.length() - 1);
	}

	
	
	/**
	* StringTokenizer的用法(有点类似于split)
	 一、构造函数。
	1. StringTokenizer(String str) :构造一个用来解析str的StringTokenizer对象。java默认的分隔符是“空格”、“制表符(‘\t’)”、“换行符(‘\n’)”、“回车符(‘\r’)”。
	2. StringTokenizer(String str, String delim) :构造一个用来解析str的StringTokenizer对象,并提供一个指定的分隔符。
	3. StringTokenizer(String str, String delim, boolean returnDelims) :构造一个用来解析str的StringTokenizer对象,并提供一个指定的分隔符,同时,指定是否返回分隔符。
	
	二、方法。
	说明:
	1. 所有方法均为public;
	2. 书写格式:[修饰符] <返回类型> <方法名([参数列表])>
	如:static int parseInt(String s) 表示:此方法(parseInt)为类方法(static),返回类型为(int),方法所需参数为String类型。
	1. int countTokens() :返回nextToken方法被调用的次数。如果采用构造函数1和2,返回的就是分隔符数量(例2)。
	2. boolean hasMoreTokens() :返回是否还有分隔符。
	3. boolean hasMoreElements() :结果同2。
	4. String nextToken() :返回从当前位置到下一个分隔符的字符串。
	5. Object nextElement() :结果同4。
	6. String nextToken(String delim) :与4类似,以指定的分隔符返回结果。
	* @param args
	*/
	public static void main(String[] args) 
	{
		Solution solution = new Solution();
		Scanner scanner = new Scanner(System.in);  //当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象。如果要获取输入的内容,则只需要调用Scanner的nextLine()方法即可。

		
		while (scanner.hasNextLine()) 
		{
			String strLine1 = scanner.nextLine();
			StringTokenizer stringTokenizer1 = new StringTokenizer(strLine1);
			
			//Initialize the original array
			int arrayLength = stringTokenizer1.countTokens();
			int[] originalArray = new int[arrayLength];
			for(int i = 0; i < arrayLength; i++)
			{
				originalArray[i] = Integer.parseInt(stringTokenizer1.nextToken());
			}
			
			//Initialize the result array
			String strLine2 = scanner.nextLine();
			StringTokenizer stringTokenizer2 = new StringTokenizer(strLine2);
			arrayLength = stringTokenizer2.countTokens();
			int[] resultArray = new int[arrayLength];
			for(int j = 0; j < arrayLength; j++)
			{
				resultArray[j] = Integer.parseInt(stringTokenizer2.nextToken());
			}
			
			String operationSequence = solution.calculateOperationSequence(originalArray, resultArray);
			System.out.println(operationSequence);
		}
	}
}

 

 

自己写的一个实现函数:

	private String calculateOperationSequence(int[] originalArray, int[] resultArray){
		StringBuffer rs = new StringBuffer();
		
		int[] numStackState = new int[originalArray.length];
		for(int i=0 ; i<numStackState.length ; i++){
			numStackState[i] = 0;
		}
		
		for(int i=0 ; i<resultArray.length ; ++i){
			for(int j=0 ; j<originalArray.length ; ++j){
				if(resultArray[i] != originalArray[j]){
					if(numStackState[j] == 0){
						numStackState[j]=1;
						rs.append("Push:"+originalArray[j]+";");
					}
				}else if(resultArray[i] == originalArray[j]){
					if(numStackState[j] == 0){
						rs.append("Push:"+originalArray[j]+";");
						rs.append("Pop:"+originalArray[j]+";");
						numStackState[j]=2;
						break;
					}else if(numStackState[j] == 1){
						if(numStackState[j+1] == 1){
							rs.append("出栈顺序不合法");
							return rs.toString();
						}else{
							rs.append("Pop:"+originalArray[j]+";");
							numStackState[j]=2;
							break;
						}
					}else{
						rs.append("出栈顺序不合法");
						return rs.toString();
					}
				}
			}	
		}
		
		return rs.toString();
	}

 

根据的先进后出的特性,一个序列是否为合法的出栈序列,必须满足以下条件: 1. 任意时刻,中的元素序列必须与给定序列相同或包含于序列中。 2. 出栈顺序必须与顺序相同或者为其逆序。 具体的判断步骤如下: 1. 定义一个一个指向出栈序列的指针(初始值为0)。 2. 遍历序列中的每一个元素,将其依次压中。 3. 在每次压元素后,判断顶元素是否等于出栈序列的第一个元素,如果相等,则将顶元素弹出,将出栈序列的指针后移一位,继续比较下一个元素。 4. 如果最终为空,并且出栈序列的指针指向了序列的末尾,说明该出栈序列合法,否则不合法。 以下是Python代码实现: ```python def is_valid_stack_sequence(push_seq, pop_seq): stack = [] pop_index = 0 for num in push_seq: stack.append(num) while stack and stack[-1] == pop_seq[pop_index]: stack.pop() pop_index += 1 return not stack and pop_index == len(pop_seq) ``` 以下是C语言代码实现: ```c #include <stdio.h> #include <stdbool.h> #define MAX_SIZE 100 bool is_valid_stack_sequence(int push_seq[], int push_len, int pop_seq[], int pop_len) { int stack[MAX_SIZE], top = -1; int pop_index = 0; for (int i = 0; i < push_len; i++) { stack[++top] = push_seq[i]; while (top >= 0 && stack[top] == pop_seq[pop_index]) { top--; pop_index++; } } return top == -1 && pop_index == pop_len; } int main() { int push_seq[] = {1, 2, 3, 4, 5}; int pop_seq[] = {4, 5, 3, 2, 1}; int push_len = sizeof(push_seq) / sizeof(push_seq[0]); int pop_len = sizeof(pop_seq) / sizeof(pop_seq[0]); if (is_valid_stack_sequence(push_seq, push_len, pop_seq, pop_len)) { printf("The pop sequence is valid.\n"); } else { printf("The pop sequence is invalid.\n"); } return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值