前言:藥店售藥環節,醫保刷卡存在特殊需求,頁面錄入任意金額T元,要求查詢出總價為T(或者略大于T)的貨品組合。
判斷邏輯:
1)根據醫保目錄随機選取同等價格商品(可略大于,但不能超過15%)
2)20元以内選取一個商品、50元以内最少選取二個商品、100元以内最少選取三個商品
3)超過100元,以上面三種方法遞增
需求分析:
0-20元檔 錄入任意金額,查出一個貨品,貨品價格區間為[0,20];
20-50元檔 錄入任意金額x,查出最少2個貨品,貨品價格總和為x;
50-100元檔 錄入任意金額y,查出最少3個貨品,貨品價格總和為y;
100-n元檔,錄入任意金額z,查出上述邏輯計算出的貨品數量,貨品價格總和為z;
代碼:
package day09;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import com.inca.np.gui.control.DBTableModel;
import com.inca.np.util.DecimalHelper;
import com.inca.np.util.SelectHelper;
import com.inca.pubsrv.ObjectUtils;
import com.inca.resale.sale.ybkp.server.GoodsqtyhovService.ZxException;
/**
* @author Yudx
* @date 2020年3月7日 上午10:41:35
*/
public class RecursionDemo {
/**
* @param con
* @param wheres
* @param yushu1
* @return
* add by yudexiao
* 2020年3月4日 下午9:31:35
* @throws Exception
*/
private DBTableModel getT2Model(Connection con, String shang1, String wheres) throws Exception {
DBTableModel t2Model = null;
Map<String, String> map = new HashMap<String, String>();
/**
* 假設我們要擷取一個40元的貨品,該貨品價格區間在[20,50]這段内,
* 那我們先從區間[10,40]價格段随機擷取一個貨品,
* 假設取到 的随機數是x,那麼 取另一個貨品價格則為40-x,
* 然後從結果集中查詢擷取價格為40-x的貨品,如果有則取出,如果沒有則遞歸,重新随機擷取一個貨品,
* 假設取到 的随機數是y,那麼 取另一個貨品價格則為40-y,
* 然後從結果集中查詢擷取價格為40-y的貨品,如果有則取出,如果沒有則遞歸。
*/
String ssql = "select b.goodsid, x.price\n" +
" from npbusi_yb_goods a,\n" +
" npbusi_yb_goods_ref b,\n" +
" (select price,priceid,goodsid from ngpcs_all_price where placepointid = "+placepointid+") x,\n" +
" pub_price_type c\n" +
" where a.ybgoodsid = b.ybgoodsid\n" +
" and x.priceid = c.priceid\n" +
" and x.goodsid = b.goodsid\n" +
" and c.pricename = '公司零售價'\n" +
" and c.workflag in (4, 5)\n" +
" and nvl(x.price, 0) >10 and nvl(x.price, 0) < "+shang1+" \n" +
" and exists (select 1 from Npbusi_yb_company\n" +
" where ybid = b.ybid and companyid = "+placepointid+")\n";
ssql = ssql + " and " + wheres ;
SelectHelper sh = new SelectHelper(ssql);//擷取複核條件的sql
DBTableModel goodsdm = null;
goodsdm = sh.executeSelect(con, 0, 10);
if (!ObjectUtils.isNULL(goodsdm)) {
for (int i = 0; i < goodsdm.getRowCount(); i++) {
map.put(goodsdm.getItemValue(i, "goodsid"), goodsdm.getItemValue(i, "price"));
}
}
String randomGoodsid = getRandomKeyFromMap(map);//将貨品價格放到map中随機擷取一個goodsid
String randomPrice = map.get(randomGoodsid);
//求內插補點
String param = DecimalHelper.toDec(shang1).subtract(DecimalHelper.toDec(randomPrice)).toString();
//遞歸取另外一個貨品
DBTableModel zxmodel = null;
try {
getSpecialModel(con,param,wheres,map,randomGoodsid,randomPrice,shang1);
} catch (ZxException e) {
//異常處理比較罕見,這裡要重點注意,跳出遞歸,此處我用到的方法是:抛異常
zxmodel = e.getModel();
} catch (Exception e) {
e.printStackTrace();
}
t2Model = zxmodel.copyStruct();
t2Model.bindMemds(zxmodel);
return t2Model;
}
class ZxException extends Exception{
private DBTableModel model ;
/**
* @return the model
*/
public DBTableModel getModel() {
return model;
}
/**
* @param model the model to set
*/
public void setModel(DBTableModel model) {
this.model = model;
}
private ZxException (DBTableModel zxmodel) {
this.model = zxmodel;
}
}
/**
* @param map
* @param wheres
* @param param
* @param con
* @param shang1
* @param randomPrice2
* @param randomGoodsid2
* @return
* add by yudexiao
* 2020年3月5日 上午10:26:27
* @throws Exception
*/
private DBTableModel getSpecialModel(Connection con, String param, String wheres, Map<String, String> map,
String randomGoodsid, String randomPrice, String shang1) throws Exception {
String theThirdSql = "select goodsid,price from ( select b.goodsid, x.price\n" +
" from npbusi_yb_goods a,\n" +
" npbusi_yb_goods_ref b,\n" +
" (select price,priceid,goodsid from ngpcs_all_price where placepointid = "+placepointid+") x,\n" +
" pub_price_type c\n" +
" where a.ybgoodsid = b.ybgoodsid\n" +
" and x.priceid = c.priceid\n" +
" and x.goodsid = b.goodsid\n" +
" and c.pricename = '公司零售價'\n" +
" and c.workflag in (4, 5)\n" +
" and nvl(x.price, 0) = " +param +
" and exists (select 1 from Npbusi_yb_company where ybid = b.ybid and companyid = "+placepointid+")\n"
+ " and " + wheres +"order by x.price asc ) where rownum = 1";
SelectHelper sh = new SelectHelper(theThirdSql);
System.out.println(param+"--"+theThirdSql);
DBTableModel theThirdModel = sh.executeSelect(con, 0, 1);
if (ObjectUtils.isNULL(theThirdModel)) {
randomGoodsid = getRandomKeyFromMap(map);
randomPrice = map.get(randomGoodsid);
//求內插補點
param = DecimalHelper.toDec(shang1).subtract(DecimalHelper.toDec(randomPrice)).toString();
getSpecialModel(con,param,wheres,map,randomGoodsid,randomPrice,shang1);
}else {
DBTableModel firstModel = theThirdModel.copyStruct();
firstModel.appendRow();
firstModel.setItemValue(0, "goodsid", randomGoodsid);
firstModel.setItemValue(0, "price", randomPrice);
theThirdModel.bindMemds(firstModel);
//采用一個抛自定義異常的方式,傳回該方法的傳回值。
throw new ZxException(theThirdModel);
//return theThirdModel;------------這種寫法有bug,無法正确跳出遞歸
}
return null;
}
class DBTableModel {
}
}
總結:跳出遞歸需要用抛異常的方式,mark一下。
這個算法思路可以總結一下,化整為零,化零為整。