如何列出包含x-z数字的n个数字列表

时间:2014-03-25 10:12:00

标签: java list for-loop dart

我不确定之前是否曾经问过这个问题,因为我很快就无法解释如何解释这个问题,所以如果有的话,请指出我正确的方向。

所以我想知道如何在Java中创建一个函数来创建列表列表。在这些列表中,我希望数字0-5的所有可能性,但每个列表中只有4个数字。我已经用一种简单的方式完成了这项工作,我可以对4进行硬编码,但我不想硬编码。

这是我用Dart写的。

void generateLists() {
  // possibles holds all the possible options. (1296 options in this case)
  List<List<int>> possibles = new List();
  int size = 4; // This should be the size of each list. This is what I'm asking about.
  int maxNum = 6; // The numbers should go from 0 - maxNum.


  // A terrible amount of for loops within each other to generate these lists.
  for(int i=0; i<maxNum; i++) {
    for(int j=0; j<maxNum; j++) {
      for(int k=0; k<maxNum; k++) {
        for(int l=0; l<maxNum; l++) {
          // Create each list and add it to the possibles.
          List<int> list = new List();
          list.add(i);
          list.add(j);
          list.add(k);
          list.add(l);
          possibles.add(list);
        }
      } 
    }

  }

  // Print all the numbers to show it works.
  for(List<int> l in possibles) {
    print(l);
  }
}

感谢。

6 个答案:

答案 0 :(得分:2)

使用Iterable.expand

main() {
  int size = 4;
  int maxNum = 6;

  // create a list of nums [0,1,2,3]
  final nums = new List.generate(maxNum, (i) => i);

  // init result with a list of nums [[0],[1],[2],[3]]
  Iterable<List> result = nums.map((i) => [i]);
  for (int i = 1; i < size; i++) {
    // every step adds a new element to the result
    // [[0],[1],...] becomes [[0,0],[0,1],[1,0],[1,1],...]
    result = result.expand((e) => nums.map((n) => e.toList()..add(n)));
  }
  result.forEach(print);
}

答案 1 :(得分:1)

此代码只是计算,当最低有效数字变为高时,它会增加下一个比maxNum更重要的数字。

对每个结果迭代外部循环。 在每次maxNum迭代后输入内部循环,并运行最少1次到最大尺寸-1次。

void main() {
  // possibles holds all the possible options. (1296 options in this case)
  List<List<int>> possibles = new List();
  int size = 4; // This should be the size of each list. This is what I'm asking about.
  int maxNum = 6; // The numbers should go from 0 - maxNum.


  List<int> cur = new List<int>(size);
  for(int i = 0; i < size; i++) cur[i] = 0;

  while(cur[0] < maxNum) {
    possibles.add(new List.from(cur));

    int pos = size-1;
    cur[pos]++;
    bool overflow = cur[pos] >= maxNum;
    while(overflow && size > 0 && pos > 0) {
      cur[pos] = 0;
      pos--;
      cur[pos]++;
      overflow = cur[pos] >= maxNum;
    }
  }

  // Print all the numbers to show it works.
  for(List<int> l in possibles) {
    print(l);
  }
}

编辑

此代码预先分配外部列表,以避免必须重复增加列表并稍微加快。

import 'dart:math';

void main() {
  Stopwatch sw = new Stopwatch();
  sw.start();

  // possibles holds all the possible options. (1296 options in this case)
  List<List<int>> possibles;
  int size = 8; // This should be the size of each list. This is what I'm asking about.
  int maxNum = 6; // The numbers should go from 0 - maxNum.

  int resultCount = pow(maxNum, size);
  possibles = new List(resultCount);

  List<int> cur = new List<int>(size);
  for(int i = 0; i < size; i++) cur[i] = 0;

  int cnt = 0;

  while(cur[0] < maxNum) {
    possibles[cnt] = new List.from(cur);
    cnt++;

    int pos = size-1;
    cur[pos]++;
    bool overrun = cur[pos] >= maxNum;
    while(overrun && size > 0 && pos > 0) {
      cur[pos] = 0;
      pos--;
      cur[pos]++;
      overrun = cur[pos] >= maxNum;
    }
  }

  sw.stop();
  print('elapsed: ${sw.elapsed}');

  // Print all the numbers to show it works.
  for(List<int> l in possibles) {
    print(l);
  }
}

答案 2 :(得分:1)

你真的只是在maxNum的基础上从0 ... maxNum ^大小算起。一个简单的方法是生成一个int列表,然后将int映射到新基数中的数字列表。

这里我作了一点使用int.toRadixString()和quiver.strings.padLeft,但它很可读:

import 'dart:math' show pow;
import 'package:quiver/strings.dart' show padLeft;

main() {
  int digits = 4;
  int base = 6;
  var result = new Iterable.generate(pow(base, digits),
      (i) => padLeft(i.toRadixString(base), digits, '0').split('').map(int.parse));
  result.forEach(print);
}

这是一种方法,无需转到字符串并返回:

import 'dart:math' show pow;

List<int> splitDigits(int i, int base, int width) {
  var digits = new List<int>.filled(width, 0);
  int digit = 0;
  while (i != 0) {
    digits[width - ++digit] = i % base;
    i = i ~/ base;
  }
  return digits;
}

main() {
  int digits = 4;
  int base = 6;
  var result = new Iterable.generate(pow(base, digits),
      (i) => splitDigits(i, base, digits));
  result.forEach(print);
}

答案 3 :(得分:0)

您可以定义2维int数组。

int[][] myArray = new int[size][];

然后你只需要循环两次:

for(int i=0; i<size; i++){
   for(int j=0 j<maxNum; j++){
      myArray[i][j] = numberYouWantToAdd;
   }
}

然后您可以通过以下方式访问这些号码:

myArray[whichList][whichItemOfThatList]

答案 4 :(得分:0)

<强>递归

class Permutation<T> {

    Permutation(List<T> pool, int maxElements) {
        this._permutations = [];
        this._permutate([], pool, maxElements);
    }

    List<List<T>> get result => this._permutations;
    List<List<T>> _permutations;

    void _permutate(List<T> permutation, List<T> pool, int maxElements) {
        int n = pool.length;
        if(n > 0 && permutation.length < maxElements) {
            for(int i=0; i<n; i++) {
                List<T> newPermutation = new List.from(permutation);
                newPermutation.add(pool[i]);
                List<T> newPool = new List.from(pool);
                newPool.removeAt(i);
                this._permutate(newPermutation, newPool, maxElements);
            }
        } else {
            this._permutations.add(permutation);
        }
    }
}

void main() {
    List<int> pool = [0,1,2,3,4,5];
    print(new Permutation<int>(pool, 4).result);
}

快速google search为Java提供了许多代码示例。

答案 5 :(得分:-1)

Dart中的相同程序可以用Java编写如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Demonstration
{
  public Demonstration()
  {
    ArrayList<List<Integer>> lists = getListOfList();

    printList(lists);
  }

  // Here's the function implementation you want.
  private ArrayList<List<Integer>> getListOfList()
  {
    ArrayList<List<Integer>> list = new ArrayList<>();

    final int maxSize = 6;

    // The 4 nested loops still take constant time as the value of `maxSize` is constant.
    // I would have created a permutation based solution only if maxSize varied.
    for (int i = 0; i < maxSize; ++i)
    {
      for (int j = 0; j < maxSize; ++j)
      {
        for (int k = 0; k < maxSize; ++k)
        {
          for (int w = 0; w < maxSize; ++w)
          {
            list.add(Arrays.asList(i, j, k, w));
          }
        }
      }
    }

    return list;
  }

  private void printList(ArrayList<List<Integer>> lists)
  {
    lists.forEach(System.out::println); // JDK 8 standard
  }

  public static void main(String[] args)
  {
    new Demonstration();
  }
}

甚至可以使用2D数组来编写程序。以下是如何做到这一点:

public class Demonstration
{
  public Demonstration2()
  {
    int[][] lists = getListOfList();

    printList(lists);
  }

  private int[][] getListOfList()
  {
    final int maxSize = 6;

    int[][] list = new int[maxSize * maxSize * maxSize * maxSize][];
    int rowIndex = 0;

    for (int i = 0; i < maxSize; ++i)
    {
      for (int j = 0; j < maxSize; ++j)
      {
        for (int k = 0; k < maxSize; ++k)
        {
          for (int w = 0; w < maxSize; ++w)
          {
            list[rowIndex++] = new int[]{i, j, k, w};
          }
        }
      }
    }

    return list;
  }

  private void printList(int[][] lists)
  {
    for (int[] list : lists)
    {
      for (int item : list)
      {
        System.out.print(item + " ");
      }

      System.out.println();
    }
  }

  public static void main(String[] args)
  {
    new Demonstration();
  }
}