题解 | #自动售货系统#
自动售货系统
https://www.nowcoder.com/practice/cd82dc8a4727404ca5d32fcb487c50bf
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
int[][] a1 = new int[][] { { 1, 2, 0 }, { 2, 3, 0 }, { 3, 4, 0 },
{ 4, 5, 0 }, { 5, 8, 0 }, { 6, 6, 0 }
};
int[][] a2 = new int[][] { { 1, 0 }, { 2, 0 }, { 5, 0 }, { 10, 0 } };
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringBuffer bu = new StringBuffer();
String rTip = "S001:Initialization is successful\n";
String[] pTips = { "S002:Pay success,balance=",
"E002:Denomination error\n",
"E003:Change is not enough, pay fail\n",
"E005:All the goods sold out\n"
};
String[] bTips = { "S003:Buy success,balance=",
"E006:Goods does not exist\n", "E007:The goods sold out\n",
"E008:Lack of balance\n"
};
String cTip = "E009:Work failure\n";
String qTip = "E010:Parameter error\n";
String a = null;
try {
a = in.readLine();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
int i = 0, j, l = a.length(), pMon, index = 0, indexM = 0, b = 0;
int[] cCnt = null;
boolean boolen2;
char[] chrAy = new char[l];
char[] chrAySub;
a.getChars(0, l, chrAy, 0);
int[][] comm = init(chrAy, l);
for (i = 0; i < comm.length; i++) {
chrAySub = new char[comm[i][1]];
System.arraycopy(chrAy, comm[i][0], chrAySub, 0, comm[i][1]);
switch (chrAySub[0]) {
case 'r'://初始化
rFunc(chrAySub, a1, a2);
bu.append(rTip);// 初始化成功信息
break;
case 'p':
pMon = getPMoney(chrAySub);
index = pFunc(a1, a2, pMon);
b = index == 0 ? b + pMon : b;// 投币余额
bu.append(index == 0 ? pTips[index] + b + "\n" :
pTips[index]);//投币余额放入输入信息
break;
case 'b':
boolen2 = bIfBuy(chrAySub);
indexM = bGetM(chrAySub, a1);
if (!boolen2)
index = 1;
else if (a1[indexM][2] == 0)
index = 2;
else if (b < a1[indexM][1]) {
index = 3;
} else {
index = 0;
a1[indexM][2]--;// 该商品数量-1
b -= a1[indexM][1];
}
bu.append(index == 0 ? bTips[index] + b + "\n" : bTips[index]);
break;
case 'c':
if (b == 0)
bu.append(cTip);
else {
cCnt = cFunc(a2, b);
b = 0;
for (j = 0; j < cCnt.length; j++) {
bu.append(a2[j][0] + " yuan coin number=" + cCnt[j])
.append("\n");
}
}
break;
case 'q':
if (chrAySub.length != 3)
bu.append(qTip);
else if (chrAySub[2] == '0') {
Arrays.sort(a1, new Comparator<int[]>() {//按数量排序
public int compare(int[] i1, int[] i2) {
return i2[2] - i1[2];
}
});
for (j = 0; j < a1.length; j++) {
index = a1[j][0];
bu.append("A" + index + " " + a1[j][1] + " " + a1[j][2]
+ "\n");
}
} else if (chrAySub[2] == '1') {
for (j = 0; j < a2.length; j++) {
bu.append(a2[j][0] + " yuan coin number=" + a2[j][1]
+ "\n");
}
}
break;
}
}
System.out.print(bu);
}
// 将输入字符串命令分割为命令个数数组,第一列存放一条命令的开始初始索引,第二列存放命令长度
static int[][] init(char[] chrAy, int l) {
int i = 0, j = 0, index = 0, commCnt = 0;
for (; i < l; i++) {
if (chrAy[i] == ';')
commCnt++;
}
int[][] indeAndLen = new int[commCnt][2];
for (i = 0; i < l; i++) {
if (chrAy[i] == ';') {
indeAndLen[j][0] = index;
indeAndLen[j][1] = i - index;//该条命令的长度
index = i + 1;//分号后一位为下一条命令开始
j++;
}
}
return indeAndLen;
}
// 执行r初始化商品和钱币的数量
static void rFunc(char[] chrArr, int[][] arr1, int[][] arr2) {
int i = 2, j = 0, l = chrArr.length, n = 0;
boolean transfer = false;// 是否是钱币的数量
for (; i < l; i++) {
if (chrArr[i] == '-') {
if (transfer)
arr2[j++][1] = n;
else
arr1[j++][2] = n;
n = 0;
} else if (chrArr[i] == ' ') {
arr1[j++][2] = n;
n = 0;
j = 0;
transfer = true;
} else {
n *= 10;
n += chrArr[i] - '0';
if (i == l - 1)
arr2[j][1] = n;
}
}
}
// 获得投入的钱币的值
public static int getPMoney(char[] chrArr) {
int i = 1, l = chrArr.length, mon = 0;
for (; i < l; i++) {
if (chrArr[i] == ' ')
continue;
mon *= 10;
mon += chrArr[i] - '0';
}
return mon;
}
// 投入钱币的成功与否判断
static int pFunc(int[][] a1, int[][] a2, int mon) {
int i = 1, l = 0, index = 0, sum1And2 = 0, stuffCnt = 0;
boolean monHas = false;
for (i = 0; i < a1.length; i++) {
stuffCnt += a1[i][2];// 剩余商品数量
}
l = a2.length;
i = 0;
for (; i < l; i++) {
if (mon == a2[i][0]) {
monHas = true;
break;// 记录钱币在钱币数组a2中的索引
}
}
sum1And2 = a2[0][0] * a2[0][1] + a2[1][0] *
a2[1][1];// 剩余1元和2元的总钱数
if (!monHas)
index = 1;// 将投入的该钱币退出
else if ((mon == a2[2][0] || mon == a2[3][0]) && sum1And2 < mon) {
index = 2;// 将投入的该钱币退出
} else if (stuffCnt == 0) {
index = 3;// 将投入的该钱币退出
} else {
a2[i][1]++;// 该面值的钱币数量+1
}
return index;
}
// 判断该商品是否能够购买
static boolean bIfBuy(char[] chrArr) {
int l = chrArr.length;
return chrArr[l - 2] == 'A'
&& (chrArr[l - 1] - '0' | '6' - chrArr[l - 1]) > 0;
}
// 获得商品的索引
static int bGetM(char[] chrArr, int[][] a1) {
int i = 0, l = chrArr.length;
int ind = chrArr[l - 1] - '0';
for (; i < a1.length; i++) {
if (ind == a1[i][0])
break;
}
return i;
}
static int[] cFunc(int[][] a2,
int mon) {// 数组初始化只能在方法外部,要么返回该数组
int l = a2.length, i = l - 1, j, monE;
int[] cCnt = new int[l];
for (; i >= 0; i--) {//从10元到1元,遍历钱币数组
monE = a2[i][0];//该钱币面值
j = mon / monE;//大面值能找零,则先找大面值
if (a2[i][1] == 0 || j == 0) {//余额不足或者该面值数量0,跳过
cCnt[i] = 0;
continue;
}
if (j > a2[i][1]) {//找零的数量超过该面值总数量
cCnt[i] = a2[i][1];//只找出该面值总数
a2[i][1] = 0;//该面值数量变为0
mon -= cCnt[i] * monE;
} else {
cCnt[i] = j;
a2[i][1] -= j;
mon -= j * monE;
}
}
return cCnt;
}
}
