根据差异将数组过滤为每十的倍数一行?
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 ..."; // 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;
}
获得的样本table为:
从 table 可以清楚地看出,第二列 beam_current
的值接近 0 到 220 之间十的每个整数倍:(0, 10, 20 ... 220 ).我想过滤我的数据集,以便对于每 10 的倍数,我只 select 最接近该倍数的行。为此我:
- 从
beam_current
的所有行中减去 10 并找出所获得的差异:差异最小的行是我对 10 的倍数感兴趣的唯一行。T
- 重复步骤 1,直到从所有行中减去总计 220。
我的预期结果是 22 行,而不是示例数据中的原始 47 行。例如,上面示例数据图片中编号为 21 的行对应于值 130
.
的 selected 行
我的问题是我没有看到预期的结果。我试过的代码是:
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;
}
此代码似乎 select 完全错误的行 - 我做错了什么?
我认为你应该换一种方式来考虑这个问题。你想要做的是找到每行十的倍数的距离。
- 最接近的十的倍数由表达式
double mult = 10d * Math.round(v / 10d)
给出
- 与十的倍数的距离由表达式
double delta = Math.abs(v - mult)
给出
- 对于
mult
的任何值,您想要的行是具有最小 delta
值的行。
因此您只需迭代一次行。
- 获取一行的
beam_value
,发现是mult
和delta
。
- 如果该行的
delta
比之前为 mult
找到的任何 delta
更近,则记录该 mult
的行,否则忽略它。
- 重复直到没有更多的行。
另请注意,此方法将防止单行记录超过十的倍数,这很难用其他方法来防止。
举个例子(我伪造了数据,因为我没有你的 SQL 查询)。输入数据:
`0.5, 12.10, 13.00, 16.01, 21.52`
给出下面的输出,这是正确的(索引 1 比索引 2 更接近 10
,索引 4 比索引 3 更接近 20
):
10x row value
0 0 0.5000
10 1 12.1000
20 4 21.5200
使用代码:
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);
}
我有一个数组,它保存来自结果集的值。我检索数组的代码大纲是:
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;
}
获得的样本table为:
从 table 可以清楚地看出,第二列 beam_current
的值接近 0 到 220 之间十的每个整数倍:(0, 10, 20 ... 220 ).我想过滤我的数据集,以便对于每 10 的倍数,我只 select 最接近该倍数的行。为此我:
- 从
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( Exception e ) { ... }
finally { ... }
return arr;
}
此代码似乎 select 完全错误的行 - 我做错了什么?
我认为你应该换一种方式来考虑这个问题。你想要做的是找到每行十的倍数的距离。
- 最接近的十的倍数由表达式
double mult = 10d * Math.round(v / 10d)
给出
- 与十的倍数的距离由表达式
double delta = Math.abs(v - mult)
给出
- 对于
mult
的任何值,您想要的行是具有最小delta
值的行。
因此您只需迭代一次行。
- 获取一行的
beam_value
,发现是mult
和delta
。 - 如果该行的
delta
比之前为mult
找到的任何delta
更近,则记录该mult
的行,否则忽略它。 - 重复直到没有更多的行。
另请注意,此方法将防止单行记录超过十的倍数,这很难用其他方法来防止。
举个例子(我伪造了数据,因为我没有你的 SQL 查询)。输入数据:
`0.5, 12.10, 13.00, 16.01, 21.52`
给出下面的输出,这是正确的(索引 1 比索引 2 更接近 10
,索引 4 比索引 3 更接近 20
):
10x row value 0 0 0.5000 10 1 12.1000 20 4 21.5200
使用代码:
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);
}