⭐题目描述
【问题描述】
商品货架可以看成一个栈,栈顶商品的生产日期最早,栈底商品的生产日期最近。上货时,需要倒货架,以保证生产日期较近的商品在较下的位置。
【基本要求】
针对一种特定商品,实现上述管理过程。
⭐整体思路
整体思路:
- 存货:输入入货商品的总个数,再输入生产日期,把生产日期一个个进栈,全部进完栈之后再快排。
- 取货:判断取货个数是否大于库存个数,若是,则重新输入,若否,则出货。
存货:
为了方便观察,我们先用数字代替生产日期。
例如:3 1 2 5 4(数字小的相当于生产日期早的)
1.3入栈。
2.1入栈。
3.2入栈。
4.5入栈。
5.4入栈,再快排,快排之后5在栈底,5上面是4,4上面是3,3上面是2,栈顶是1。
最后从栈底到栈顶的元素一次为5 4 3 2 1。
取货:
- 先判断取货数是否小于库存数,是则开始取货,否则重新输入。
- 假定取货数为2,取到的第一个数为1,此时栈1的位置变为0。
- 取到的第二个数为2,此时栈2的位置变为0。
以此类推!
⭐代码详情
所有的类都放在同一个包下(大佬略过)
排序方法用堆排序也许更好,因为快排更适合无序状态下的排序。
🍓存放货物代码
import java.util.Scanner;
import static ch01.stack.element;
import static ch01.stack.maxsize;
public class save {
Scanner sc = new Scanner(System.in);
boolean mark = false; //跳出异常标志
int y, m, d;
public void operate(int k,int sum){
for (int i = k; i < sum; ) {
System.out.println("请输入第" + (i + 1) + "件商品的生产日期(输入格式为2xxx/xx/xx):");
do {
String s = sc.next(); //输入日期 格式为2020/3/21
String[] array = s.split("/"); // 以/为分隔符,提取年月日
try {
y = Integer.parseInt(array[0]); //转换为int型
m = Integer.parseInt(array[1]);
d = Integer.parseInt(array[2]);
mark = true;
} catch (Exception e) {
System.out.println("输入有误,请重新输入(输入格式为2xxx/xx/xx)。");
continue;
}
ch01.data rq01 = new ch01.data(y, m, d);
if (rq01.whether(y, m, d)) {
stack.push(rq01.print());
i++;
} else {
System.out.println("输入有误,请重新输入(请检查输入日期是否正确):");
mark = false;
}
} while (!mark);
}
quickSort.quicksort02(element,maxsize);
whether.operate();
}
}
🍓快排代码
public class quickSort {
//一趟快速排序(以左侧记录作为枢轴)
public static int partition(int[] arr,int high,int low){ //待排序序列,排序的范围
int temp=arr[high]; //暂存枢轴
while(low!=high){ //开始分割
while(high<low&arr[low]<=temp){
low--;
}
if(high<low){
arr[high]=arr[low];
high++;
}
while(high<low&arr[high]>=temp){
high++;
}
if(high<low){
arr[low]=arr[high];
low--;
}
}
arr[high]=temp;
return high;
}
//递归快速排序
public static void quickSort01(int[] arr,int high,int low){
int pivot;
if(high<low){
pivot=partition(arr,high,low); //一次划分,返回枢轴位置
quickSort01(arr,high,pivot-1); //对枢轴左边一半快速排序
quickSort01(arr,pivot+1,low); //对枢轴右边一半快速排序
}
}
//快速排序的接口函数
public static void quicksort02(int[] arr,int size){ //待排序序列,序列大小
quickSort01(arr,0,size-1);
}
}
🍓栈操作代码
public class stack {
static int maxsize=1;
static int top=0;
static int[] element;
public static void create() { //创建栈
element = new int[maxsize];
}
public static void push(int n){ //入栈
if(top==maxsize){
resize();
}
element[top++]=n;
}
public static void pop(int n) { //出栈
if (n > 0) {
for (int i = 0; i < n; i++) {
System.out.print(element[--top] + " ");
element[top] = 0; //已经出栈的位置的元素变为0
}
System.out.println();
}
whether.operate();
}
public static void resize(){ //扩容
maxsize*=2;
int []newArr=new int[maxsize];
System.arraycopy(element,0,newArr,0,element.length);
element=newArr;
}
}
🍓操作选择代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class whether {
static String inputStr;
static int k=0;
static int sum=0;
static int n = 0;
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static int a;
static int b;
static int c;
public static void operate(){
boolean mark = false;
do {
try {
System.out.println("请输入你要进行的操作:");
System.out.println("1、存放商品");
System.out.println("2、取出商品");
System.out.println("0、退出");
inputStr = in.readLine();
a = Integer.parseInt(inputStr);
if (a < 0 | a > 2) {
throw new Exception();
}if(a==0){
System.out.println("退出成功!");
break;
}if(a==1){
k+=n-c; //更新存入商品的位置
c=0; //更新总取出的商品个数
do {
try {
System.out.println("请输入你要存放的货品个数:");
inputStr = in.readLine();
n = Integer.parseInt(inputStr);
if (n < 0) {
throw new Exception();
}
if(n==0){
System.out.println("你没有添加新商品。");
}
mark = true;
} catch (Exception e) {
System.out.println("输入有误!!!请输入一个正整数!");
}
} while (!mark);
sum+=n; //更新总的商品个数
save s=new save();
s.operate(k,sum);
}if(a==2){
do {
try {
System.out.println("请输入你要取出的商品个数:");
inputStr = in.readLine();
b = Integer.parseInt(inputStr);
if (b < 0|b>sum) {
throw new Exception();
}
if(b==0){
System.out.println("你没有取出商品。");
}
sum-=b; //更新总商品个数
mark = true;
c+=b; //计算商品取出个数
} catch (Exception e) {
System.out.println("输入有误!!请输入一个不大于库存个数的整数。目前库存还有"+sum+"件。");
}
} while (!mark);
stack.pop(b);
}
mark = true;
} catch (Exception e) {
System.out.println("输入有误!!!请输入一个正整数!");
}
} while (!mark);
}
}
🍓日期处理代码
public class data {
int year = 2000; //初始化日期
int month = 1;
int day = 1;
int[] month01 = new int[] {1, 3, 5, 7, 8, 10, 12}; //大月
int k = 0; //判断大小月
public int print() {
return year *(10*10*10*10)+month*(10*10)+day; //把2xxx/xx/xx变成2xxx xx xx(无空格)
}
//判断日期转换前后是否一致
public boolean whether(int year, int month, int day) {
return this.year == year &this.month == month &this.day == day;
}
//将日期转为合法日期
public data(int year, int month, int day) {
if (year > 0 && year < 3000) { //年份在1-2999
this.year = year;
if (month > 0 && month < 13) //月份在1-12
this.month = month;
//判断是否为大月
for (int j : month01)
if (month == j) {
k = 1;
break;
}
if (k == 1 && day > 0 && day < 32) //大月
this.day = day;
else if (k == 0 && month != 2 && day > 0 && day < 31) //小月
this.day = day;
else if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) {
if (day > 0 && day < 30) //闰年2月
this.day = day;
} else if (day > 0 && day < 29) //平年2月
this.day = day;
}
}
}
🍓程序入口代码
public class test {
public static void main(String[] args) {
stack.create();
whether.operate();
}
}
⭐运行结果
🍌运行结果一
🍌 运行结果二
🍌 运行结果三