2016-10-21 28 views
3

私はアルゴリズムを実践しており、再帰は常に私の弱点です。この問題は、ネストされた配列を単一の配列にまとめることを要求します。これは、O(n^3)[与えられた等しい大きさの3dアレイ]解を与えるループを使用するならば、簡単であろう。Java-再帰を使用して配列を平滑化

しかし、再帰で私は数時間苦労しています。これは私が持っているものです、私は別のソリューションを試して私のコードで手抜きしていることに注意してください、これは私があなたに投稿するにそれを残すことを決めたものです。

私が欲しいのは、現在のコードを修正して正しい出力を得ることができますか、再帰を使用してこのコードを書くのが簡単で難解な方法です。

ボーナス質問ネストされた配列のサイズがわからない場合は、どのように再帰を使用してこの問題について説明しますか? [OK]を

EDIT ので、いくつかのハード(私はしたくないもの)をコードした後、私はこの仕事を得ることができました。しかし、コードは現在ハードコード化されており、非常に面倒です。コードをクリーンアップするか、再帰を使用してこれを解決する簡単な方法に行くのですか?私がREDO-INGのヘルパーメソッドの再帰を使用してこの問題をしようとしています

EDIT2 。私はこのスタイルを使用して、より良い運を持っている場合、私は表示されます

import java.io. * ; 
    import java.util. * ; 
    class Solution { 
    // static int oneLen = 0; 
    //static int twoLen = 0; 
    //static int threeLen = 0; 

    static int oneCnt = 0; 
      static int twoCnt = 0; 
      static int threeCnt = 0; 
      static ArrayList <Integer> result = new ArrayList <Integer>(); 
      public static ArrayList <Integer> flatten(int [][][] arr){ 

    if (oneCnt < arr[threeCnt][twoCnt].length && !(oneCnt == 2 && twoCnt == 2 && threeCnt == 2)) 
    { 


    if (oneCnt == 0 && twoCnt == 0 && threeCnt == 0){ 
    result.add(arr[threeCnt][twoCnt][oneCnt]); 
      oneCnt++; 
      result.add(arr[threeCnt][twoCnt][oneCnt]); 
      System.out.println("Line One"); 
      System.out.println("Count1: " + oneCnt); 
      System.out.println("Count2: " + twoCnt); 
      System.out.println("Count3: " + threeCnt); 
    } 
    oneCnt++; 
      if (oneCnt != 3){ 
    result.add(arr[threeCnt][twoCnt][oneCnt]); } 






    System.out.println("Line One"); 
      System.out.println("Count1: " + oneCnt); 
      System.out.println("Count2: " + twoCnt); 
      System.out.println("Count3: " + threeCnt); 
      flatten(arr); 
    }  else if (oneCnt == arr[threeCnt][twoCnt].length && twoCnt < arr[threeCnt].length - 1){ 


    //oneLen = 0;  
    oneCnt = 0; 
      // twoLen++; 


      twoCnt++; 
      result.add(arr[threeCnt][twoCnt][oneCnt]); 
      System.out.println("Line Two"); 
      System.out.println("Count:1 " + oneCnt); 
      System.out.println("Count:2 " + twoCnt); 
      System.out.println("Count:3 " + threeCnt); 
      flatten(arr); 
    } 

    else if (oneCnt == arr[threeCnt][twoCnt].length && twoCnt == arr[threeCnt].length - 1 && threeCnt < arr.length - 1){ 

    oneCnt = 0; 
    twoCnt = 0; 
      threeCnt++; 
      result.add(arr[threeCnt][twoCnt][oneCnt]); 
      System.out.println("Line Three"); 
      System.out.println("Count:1 " + oneCnt); 
      System.out.println("Count:2 " + twoCnt); 
      System.out.println("Count:3 " + threeCnt); 
      flatten(arr); 
    } 
    return result; 
    } 
    public static void main(String[] args) { 
    int[][][] array = 
    { { {1, 2, 3}, { 4, 5, 6}, { 7, 8, 9} }, 
    { {10, 11, 12}, {13, 14, 15}, {16, 17, 18} }, 
    { {19, 20, 21}, {22, 23, 24}, {25, 26, 27} } }; 
      flatten(array); 
      for (int i = 0; i < result.size(); i++){ 
    System.out.print(result.get(i) + ","); 
    } 
    } 
    } 

出力:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 、16,17,18,19,20,21,22,23,24,25,26,27、

EDIT3 私はほとんどの答えを持っていますが、最後の要素文句を言わないヘルパー再帰を使用した後arraylistに追加します。

import java.io. * ; 
    import java.util. * ; 
    class Solution { 



    static ArrayList <Integer> result = new ArrayList <Integer>(); 
      public static void flatten(int [][][] arr){ 
    int oneLen = 0; 
      int twoLen = 0; 
      int threeLen = 0; 
      flattenHelper(arr, oneLen, twoLen, threeLen); 
    } 

    public static void flattenHelper(int [][][] arr, int oneLen, int twoLen, int threeLen){ 

    if (oneLen < arr[threeLen][twoLen].length - 1){ 
    System.out.println("Line One"); 
      System.out.println("Count:1 " + oneLen); 
      System.out.println("Count:2 " + twoLen); 
      System.out.println("Count:3 " + threeLen); 
      result.add(arr[threeLen][twoLen][oneLen]); 
      flattenHelper(arr, oneLen + 1, twoLen, threeLen); 
    } 
    else if (twoLen < arr[threeLen].length - 1){ 
    System.out.println("Line Two"); 
      System.out.println("Count:1 " + oneLen); 
      System.out.println("Count:2 " + twoLen); 
      System.out.println("Count:3 " + threeLen); 
      result.add(arr[threeLen][twoLen][oneLen]); 
      flattenHelper(arr, oneLen = 0, twoLen + 1, threeLen); 
    }  else if (threeLen < arr.length - 1){ 
    System.out.println("Line Two"); 
      System.out.println("Count:1 " + oneLen); 
      System.out.println("Count:2 " + twoLen); 
      System.out.println("Count:3 " + threeLen); 
      result.add(arr[threeLen][twoLen][oneLen]); 
      flattenHelper(arr, oneLen = 0, twoLen = 0, threeLen + 1); 
    } 

    } 

    public static void main(String[] args) { 
    int[][][] array = 
    { { {1, 2, 3}, { 4, 5, 6}, { 7, 8, 9} }, 
    { {10, 11, 12}, {13, 14, 15}, {16, 17, 18} }, 
    { {19, 20, 21}, {22, 23, 24}, {25, 26, 27} } }; 
      flatten(array); 
      for (int i = 0; i < result.size(); i++){ 
    System.out.print(result.get(i) + ","); 
    } 
    } 
    } 

出力:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 、22,23,24,25,26,

答えて

4

入力構造を変更する必要はなく、配列の寸法を知る必要はありません。あなたはそれがArrayListのを返します、狂気に行くと配列、リスト、およびその他のオブジェクトを混在させることができます:

package stackOverflow; 

import java.lang.reflect.Array; 
import java.util.ArrayList; 
import java.util.List; 

public class Solution 
{ 
    public static void main(String[] args) { 
     int[][][] int3dArray = { { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }, 
       { { 10, 11, 12 }, { 13, 14, 15 }, { 16, 17, 18 } }, 
       { { 19, 20, 21 }, { 22, 23, 24 }, { 25, 26, 27 }, { 28 }, { 29, 30 } } }; 
     String[][] string2dArray = { { "He, llo" }, { "Wo", "rld" } }; 
     String[] stringArray = { "Hello", "World" }; 
     Object[] objectArray = { "Hell", 0, "W", 0, "rld" }; 

     List<Object> mixList = new ArrayList<Object>(); 
     mixList.add("String"); 
     mixList.add(3); 
     mixList.add(string2dArray); 

     System.out.println(flatten(int3dArray)); 
     System.out.println(flatten(flatten(int3dArray))); 
     System.out.println(flatten(3)); 
     System.out.println(flatten(stringArray)); 
     System.out.println(flatten(string2dArray)); 
     System.out.println(flatten(objectArray)); 
     System.out.println(flatten(mixList)); 
    } 

    private static List<Object> flatten(Object object) { 
     List<Object> l = new ArrayList<Object>(); 
     if (object.getClass().isArray()) { 
      for (int i = 0; i < Array.getLength(object); i++) { 
       l.addAll(flatten(Array.get(object, i))); 
      } 
     } else if (object instanceof List) { 
      for (Object element : (List<?>) object) { 
       l.addAll(flatten(element)); 
      } 
     } else { 
      l.add(object); 
     } 
     return l; 
    } 
} 

それは出力:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] 
[3] 
[Hello, World] 
[He, llo, Wo, rld] 
[Hell, 0, W, 0, rld] 
[String, 3, He, llo, Wo, rld] 

はここでも値のコレクションに地図を平らmodified version、です。 SetまたはListのいずれかを出力できます。それは返す

package stackOverflow; 

import java.lang.reflect.Array; 


public class Solution 
{ 
    public static void main(String[] args) { 
     int[][][] array = { { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }, 
       { { 10, 11, 12 }, { 13, 14, 15 }, { 16, 17, 18 } }, 
       { { 19, 20, 21 }, { 22, 23, 24 }, { 25, 26, 27 }, { 28 } } }; 
     flatten(array); 
    } 

    private static void flatten(Object object) { 
     if (object.getClass().isArray()) { 
      for (int i = 0; i < Array.getLength(object); i++) { 
       flatten(Array.get(object, i)); 
      } 
     } else { 
      System.out.print(object + ","); 
     } 
    } 
} 

: 1,2,3,4,5,6,7,8,9,10ここ

は結果のみを表示しますが、void型の戻り私の元のソリューションであり、 、11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,

+1

ありがとう!これはまさに私が持っていたボーナスの質問に答えるという点で私が探していたものです。 – user3051442

+0

リフレクションライブラリの機能と、このソリューションとの関連性を尋ねることはできますか?それに関する文書を探してみて、ありがとう。 – user3051442

+0

ここには良いスタートがあります: https://docs.oracle.com/javase/tutorial/reflect/ これは基本的にJavaを少し「剛性の低い」ものにし、Pythonなどの言語でより一般的に見られるいくつかの方法をもたらしますとRuby。 コンパイル時にすべてを知ることができず、ランタイムを待つ必要があることがあります。このオブジェクトは配列のように見えますが、int [] []かArrayList かもしれませんが、すべての要素を繰り返し処理したいだけです。 –

1

データをintではなくIntegerの配列に変更することができれば、渡された配列の要素を検査し、配列である要素を再帰的に調べるか、そうでなければ直接結果につなげる。

public static ArrayList<Integer> flatten(Object [] arr) { 
    ArrayList<Integer> result = new ArrayList<>(); 

    for (int i = 0; i < arr.length; i++) { 
     if (arr[i].getClass().isArray()){ 
      result.addAll(flatten((Object[])arr[i])); 
     } else { 
      result.add((int)arr[i]); 
     } 
    } 

    return result; 
} 
関連する問題