根据差异,将数组过滤为每10个十行一行? [英] Filter array to one row per multiple of ten, based on difference?
问题描述
我有一个数组,用于保存结果集中的值。我检索数组的代码大纲是:
public String [] [] ref_Details( ){
int i = 0;
String a [] [] = new String [47] [11];
try
{
con = getConnection();
stmt = con.createStatement();
String sql =select b.LOGTIME,b.beam_current,b.beam_energy ......; //缩短
stmt.executeQuery(sql);
rs = stmt.getResultSet();
while(rs.next()){
for(int j = 0; j< 11; j ++)
a [i] [j] = rs.getString(j 1);
i ++;
}
}
catch(例外e){...}
finally {
closeConnection(stmt,rs,con);
}
返回a;
}
获得的样本表是:
从表中可以清楚地看到,第二列 beam_current
的值接近10到0的每个整数倍:(0,10,20 ...... 220) )。我想过滤我的数据集,这样,对于每个十的倍数,我只选择最接近该倍数的行。为此,我:
- 从
beam_current
的所有行中减去10并找到获得的差异:差异最小的行是我对10的倍数感兴趣的唯一行.T - 重复步骤1,直到从所有行中减去总计220 。
我的预期结果是22行,而不是样本数据中的原始47行。例如,上面的示例数据图片中编号为21的行将对应于值 130
的所选行。
<我的问题是我没有看到我预期的结果。我尝试的代码是:
public int [] ref_BeamCurrent(){
int i = 0;
int [] arr = new int [47];
try
{
con = getConnection();
...
rs = stmt.getResultSet();
while(rs.next())
{
for(i = 0; i< arr.length; i ++)
{
arr [ i] = rs.getInt(2);
System.out.println(arr);
while(i< arr.length&& number< = 210)
{
arr [i] = arr [i] - number;
System.out.println(arr);
number = number + 10;
System.out.println(number);
i = i + 1;
// System.out.println(arr);
}
}
}
}
catch(例外e){...}
finally {...}
return arr ;
}
这段代码似乎完全选择了错误的行 - 我做错了什么?
我认为你应该以不同的方式思考这个问题。你想要做的是找到每行十的倍数距离。
- 十分之一的最接近倍数由表达式
double mult = 10d * Math.round(v / 10d)给出)
- 距离十的倍数的距离由表达式
double delta = Math.abs(v-mult)
- 对于
mult
的任何值,您想要的行是delta
value。
因此,您只需迭代行一次。
- 获取行的
beam_value
并找到mult
和delta
。 - 如果行的
delta
比之前找到的delta
更接近mult
,然后记录mult
的那一行,否则忽略它。 - 重复,直到没有更多的行。
另请注意,此方法将阻止单行记录十个以上的十个倍数,用其他方法很难防止。
通过示例(我伪造了数据,因为我没有你的SQL查询)。输入数据:
`0.5,12.10,13.00,16.01,21.52`
给出下面的输出,这是正确的(索引1比索引2更接近 10
,和索引4比索引3更接近 20
:
10x行值
0 0 0.5000
10 1 12.1000
20 4 21.5200
代码:
public static void findClosestRowsToMultiplesOfTen(){
//假行值
double [] vals = new double [] {0.5,12.10,13.00,16.01,21.52};
//获取最大值,以及它的倍数为10以获得桶数
double max = Double.MIN_VALUE;
for(double v:vals)max = Math.max(max,v);
int bucketCount = 1 +(int)(max / 10);
//初始化桶数组以存储最接近的值
double [] [] buckets = new double [bucketCount] [3];
for(int i = 0; i< bucketCount; i ++){
//在第一个元素中存储当前最小的delta
buckets [i] [0] = Double.MAX_VALUE;
//将当前最接近的索引存储在第二个元素中
buckets [i] [1] = -1d;
//将当前最接近的值存储在第三个元素中
buckets [i] [2] = Double.MAX_VALUE;
}
//迭代行
for(int i = 0; i< vals.length; i ++)
{
// get行
double v = vals [i];
//获得10的最接近倍数v
double mult = getMultipleOfTen(v);
//从10的倍数得到v的绝对距离
double delta = Math.abs(mult-v);
//根据`mult`
int bIdx =(int)(mult / 10d)的值获取bucket索引;
//测试此桶的最后已知最小增量
if(buckets [bIdx] [0]> delta)
{
//这比最后一个已知的最小三角洲
桶[bIdx] [0] = delta;
buckets [bIdx] [1] = i;
buckets [bIdx] [2] = v;
}
}
//打印出结果
System.out.format(10x行值%n);
for(int i = 0; i< buckets.length; i ++)
{
double [] bucket = buckets [i];
int multipleOfTen = i * 10;
double rowIndex = bucket [1];
double rowValue = bucket [2];
System.out.format(%,2d%,4.0f%.4f%n,
multipleOfTen,rowIndex,rowValue);
}
}
public static double getMultipleOfTen(double v)
{
return 10d * Math.round(v / 10d);
}
I have an array which holds the values from a resultset. The outline of my code to retrieve the array is:
public String[][] ref_Details() {
int i = 0;
String a[][] = new String[47][11];
try
{
con = getConnection();
stmt = con.createStatement();
String sql=" select b.LOGTIME, b.beam_current, b.beam_energy ..."; // shortened
stmt.executeQuery(sql);
rs = stmt.getResultSet();
while(rs.next()) {
for(int j=0; j<11; j++)
a[i][j] = rs.getString(j+1);
i++;
}
}
catch( Exception e ) { ... }
finally {
closeConnection(stmt, rs, con);
}
return a;
}
The sample table obtained is:
From the table it is clear that the second column beam_current
has values which are near to each integer multiple of ten from 0 to 220: (0, 10, 20 ... 220). I want to filter my data set so that, for each multiple of ten, I only select the row closest to that multiple. For this I:
- subtract 10 from all the rows of
beam_current
and find the differences obtained: the row with the smallest difference is the only row in which I'm interested for that multiple of 10. T - repeat step 1 until a total of 220 is subtracted from all rows.
My expected result is 22 rows instead of the original 47 from the sample data. For example, the row numbered 21 in the sample data picture above would correspond to the selected row for the value 130
.
My problem is that I'm not seeing my expected results. The code I tried is:
public int[] ref_BeamCurrent() {
int i = 0;
int[] arr = new int[47];
try
{
con = getConnection();
...
rs = stmt.getResultSet();
while(rs.next())
{
for(i=0; i<arr.length; i++)
{
arr[i] = rs.getInt(2);
System.out.println(arr);
while (i < arr.length && number <= 210)
{
arr[i] = arr[i] - number;
System.out.println(arr);
number = number + 10;
System.out.println(number);
i = i + 1;
// System.out.println(arr);
}
}
}
}
catch( Exception e ) { ... }
finally { ... }
return arr;
}
This code seems to be selecting entirely the wrong rows - what am I doing wrong?
I think you should think about this in a different way. What you want to do is find the distance from a multiple of ten for each row.
- The closest multiple of ten is given by the expression
double mult = 10d * Math.round(v / 10d)
- The distance from the multiple of ten is given by the expression
double delta = Math.abs(v - mult)
- For any value of
mult
, the row you want is the one with the smallestdelta
value.
Therefore you only have to iterate the rows once.
- Get the
beam_value
for a row and find it'smult
anddelta
. - If the row's
delta
is closer than any previously founddelta
formult
, then log that row for thatmult
, otherwise ignore it. - repeat until there are no more rows.
Also note that this approach will prevent a single row being logged against more than one multiple of ten, which is hard to prevent with other approaches.
By example (and I have faked the data as I don't have your SQL query). The input data:
`0.5, 12.10, 13.00, 16.01, 21.52`
gives the output below, which is correct (index 1 is closer to 10
than index 2, and index 4 is closer to 20
than index 3):
10x row value 0 0 0.5000 10 1 12.1000 20 4 21.5200
with the code:
public static void findClosestRowsToMultiplesOfTen() {
// fake row values
double[] vals = new double[]{ 0.5, 12.10, 13.00, 16.01, 21.52 };
// get the max value, and its multiple of ten to get the number of buckets
double max = Double.MIN_VALUE;
for (double v : vals) max = Math.max(max, v);
int bucketCount = 1 + (int)(max/10);
// initialise the buckets array to store the closest values
double[][] buckets = new double[bucketCount][3];
for (int i = 0; i < bucketCount; i++){
// store the current smallest delta in the first element
buckets[i][0] = Double.MAX_VALUE;
// store the current "closest" index in the second element
buckets[i][1] = -1d;
// store the current "closest" value in the third element
buckets[i][2] = Double.MAX_VALUE;
}
// iterate the rows
for (int i = 0; i < vals.length; i++)
{
// get the value from the row
double v = vals[i];
// get the closest multiple of ten to v
double mult = getMultipleOfTen(v);
// get the absolute distance of v from the multiple of ten
double delta = Math.abs(mult - v);
// get the bucket index based on the value of `mult`
int bIdx = (int)(mult / 10d);
// test the last known "smallest delta" for this bucket
if (buckets[bIdx][0] > delta)
{
// this is closer than the last known "smallest delta"
buckets[bIdx][0] = delta;
buckets[bIdx][1] = i;
buckets[bIdx][2] = v;
}
}
// print out the result
System.out.format(" 10x row value%n");
for (int i = 0; i < buckets.length; i++)
{
double[] bucket = buckets[i];
int multipleOfTen = i * 10;
double rowIndex = bucket[1];
double rowValue = bucket[2];
System.out.format(" %,2d %,4.0f %.4f%n",
multipleOfTen, rowIndex, rowValue);
}
}
public static double getMultipleOfTen(double v)
{
return 10d * Math.round(v / 10d);
}
这篇关于根据差异,将数组过滤为每10个十行一行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!