【问题标题】:Java - How to split array on each iteration and pass into a function efficiently?Java - 如何在每次迭代时拆分数组并有效地传递给函数?
【发布时间】:2013-02-24 23:55:34
【问题描述】:

我有一个包含一些值的数组和一个接收两个数组的函数。我想要做的是拆分数组,以便最后一个元素不在数组中,所以我有两个数组,一个包含除最后一个之外的所有原始元素,另一个只有一个元素 - 最后一个。将其传递给函数后,我想使用原始数组,但这次将倒数第二个元素放入单独的数组中,依此类推。我想这样做五次。以下将更好地解释它:

int[] val = {25,50,66,75,100,1000,5000,10000,25000};

for (int i=0; i<5; i++){

//Need to split the array and then pass it to the function here
}

public void evaluate(int[] train, int[] test){

....
}

因此,例如在第一次迭代中,我想从数组中删除/拆分 25000 并将其放入另一个数组中,然后将这两个数组传递给函数:

第一个数组现在有{25,50,66,75,100,1000,5000,10000} 第二个数组现在有{25000}

在下一次迭代中,我现在想拆分/删除 10000(25000 现在回到数组中):

所以第一个数组现在有{25,50,66,75,100,1000,5000,25000} 第二个数组现在有{10000}

所以基本上它是从底部往上走,但只有 5 次。

【问题讨论】:

  • 请不要在您的问题中包含“如果我不能正确解释这一点,我很抱歉(因此描述很长)。希望有人可以帮助或指出我正确的方向。谢谢”。这是无用的噪音。
  • @Doorknob 哇好。有礼貌,还是谢谢
  • 我知道,我一开始也是这么想的。但是,这里通常不受欢迎。 meta.stackexchange.com/questions/2950/…
  • 也许使用LinkedList,使用remove(int index)add(int index, E element)

标签: java arrays loops


【解决方案1】:

预先创建两个数组,并在每次迭代后将一个元素交换到您的测试数组中。这将比一直分配新数组更快。

int[] val = {25,50,66,75,100,1000,5000,10000,25000};

// create the destination arrays:
int[] train = new int[val.length-1];
int[] test = new int[1];

// initialize the arrays:
test[0] = val[val.length-1];
for (int i = 0; i < val.length-1; ++i)
{
    train[i] = val[i];
}

int timesToIterate = 5;

for (int iteration = 0; iteration < timesToIterate; ++iteration)
{
    evaluate(train, test);

    int i = train.length-1-iteration;
    if (i >= 0) // don't swap if this is the last element in the array
    {
        int tmp = test[0];
        test[0] = train[i];
        train[i] = tmp;
    }
}

使用您的示例数据,传递给评估函数的数组是:

{25 50 66 75 100 1000 5000 10000 } {25000}
{25 50 66 75 100 1000 5000 25000 } {10000}
{25 50 66 75 100 1000 10000 25000 } {5000}
{25 50 66 75 100 5000 10000 25000 } {1000}
{25 50 66 75 1000 5000 10000 25000 } {100}

【讨论】:

    【解决方案2】:

    我不知道您最终要做什么,但这似乎非常适合函数式编程语言。无论如何,我们可以在 java 和数组中做到这一点:

    在包含从 1 到 5 的 for 循环中,您可能会输入如下内容:

    for (int i=1; i<=5; i++){
      int[] train = new int[val.length-i];
      System.arraycopy( val, 0, train, 0, train.length-1 );
      int test = new int[1];
      test[0] = val[val.length-i];
      evaluate(train,test);
    }
    

    【讨论】:

    • train数组的长度永远不会减少。它只会删除一个元素并将先前删除的元素添加回
    【解决方案3】:

    我会使用的算法是:

    1. 获取原始数组 A,并创建一个新的 A',其中少 1 个元素和一个单元素数组,称为 B。
    2. 用 n-1 个元素填充 A',用 1 个元素填充 B。
    3. 然后,当您完成处理 A' 和 B 后,将 A' 中的适当元素与 B[0] 交换。

    单个副本是O(n),5 次迭代中的每一次都有一个恒定时间操作来进行交换。内存也是O(n)

    【讨论】:

      【解决方案4】:

      最简单的做法是从使用数组切换到使用List&lt;Integer&gt;。然后,您可以使用subList 方法构造作为原始数组子序列的数组。

      如果你坚持使用数组,你有两种选择:

      1. 添加参数以表示每个数组参数的适用范围的开始和结束索引。然后,您需要重写逻辑以从 start 到 end-1(而不是 0 到 array.length - 1)。
      2. 分配新数组并将数据复制到其中。如果您打算修改数组元素,这是行不通的,而且在任何情况下都需要做很多额外的工作。

      这里有一些代码来展示如何使用List&lt;Integer&gt;

      // autobox each value as an Integer:
      List<Integer> vals = Arrays.asList(
          new Integer[] {25,50,66,75,100,1000,5000,10000,25000});
      final int len = vals.length();
      
      for (int i=0; i<5; i++){
          evaluate(vals.subList(0, i), vals.subList(i, len));
      }
      
      public void evaluate(List<Integer> train, List<Integer> test){
      
      ....
      }
      

      【讨论】:

      • 传递给函数的值永远不会被修改,所以最终,原始数组值仍然保持不变
      • @Matt9Atkins - 我仍然建议使用某种List。我添加了一些示例代码来展示我的想法。
      • 我曾考虑使用某种列表,但我的函数需要使用数组。所以我可以进行拆分并转换回数组,然后传递给函数,但这将是矫枉过正
      • @Matt9Atkins - 那么,为每个数组传递范围开始和结束索引的选项可能是您最好的选择。
      【解决方案5】:

      查看Arrays API,您可以使用 Arrays.copyOf(..) 方法。

      newArray = Arrays.copyOf(oldArray, oldArray.length-1)
      

      也许这段代码可以帮助你。

          int[] val = { 25, 50, 66, 75, 100, 1000, 5000, 10000, 25000 };
          int[] firstArray = new int[val.length-1];
          int[] SecondArray = new int[1];     
          //iterates the whole array set to 5 if needed
          for (int n = 0; n < val.length; n++) {
              SecondArray[0] = val[val.length-n-1];
              for(int x = 0, firstArrayCounter= 0; x < val.length; x++){
                  if(val[x]!=SecondArray[0]){                 
                      firstArray[firstArrayCounter] = val[x];
                      firstArrayCounter++;
                  }       
              }
              //prints what is in the arrays                      
              for (int i = 0; i < firstArray.length; i++)
                  System.out.print(firstArray[i] + " ");
              System.out.println("\n"+SecondArray[0]);
          }
      

      祝你好运!

      【讨论】:

        【解决方案6】:

        可以使用Apache commons的ArrayUtils,代码示例如下:

            private static int[] val = { 25, 50, 66, 75, 100, 1000, 5000, 10000, 25000 };
            private static int[] test = {};
        
            public static void evaluate(int[] train, int[] test) {
                for (int i = 0; i < train.length; i++) {
                    System.out.print(train[i] + ",");
                }
                System.out.println("");
                for (int i = 0; i < test.length; i++) {
                    System.out.print(test[i] + ",");
        
                }
                System.out.println("");
                System.out.println("-----");
            }
        
            public static void main(String[] args) {
        
                for (int i = 0; i < 5; i++) {
                    if (!ArrayUtils.isEmpty(test))
                        ArrayUtils.remove(test, 0);
                    evaluate(ArrayUtils.remove(val, val.length - 1 - i), ArrayUtils.add(test, val[val.length - 1 - i]));
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-28
          • 2021-07-08
          • 2015-09-08
          • 2019-09-03
          相关资源
          最近更新 更多