根据差异,将数组过滤为每10个十行一行?

时间:2015-01-14 11:15:29

标签: java multidimensional-array

我有一个数组,用于保存结果集中的值。我检索数组的代码大纲是:

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;
}

获得的样本表是:

enter image description here

从表中可以清楚地看出,第二列beam_current的值接近10到0的每个整数倍:(0,10,20 ... 220)。我想过滤我的数据集,这样,对于每个十的倍数,我只选择最接近该倍数的行。为此我:

  1. beam_current的所有行中减去10并找出所获得的差异:差异最小的行是我唯一对10的倍数感兴趣的行.T
  2. 重复步骤1,直到从所有行中减去总计220个。
  3. 我的预期结果是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;
    }
    

    这段代码似乎完全选择了错误的行 - 我做错了什么?

1 个答案:

答案 0 :(得分:3)

我认为你应该以不同的方式思考这个问题。你想要做的是找到每行十的倍数距离。

  • 十分之一的最接近的倍数由表达式double mult = 10d * Math.round(v / 10d)
  • 给出
  • 距离十的倍数的距离由表达式double delta = Math.abs(v - mult)
  • 给出
  • 对于mult的任何值,您想要的行是delta值最小的行。

因此,您只需迭代行一次。

  1. 获取行beam_value,找到multdelta
  2. 如果行deltadelta之前找到的mult更接近,则记录该mult的该行,否则忽略它。
  3. 重复,直到没有更多行。
  4. 另请注意,这种方法可以防止单行记录多于十的倍数,这很难用其他方法来防止。

    通过示例(我伪造了数据,因为我没有你的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);
    }