2016-03-21 19 views
0

Tüm olası dizin konumlarını rastgele bir boyutta ve rastgele boyut boyutu dizisinde bulmak için bir yol bulmak istiyorum. Örneğin: çıktı olurdu böyleceTüm olası dizi endeks konumlarını verimli bir şekilde alma

int [][][] myArray = new int [2][3][2] 

i sonra tüm olası dize dizini pozisyonları isteyeceği bir şey gibi:

0,0,0 
1,0,0 
0,1,0 
0,2,0 

ve benzeri, yani temelde dizinin tüm pozisyonları ve bir yol olan çok sayıda gömülü döngüye sahip olmaktan biraz daha verimlidir.

+0

3 boyutlu bir dizi tanımladınız ve 2 boyutlu bir dizi görüntülüyorsunuz. Sanırım temsil ettiğimi düşündüğünüzden daha ince. Bununla birlikte, gerçekten tüm pozisyonları görüntülemeniz mi gerekiyor yoksa tüm olası dizin kombinasyonlarını numaralandırmanız mı gerekiyor? – Makoto

+0

Girişin ne olmasını istiyorsunuz? Bir dizi boyut (2, 3, 2) veya asıl dizinin kendisi mi? –

+0

@Makoto, çıktısının ne olması gerektiği gibi kafa karıştırıcı olmasından dolayı, dizinin nasıl görünmesi gerektiğini göstermediğinden, tüm olası indeks kombinasyonunu gösteriyor. Ben hepsini çok göstereceği gibi göstermedim. Ama çıktı sadece olası dizin kombinasyonlarına ihtiyacım var. –

cevap

1

çok boyutlu diziler fiziksel tek boyut bellekte bulunan, sözdizimi şeker gibidir:

final int dim1 = 2; 
final int dim2 = 3; 
final int dim3 = 4; 
final int[][][] myArray = new int[dim1][dim2][dim3]; 

for (long i = 0; i < ((long) dim1 * dim2 * dim3); i++) { 
    long idx = i; 
    final int i3 = (int) (idx % dim3); 
    idx /= dim3; 
    final int i2 = (int) (idx % dim2); 
    idx /= dim2; 
    final int i1 = (int) idx; 
    System.out.println(i1 + "," + i2 + "," + i3); 
} 

not: Bu kod % ve / kullanır

yüzden böyle bir şey deneyebilir oldukça yavaş olan operatörler, ancak boyutlarınız 2 gücüyse, & ve >>> ile değiştirip daha hızlı çalışacak şekilde iç içe döngüler yapamazsınız

başka varyantı:

final int dim1 = 2; 
final int dim2 = 3; 
final int dim3 = 4; 
final int[][][] myArray = new int[dim1][dim2][dim3]; 

int i1 = 0; 
int i2 = 0; 
int i3 = 0; 
for (long i = 0; i < ((long) dim1 * dim2 * dim3); i++) { 
    System.out.println(i1 + "," + i2 + "," + i3); 
    i3++; 
    if (i3 == dim3) { 
     i3 = 0; 
     i2++; 
     if (i2 == dim2) { 
      i2 = 0; 
      i1++; 
     } 
    } 
} 

daha hızlı işe yarayabilir, ancak her iki Böyle bir yaklaşımdan yana

0

varyantları kriter onun daha iyi bu yüzden, döngü içine şubesi vardır. Bu şekilde List özel uygulamasının kullanılmasının avantajı, hepsini aynı anda bellekte saklamak zorunda kalmadan tüm olası dizin kombinasyonlarını temsil edebilmenizdir.

public static void main(String[] args) { 
    List<List<Integer>> indices = indices(2, 3); 
    for (List<Integer> list : indices) 
     System.out.println(list); 
} 

public static List<List<Integer>> indices(final int... dimensions) { 
    int s = 1; 
    for (int a : dimensions) 
     s *= a; 
    final int size = s; 
    return new AbstractList<List<Integer>>() { 
     @Override 
     public int size() { 
      return size; 
     } 
     @Override 
     public List<Integer> get(int index) { 
      if (index < 0 || index >= size) 
       throw new IndexOutOfBoundsException(); 
      List<Integer> temp = new ArrayList<>(); 
      for (int d : dimensions) { 
       temp.add(index % d); 
       index /= d; 
      } 
      return Collections.unmodifiableList(temp); 
     } 
    }; 
} 
İlgili konular