Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将n大小的数组拆分为k盒_Java_Arrays - Fatal编程技术网

Java 将n大小的数组拆分为k盒

Java 将n大小的数组拆分为k盒,java,arrays,Java,Arrays,我试图编写一个程序,给定一个递增顺序的整数n数组和k框,它将原始数组拆分为连续数字的框,也就是说,它们以输入顺序出现 到目前为止,我已经编写了以下代码 int[] A = {1,2,3,4,5}; int k = 3; int n = 5; for(int i = 0; i <= n - k; i++){ for(int j = i+1; j < n-1; j++){ int[] k1 = Arrays.copyOfRange(A, 0, i+1);

我试图编写一个程序,给定一个递增顺序的整数n数组和k框,它将原始数组拆分为连续数字的框,也就是说,它们以输入顺序出现

到目前为止,我已经编写了以下代码

int[] A = {1,2,3,4,5};
int k = 3;
int n = 5; 
for(int i = 0; i <= n - k; i++){
   for(int j = i+1; j < n-1; j++){
      int[] k1 = Arrays.copyOfRange(A, 0, i+1);
      int[] k2 = Arrays.copyOfRange(A, i+1, j+1);
      int[] k3 = Arrays.copyOfRange(A, j+1, n);
      System.out.println(Arrays.toString(k1) + "|" + Arrays.toString(k2) + "|" + Arrays.toString(k3));
   }
}
int[]A={1,2,3,4,5};
int k=3;
int n=5;

for(int i=0;i在搜索我遇到的一个位时。您可以使用它来获取输入列表中所有可能的分区。您必须对该代码进行一个小的修改:
holder.addAll(b);
变成
holder.addAll(0,b);
,因此
b
的值被添加到前面而不是末尾,这意味着原始顺序大部分被保留而不是颠倒

之后,您可以使用两个过滤器:

  • 检查(展平)分区中的所有值是否仍按原始顺序排列,删除所有不按原始顺序排列的值
  • 一个是根据块的数量对其进行过滤
    k
    (我使用了Java8+流过滤器)
这里有一个可能的解决方案:

import java.util.*;
import java.util.stream.Collectors;
class Main{
  public static void main(String[] args) {
    int[] A = {1,2,3,4,5};

    // Convert your int-array to an Integer-ArrayList:
    List<Integer> inputList = Arrays.stream(A).boxed().collect(Collectors.toList());

    // Get all possible partitions of this List:
    List<List<List<Integer>>> partitions = partition(inputList);
    System.out.println("All partitions: ");
    prettyPrintPartitions(partitions);

    // Remove all items which aren't in the original order:
    filterPartitionsByOriginalOrder(partitions, A);
    System.out.println("\nPartitions that are in the original order: ");
    prettyPrintPartitions(partitions);

    // Filter them based on amount of chunks `k`:
    for(int k=2; k<A.length; k++){
      System.out.println("\nPartitions of size "+k+" (and also in the original order): ");
      List<List<List<Integer>>> filteredPartitions = filterPartitionsByAmountOfChunks(partitions, k);
      prettyPrintPartitions(filteredPartitions);
    }
  }

  private static void prettyPrintPartitions(List<List<List<Integer>>> partitions){
    for(List<List<Integer>> partition : partitions){
      System.out.println(partition);
    }
  }

  /* Method to get all partitions (all possible ways to divide the list in a variable amount of chunks) of a List of Integers */
  private static List<List<List<Integer>>> partition(List<Integer> inputList) {
    List<List<List<Integer>>> result = new ArrayList<>();
    if(inputList.isEmpty()){
      List<List<Integer>> empty = new ArrayList<>();
      result.add(empty);
      return result;
    }
    // Note that this algorithm only works if inputList.size() < 31
    // since you overflow int space beyond that. This is true even
    // if you use Math.pow and cast back to int.
    int limit = 1 << (inputList.size() - 1);
    // Note the separate variable to avoid resetting
    // the loop variable on each iteration.
    for(int j=0; j<limit; j++){
      List<List<Integer>> parts = new ArrayList<>();
      List<Integer> part1 = new ArrayList<>();
      List<Integer> part2 = new ArrayList<>();
      parts.add(part1);
      parts.add(part2);
      int i = j;
      for(Integer item : inputList){
        parts.get(i%2).add(item);
        i >>= 1;
      }
      for(List<List<Integer>> b : partition(part2)){
        List<List<Integer>> holder = new ArrayList<>();
        holder.add(part1);
        // Add them at the start instead of end so the items hold the original order
        holder.addAll(0, b);
        result.add(holder);
      }
    }
    return result;
  }

  /* Method to filter a List of List of List of Integers (partitions) based on a given amount of chunks `k` */
  private static List<List<List<Integer>>> filterPartitionsByAmountOfChunks(List<List<List<Integer>>> partitions, int k){
    List<List<List<Integer>>> filteredPartitions = partitions.stream()
                                                             .filter(partition -> partition.size() == k)
                                                             .collect(Collectors.toList());
    return filteredPartitions;
  }


  /* Method to remove any partition that (flattened) isn't in the same order as the original given int-array */
  private static void filterPartitionsByOriginalOrder(List<List<List<Integer>>> partitions, int[] A){
    partitions.removeIf(partition -> {
      int index = 0;
      for(List<Integer> part : partition){
        for(int value : part){
          // The value is not at the same index in the original array,
          // so remove the partition
          if(value != A[index]){
            return true;
          }
          index++;
        }
      }
      return false;
    });
  }
}

根据这篇wekipedia帖子和我的类似答案,这里有另一种没有流的方式:

public static void main(String[] args) {
    int[] arr = {1,2,3,4,5,6,7};
    int k = 3;
    permute(arr,k);
}

public static void permute(int [] arr, int k ) {
    int combinations = (int) Math.pow(2, arr.length - 1);
    List<List<List<Integer>>> result = new ArrayList<>();
    for (int i = 0; i < combinations; i++) {
        String operators = String.format("%" + (arr.length - 1) + "s", Integer.toBinaryString(i)).replace(' ', '0');

        int count = 0;
        List<List<Integer>> tempListOfList = new ArrayList<>();
        List<Integer> tempList = new ArrayList<>();
        for (int x = 0; x < operators.length(); x++) {                
            tempList.add(arr[x]);
            if (operators.charAt(x) == '0') {
                if(count < k-1){
                    tempListOfList.add(tempList);
                    tempList = new ArrayList<>();                    
                }
                count++;
            }                
        }            
        tempList.add(arr[arr.length-1]);
        tempListOfList.add(tempList);
        if(count == k-1){
            result.add(tempListOfList);                
        }            
    }
    for(List<List<Integer>> parts: result){
        System.out.println(parts);
    }
}
publicstaticvoidmain(字符串[]args){
int[]arr={1,2,3,4,5,6,7};
int k=3;
排列(arr,k);
}
公共静态无效置换(int[]arr,int k){
int组合=(int)Math.pow(2,arr.length-1);
列表结果=新建ArrayList();
对于(int i=0;i<组合;i++){
字符串运算符=String.format(“%”+(arr.length-1)+“s”,Integer.toBinaryString(i)).replace(“,”0”);
整数计数=0;
List templastistoflist=new ArrayList();
List templast=new ArrayList();
对于(intx=0;x
一个框中有多少个元素?它们应该大小相等吗?@arslanbenzer这些框不能是空的,所以至少有一个元素,并且没有上限。您可以解释原始元素应该放在哪个数组中的属性吗?如果数组中有3个框和10个元素,那么整数应该如何分布?3-3-4或者8-1-1,有很多可能性如果你在寻找一个数据结构,数组的
列表应该可以。如果你像其他人所说的那样要求算法来填充这些框,你应该告诉我们。很好,对另一个答案给予肯定,但随后添加了很多有用的内容!它工作得很好,但有一点细微之处问题。它生成所有可能性([[4,5],[3],[1,2]])这是无效的,因为框必须有连续的数字,也就是说,它们出现在输入顺序中。因此,如果我合并所有框,我将以原始顺序得到原始数组。我希望你得到我想要的say@JonDoe啊,好的,是的,我明白你的意思。我在社区制作的05AB1E程序中也有同样的东西这就是为什么我在程序的其余部分添加了额外的
gĀP}
,以过滤分区,并只保留与输入列表相等的分区。我将尝试在Java代码中为第二个过滤器想出一些东西(尽管可能使用不同的分区方法会更好地提高性能)@JonDoe好的,我添加了第二种方法来删除任何不符合原始顺序的分区。如果以某种方式将这三种方法组合在一起可能会更好地提高性能,因此,与其创建一个包含所有分区的列表并删除/过滤我们不需要的分区,不如以某种方式将这三种方法组合在一起,以避免在开始时创建这些分区使用,但我不知道实现此合并的可行方法是什么。现在应该这样做。@KevinCruijssen完美。非常感谢!啊,使用二进制字符串的方法非常好。代码也比我的要紧凑得多,这对我来说是一个加号(尤其是因为我是)。;)我的+1!效果也很好。我想知道是否有办法对其进行优化。主for循环经过2^n个循环