本题唯一的难点在于如何处理输入的数据,代码中的注释可以很好的解释说明,如果看完代码还有些不懂,则可以看看代码下面的图文解释
import java.util.Scanner;
/**
* @author ComputerGod
*/
public class poj1363 {
private static Stack stack;
private static String[] arr;
private static int size;
private static String[] arr2;
public static void main(String[] args) {
control();
}
/**
* 核心思想,将顺序的序列与传入的序列进行对比,火车车厢是先进后出,符合栈的原理,
*由于火车一开始是顺序,入站后,经过排序而变为其他顺序的,故将顺序的序列先储入栈中,
* 然后与无序序列进行顺序比较,即无序序列从第一个数开始逐个比较,如果栈顶有无序序列中的数即弹出,
* 如果无则继续压栈,如果比到最后发现以无序序列的顺序进行比较,栈不为空,即证明该无序序列以有序序列排,
*根本做不到。
*/
public static void control(){
//创建StirngBuilder对象,将结果进行拼接。
StringBuilder stringBuilder = new StringBuilder();
//创建scanner对象,对控制台的数据进行扫描。
Scanner scanner = new Scanner(System.in);
while(true){
//size的值,即第一个值为火车车厢的个数,从而将栈,数组arr的大小进行初始化
String str = scanner.nextLine();
//这条语句则是判断0是否出现两次,若出现两次,说明判断结束
if (str.equals("0")) {
break;
}
//往下进行遍历,对传入的排序号码的可行性进行判断
while(true){
size = Integer.parseInt(str);
String str2 = scanner.nextLine();
//这里判断是否为0是为了结束区块,阻止往下运行,跳出当前while,重新更新size的值,执行下一个区块
if (str2.equals("0")){
break;
}
//运用String类中的split方法,将传入的排序序列分割成String数组
arr2 = str2.split(" ");
//这里根据size的大小初始化
arr = new String[size];
stack = new Stack(size);
//序号是从1到N的,实现有序序列
for (int i = 0; i < size; i++) {
arr[i] = (i + 1) + "";
}
//无序序列的索引
int index = 0;
//进行比对
for (int i = 0; i < size; i++) {
stack.push(arr[i]);
while (true) {
//如果栈为空即栈中没有元素,需要压入新的元素才能比对,故判断不能让栈为空才能比对
if (!stack.isEmpty()) {
if (arr2[index].equals(stack.getNowElm())) {
//如果比对的元素相同即弹栈
stack.pop();
//如果比对的元素相同即让无序序列往下一个元素走,比对下一个元素
index++;
}else{
break;
}
}else{
break;
}
}
}
stringBuilder.append(yesOrNo()+"\n");
}
stringBuilder.append("\n");
}
System.out.println(stringBuilder);
}
/**
* 该方法用于判断是否能排序,并返回yes或者no
* @return
*/
public static String yesOrNo(){
return stack.isEmpty() ? "Yes" : "No";
}
}
class Stack{
int size;
int front = -1;
String[] stack;
public Stack(int size) {
this.size = size;
stack = new String[size];
}
public boolean isEmpty(){
return front == -1;
}
public boolean isFull(){
return front == size - 1;
}
public void push(String num){
if (isFull()){
return;
}
front++;
stack[front] = num;
}
public void pop(){
if (isEmpty()){
return;
}
front--;
}
public String getNowElm(){
return stack[front];
}
}
有图有真相,用图来解释核心思想。
首先该题输入的数据为:
5 1 2 3 4 5 5 4 1 2 3 0 6 6 5 4 3 2 1 0 0
输出数据为:
Yes
No
Yes
注意:每一个区块处理完后都要换行输出一个空白行
我们要判断的数据是区块中的数据,数字n到0为一个区块,即:
5 6
1 2 3 4 5 和 6 5 4 3 2 1
5 4 1 2 3 0
0
区块中的数据即第一个数n到0之间的数据。
即:1 2 3 4 5
5 4 1 2 3
6 5 4 3 2 1
我们以 5 4 1 2 3 为例,用图的方式来进行说明
注意:
火车的车厢是一进去就不能往回走的,即火车编号一旦进栈,出栈后就不能重新进栈。

火车进站,直到车厢编号与需要处理的数据的编号相同时,停止加入

当加入的编号与需要处理数据的编号相同时,停止加入且出栈(即火车车厢出栈),此时index指向下一个需要处理的数据,判断是否与栈顶的数据相同如果相同,则出栈,往下继续判断,如果需要处理的数据的指针index指向最后一个并且最后一个也符合要求,即栈为空,返回Yes。如果不同就结束判断,此时栈不为空,返No;
接下来我们根据这个思路进行处理:

此时index指向的数据与栈顶的数据并不相同,所以结束判断 ,此时栈不为空,返回No
本文介绍了一个编程问题,通过Java实现栈来判断无序序列是否能按照给定顺序排列。核心思想是利用栈的先进后出特性,对比顺序序列和无序序列。

1574

被折叠的 条评论
为什么被折叠?



