04-字符串序列的转换

2020年2月 TapTap × 心动网络的一个笔试题,原题记不太清了,只能回忆一下了。

题目回忆

给定两个字符串str1和str2,拿str1 = “asd”, str2 = “dsa” 举例。
str1的末尾字符取下,放到栈中,这个操作记为 E
判断栈顶元素是否与str2 的首字符相同,如果相同,那么栈顶元素出栈,这个操作记为 D
现在给定任意的两个字符串,需要判断字符串1能否通过合理的E、D操作得到字符串2,并将E、D操作序列输出。
规定每个字符串中没有相同的字符,每个字符都是唯一的。

样例1
input: asd dsa
output: EDEDED
样例2: 
input: qwert twerq
output: EDEEEDDDED

解题思路

  1. 设置遍历下标index用于顺序遍历字符串2,以便进行判等操作;
  2. 逆序遍历字符串1进行入栈操作,每次入栈后,在结果字符串中追加 E 操作;
  3. 每次入栈之后,借助while循环,对栈顶元素和字符串2当前的首字符进行判断,如果两者相等,那么栈顶元素出栈,index后移,同时在结果字符串中追加 D 操作,这里必须用while循环一直判断到 栈空 或者栈顶元素和字符串2首字符不相等 为止,单纯的if判断一次是不能解决问题的;
  4. 当字符串1遍历结束之后,若栈不空,对栈内元素进行遍历,思路与步骤3大致相同,但是当遍历到栈顶元素与字符串2的首字符不相同时,直接跳出循环,这里就很明显的可以判定 字符串1不能通过E、D操作得到字符串2了,栈内只剩这点儿元素,但是还有不匹配的,那肯定不行了;
  5. 最后的输出工作:若栈不空 就不能得到,若栈空,就是能得到,输出ED操作序列。

代码实现(Java)

import java.util.Scanner;
import java.util.Stack;

public class Main {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		String str1 = in.next();
		String str2 = in.next();
		// 字符串的合法性判断
		if (str1 == null || str2 == null) {
			System.out.print(-1);
		}
		// 借助StringBuffer,追加的时候比较方便
		// 相对于String而言节省内存
		StringBuffer res = new StringBuffer();
		Stack<Character> stack = new Stack<Character>();
		int len = str1.length();
		// 位置下标index用于对str2进行顺序遍历
		int index = 0;	
		// 逆序遍历str1
		for (int i = len - 1; i >= 0; i --) { 
			char ch = str1.charAt(i);	// 为了下面使用起来方便
			stack.add(ch);				// 入栈
			res.append('E');			// 完成 E 操作
			// 下面的while循环必须先对栈进行判空操作,
			// 栈空了再怎么比较也没意义,而且会报错
			while (!stack.isEmpty() && stack.peek() == str2.charAt(index)) {
				stack.pop();	 // 匹配 -- 栈顶元素出栈
				index ++;		 // 位置下标index递增,用于后面的匹配
				res.append('D'); // 完成 D 操作
			}
		}
		while(!stack.isEmpty()) { // 栈不空,继续判断剩下的
			if (stack.peek() == str2.charAt(index)) {
				stack.pop();
				index ++;
				res.append('D');
			}
			else {	// 只要出现不匹配,直接跳出就行了,肯定不能完成目标
				break;
			}
		}
		if (!stack.isEmpty()) {
			System.out.print("Error Operation");
		}else {
			System.out.print(res);	// 输出合法ED操作序列
		}
	}
}

你可能感兴趣的:(笔试踩的坑)