插值查询:如果有这样一张表,有一列叫水位,有一列叫库容,比如下面的图。

我现在想做这么一件事情:对于这个测站而言,当我输入某一个水位或者库容的时候,想要查询到对应的水位或者库容呢?

而这个值不一定是存在数据库中的,也许这只是一个推导出来的近似值呢?

算法要点:如果这个输入的值是位于数据库值的某一个区间内的话,那么取最小的区间,然后求这个区间内单位数量的值。

大家听得可能有点不太明白,我画张图。

呵呵,应该有点眉目了吧?这个第一步也是最重要的一步就是确定区间哦

算法的话很简单,用一句公式来概括就是

1.通过水位求库容:(单位水位所包含的库容)*(输入水位-这个水位左边区间的水位值)+这个水位左边区间的水位值

2.通过库容求水位:(单位库容所包含的库容)*(输入库容-这个库容左边区间的库容值)+这个库容左边区间的库容值

不废话,贴代码,用的是JAVA实现的

    //插值查询法
@Override
public String InterpolantQuery(ReservoirCapacityConditionParam param)
{
String finalVal="";
float finalVolumn=;
StringBuffer sb=new StringBuffer();
StringBuffer sd=new StringBuffer();
sb.append("select z,v from hydro_curve_b where stcd='"+param.getStcd()+"' "); if(param.getV()==""&&param.getZ()!="")
{
sb.append(" and z='"+param.getZ()+"'");
}
else if(param.getV()!=""&&param.getZ()=="")
{
sb.append(" and v='"+param.getV()+"'");
} List<Object []> fromSTCD=this.daoHelper.findBySql(sb.toString()); //如果是已有数据,直接显示,否则算法查找
/*算法:通过库容查水位或通过水位查库容,如果输入的值在已有数据的某个范围内,则定位此数据的最小范围
* 1.比如输入120,有119~121,118~122这2个范围,则取119~121这个近似范围
* 2.假设输入的是水位,要查询库容,那么首先算出每一米水位在(1)范围内的库容,然后算出库容的增量,用这个增量加上这个区间内较低的库容
* 3.由于框架不能使用TOP关键字,所以(1)的范围的的取法:左边:查出比输入值小的所有数据,按大小的降序拍了,取最后一条,右边:查出比输入值大的所有数据,按升序排列,取最后一条*/
if(fromSTCD.size()==)
{
//如果水位为空,则按照库容查询水位
if(param.getZ()=="")
{ if(param.getV().equals(""))
{
//如果输入0,则不查询
} else
{
//查出左边区间的
List<Object []> left_fromSTCD=this.daoHelper.findBySql("select z,v from hydro_curve_b where stcd='"+param.getStcd()+"' and v<'"+param.getV()+"' order by z asc"); //查出右边区间的
List<Object []> right_fromSTCD=this.daoHelper.findBySql("select z,v from hydro_curve_b where stcd='"+param.getStcd()+"' and v>'"+param.getV()+"' order by z desc"); float beginZ=,beginV=; //水位
float endZ=,endV=; //库容 //如果左边区间为空
if(left_fromSTCD.size()==)
{
//重置左边的区间
left_fromSTCD=this.daoHelper.findBySql(" select z,min(v) v from hydro_curve_b where stcd='"+param.getStcd()+"' group by z order by z desc"); for(Object []obj:left_fromSTCD)
{
beginZ=Float.parseFloat(String.valueOf(obj[]));
beginV=Float.parseFloat(String.valueOf(obj[]));
} //重置右边的区间
right_fromSTCD=this.daoHelper.findBySql("select z.* from (select top 2 z,min(v) v from hydro_curve_b where stcd='"+param.getStcd()+"' and v>"+param.getV()+" group by z) z order by z.z asc"); for(Object []obj:right_fromSTCD)
{
endZ=Float.parseFloat(String.valueOf(obj[]));
endV=Float.parseFloat(String.valueOf(obj[]));
}
} else
{
for(Object []obj:left_fromSTCD)
{
beginZ=Float.parseFloat(String.valueOf(obj[]));
beginV=Float.parseFloat(String.valueOf(obj[]));
}
} //如果右边区间为空
if(right_fromSTCD.size()==)
{
//重置左边的区间
left_fromSTCD=this.daoHelper.findBySql("select z.* from (select top 2 z,max(v) v from hydro_curve_b where stcd='"+param.getStcd()+"' and v<"+param.getV()+" group by z) z order by z.z desc"); for(Object []obj:left_fromSTCD)
{
beginZ=Float.parseFloat(String.valueOf(obj[]));
beginV=Float.parseFloat(String.valueOf(obj[]));
} //重置右边的区间
right_fromSTCD=this.daoHelper.findBySql("select z,max(v) from hydro_curve_b where stcd='"+param.getStcd()+"' group by z order by z asc"); for(Object []obj:right_fromSTCD)
{
endZ=Float.parseFloat(String.valueOf(obj[]));
endV=Float.parseFloat(String.valueOf(obj[]));
}
}
else
{
for(Object []obj:right_fromSTCD)
{
endZ=Float.parseFloat(String.valueOf(obj[]));
endV=Float.parseFloat(String.valueOf(obj[]));
}
} //计算每一格库容所包含的水位
float eachVolumn=/((endV-beginV)/(endZ-beginZ));
float z=Float.parseFloat(param.getV());
//得到最终的水位
finalVolumn=(z-beginV)*eachVolumn+beginZ;
} }
//如果库容为空,则按照水位查询库容
else if(param.getV()=="")
{ if(param.getZ().equals(""))
{
//如果输入0,则不做任何操作
}
else
{
//查出左边区间的
List<Object []> left_fromSTCD=this.daoHelper.findBySql("select z,v from hydro_curve_b where stcd='"+param.getStcd()+"' and z<'"+param.getZ()+"' order by v asc"); //查出右边区间的
List<Object []> right_fromSTCD=this.daoHelper.findBySql("select z,v from hydro_curve_b where stcd='"+param.getStcd()+"' and z>'"+param.getZ()+"' order by v desc"); float beginZ=,beginV=; //水位,库容(left)
float endZ=,endV=; //水位,库容(right) //如果输入的最小值比最数据库里的最小值小,那么取数据库里的最小值
//重置区间的原因是因为最小值是一个区间,用TOP2确定范围
if(left_fromSTCD.size()==)
{
//重置左边的区间
left_fromSTCD=this.daoHelper.findBySql(" select MIN(z) z,v from hydro_curve_b where stcd='"+param.getStcd()+"' group by v order by v desc"); for(Object []obj:left_fromSTCD)
{
beginZ=Float.parseFloat(String.valueOf(obj[]));
beginV=Float.parseFloat(String.valueOf(obj[]));
} //重置右边的区间
right_fromSTCD=this.daoHelper.findBySql("select z.* from (select top 2 min(z) z,v from hydro_curve_b where stcd='"+param.getStcd()+"' and z>"+param.getZ()+" group by v) z order by z.v asc"); for(Object []obj:right_fromSTCD)
{
endZ=Float.parseFloat(String.valueOf(obj[]));
endV=Float.parseFloat(String.valueOf(obj[]));
}
}
else
{ for(Object []obj:left_fromSTCD)
{
beginZ=Float.parseFloat(String.valueOf(obj[]));
beginV=Float.parseFloat(String.valueOf(obj[]));
}
}
//如果输入的最大值比数据库里的最大值大,那么取数据库的最大值。
if(right_fromSTCD.size()==)
{ //重置左边的区间
left_fromSTCD=this.daoHelper.findBySql("select z.* from (select top 2 max(z) z,v from hydro_curve_b where stcd='"+param.getStcd()+"' and z<"+param.getZ()+" group by v) z order by z.v desc"); for(Object []obj:left_fromSTCD)
{
beginZ=Float.parseFloat(String.valueOf(obj[]));
beginV=Float.parseFloat(String.valueOf(obj[]));
} //重置右边的区间
right_fromSTCD=this.daoHelper.findBySql("select max(z) z,v from hydro_curve_b where stcd='"+param.getStcd()+"' group by v order by v asc"); for(Object []obj:right_fromSTCD)
{
endZ=Float.parseFloat(String.valueOf(obj[]));
endV=Float.parseFloat(String.valueOf(obj[]));
} } else
{
for(Object []obj:right_fromSTCD)
{
endZ=Float.parseFloat(String.valueOf(obj[]));
endV=Float.parseFloat(String.valueOf(obj[]));
}
}
//计算每一格库容所包含的水位
//float eachVolumn=(endV-beginV)/(endZ-beginZ);
float eachVolumn=/((endZ-beginZ)/(endV-beginV));
float z=Float.parseFloat(param.getZ());
//得到最终的库容
//finalVolumn=(endZ-z)*eachVolumn+endZ;
finalVolumn=beginV+eachVolumn*(z-beginZ); } } return String.valueOf(finalVolumn); }
else
{
for(Object obj[]:fromSTCD)
{
if(param.getV()=="")
{
finalVal=String.valueOf(obj[]);
}
else if(param.getZ()=="")
{
finalVal=String.valueOf(obj[]);
} }
return finalVal;
} }

其中也没什么难点,就是要注意一下左右区间重置的计算方法。

因为每次FOR遍历出里面的变量以后,前面的变量都会被后面的变量所覆盖,所以这里大家需要注意一下,合理使用top关键字和order by 是做出这个的关键,

好了,最后截图2张给大家看看效果,最后啰嗦一句,插值查询法虽然是算出来的,但是和数据库里的数据时息息相关的,是根据数据库里的数据算出的近似值。

比如下面的图,都是输入200的水位,但是结果不同,因为他们对应的区间不同。

用JAVA实现插值查询的方法(算近似值,区间求法)的更多相关文章

  1. JAVA之数组查询binarySearch()方法详解

    binarySearch()方法提供了多种重载形式,用于满足各种类型数组的查找需要,binarySearch()有两种参数类型 注:此法为二分搜索法,故查询前需要用sort()方法将数组排序,如果数组 ...

  2. Java jar包查询下载方法

    做过java开发的工程师,对java应用所需jar包一定不会陌生.特别是有需要搭建开发环境时,对各种jar包的需求量就会很大. 如何快速的找到自己想要的jar包,是蛮多java工程师所面临的一个难题. ...

  3. Elasticsearch java api 常用查询方法QueryBuilder构造举例

    转载:http://m.blog.csdn.net/u012546526/article/details/74184769 Elasticsearch java api 常用查询方法QueryBuil ...

  4. java配置数据库连接池的方法步骤

    java配置数据库连接池的方法步骤 java配置数据库连接池的方法步骤,需要的朋友可以参考一下   先来了解下什么是数据库连接池数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个Vecto ...

  5. Oracle 特殊字符模糊查询的方法

    最近在写DAO层的时候,遇到一个问题,就是使用like进行模糊查询时,输入下划线,无法精确查到数据,而是返回所有的数据. 这让我很好奇,百度之后才发现,原来是因为有些特殊字符需要进行转义才可以进行查询 ...

  6. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  7. SSH框架的多表查询(方法二)增删查改

     必须声明本文章==>http://www.cnblogs.com/zhu520/p/7773133.html  一:在前一个方法(http://www.cnblogs.com/zhu520/p ...

  8. 【java】详解native方法的使用

    目录结构: contents structure [+] 关于native关键字 使用native关键字 使用步骤 案例 编写.java文件 编译.java文件 获得.h文件 编写hello.cpp文 ...

  9. JVM总结-Java 虚拟机是怎么识别目标方法(下)

    1. 虚方法调用 在上一篇中我曾经提到,Java 里所有非私有实例方法调用都会被编译成 invokevirtual 指令,而接口方法调用都会被编译成 invokeinterface 指令.这两种指令, ...

随机推荐

  1. java并发编程(十七)Executor框架和线程池

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497   Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...

  2. JPA或Hibernate中的

    JPA执行原生SQL截断Char类型问题 在JPA的API中执行原生SQL:EntityManager.createNativeQuery(String sqlString); 传入参数是原生SQL语 ...

  3. nginx-(/usr/local/nginx)配置编译

    ./configure \ --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --conf-path=/usr ...

  4. myeclipse导入项目出现jquery错误(有红叉)

    今天导入了一个项目,但是进去之后jquery出现了红叉,如图(事实上在我没调好之前两个jquery文件都有叉号) 怎么调呢?右键jquery文件,选择MyEclipse->Exclude Fro ...

  5. fwrite写入文件不成功bug

    文件写入了,只是从头覆盖了!因为在fwrite():前面 文件位置指针是是SEEK_SET,即首位置.在fwrite(fileHeader, 1, 10, file); 前面加上一行fseek(fil ...

  6. c = (a / b, a%b) 运算输出顺序

    #include<iostream> int main() { using namespace std; int a, b, c; a = ; b = ; c = ; printf(&qu ...

  7. Java static 的一两点使用

    这篇文章是关于Java static关键字的使用,主要会介绍以下的内容: static 的概念 static的各种应用 总结 static 是什么 static 顾名思义是静态的意思.与this相对, ...

  8. JAVA集合

    为了保存数量不确定的数据或者提供映射关系的数据,Java提供了集合类,也称作集合类,Collection和Map分别为两个根接口.两个接口体系的继承系如下图 (图片来源于网络) Collection接 ...

  9. 详解CSS的相对定位和绝对定位

    CSS的相对定位和绝对定位通常情况下,我们元素的position属性的值默认为static 就是没有定位,元素出现在正常的文档流中,,这个时候你给这个元素设置的left,right,bottom,to ...

  10. XSD文件生成C#VO实体类

    最近公司要做一个项目,需要和现有的其他项目对接,由于不知道他们的数据库,只有XSD文件.所以,我们在修改相应的程序时,就需要根据他们提供的XSD文件,来写我们的VO实体类,由于我写过根据Oracle数 ...