题解 | #自动售货系统#
自动售货系统
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; } }