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
解題思路
- 設置遍歷下標index用於順序遍歷字符串2,以便進行判等操作;
- 逆序遍歷字符串1進行入棧操作,每次入棧後,在結果字符串中追加 E 操作;
- 每次入棧之後,藉助while循環,對棧頂元素和字符串2當前的首字符進行判斷,如果兩者相等,那麼棧頂元素出棧,index後移,同時在結果字符串中追加 D 操作,這裏必須用while循環一直判斷到 棧空 或者棧頂元素和字符串2首字符不相等 爲止,單純的if判斷一次是不能解決問題的;
- 當字符串1遍歷結束之後,若棧不空,對棧內元素進行遍歷,思路與步驟3大致相同,但是當遍歷到棧頂元素與字符串2的首字符不相同時,直接跳出循環,這裏就很明顯的可以判定 字符串1不能通過E、D操作得到字符串2了,棧內只剩這點兒元素,但是還有不匹配的,那肯定不行了;
- 最後的輸出工作:若棧不空 就不能得到,若棧空,就是能得到,輸出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操作序列
}
}
}