前言:药店售药环节,医保刷卡存在特殊需求,页面录入任意金额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一下。
这个算法思路可以总结一下,化整为零,化零为整。