2017-03-13 60 views
0

我用圖形來解決了這個問題,但不幸的是,現在我卡具有使用二維數組,我有去了解它的最好方法問題:什麼是最快和最簡潔/正確的方式來實現這個模型類支持二維數組中的值?

public class Data { 

    int[][] structure; 

    public data(int x, int y){ 
    structure = new int[x][y] 
    } 

    public <<TBD>> generateRandom() { 
    // This is what my question is about 
    } 

} 

我有一個控制器/事件處理程序類:

public class Handler implements EventHandler { 

    @Override 
    public void onEvent(Event<T> e) { 
    this.dataInstance.generateRandom(); 

    // ... other stuff 
    } 
} 

以下是每種方法都行:

  • Data.generateRandom()將產生在隨機位置,如果所述2D int數組隨機值在未初始化的結構中存在值或者存在等於零的值
  • 如果在結構中沒有可用點,則結構的狀態是最終的(即,在字面意義上的,而不是Java的聲明)

這就是我想知道:

什麼是檢查,如果董事會是充分的最有效方法是什麼?使用圖形,我能夠檢查O(1)上的板是否已滿,並在最壞情況O(n^2 - 1),最佳情況O(1)下獲得可用但也是隨機的位置。顯然現在陣列改善n^2是困難的,所以我現在只關注執行速度和LOC。會以最快的方式做到這一點,現在使用流等以檢查整個二維數組:

Arrays.stream(board).flatMapToInt(tile -> tile.getX()).map(x -> x > 0).count() > board.getWidth() * board.getHeight() 
+1

即使突變已經選擇的元素,如果你不使用一些輔助數據結構,確定性地發現一個真正隨機可用的元素需要搜索超過一百萬個元素的整個數組;如果只允許持續存儲,則爲兩次。這是一個瓶頸。你是否願意花費大量的時間?因爲這將是需要的。在你已經想出如何解決主要問題之後,你如何構造代碼的好處。 – Gene

回答

1

(1)你絕對可以使用並行流安全地執行陣列上的只讀操作。如果存在任何尚未初始化的空間,您也可以執行anyMatch調用,因爲您只關心(對於isFull檢查)。這可能看起來像這樣:

Arrays.stream(structure) 
     .parallel() 
     .anyMatch(i -> i == 0) 

但是,這仍然是一個n^2解決方案。但是,您可以做的是保留一個可能的空間數量,以便您在第一次初始化空間時遞減。然後isFull檢查將始終是恆定的時間(你只是比較int爲0)。

public class Data { 

    private int numUninitialized; 
    private int[][] structure; 

    public Data(int x, int y) { 
     if (x <= 0 || y <= 0) { 
      throw new IllegalArgumentException("You can't create a Data object with an argument that isn't a positive integer."); 
     } 
     structure = new int[x][y]; 
     int numUninitialized = x * y; 
    } 

    public void generateRandom() { 
     if (isFull()) { 
      // do whatever you want when the array is full 
     } else { 
      // Calculate the random space you want to set a value for 
      int x = ThreadLocalRandom.current().nextInt(structure.length); 
      int y = ThreadLocalRandom.current().nextInt(structure[0].length); 
      if (structure[x][y] == 0) { 
       // A new, uninitialized space 
       numUninitialized--; 
      } 
      // Populate the space with a random value 
      structure[x][y] = ThreadLocalRandom.current().nextInt(Integer.MIN_VALUE, Integer.MAX_VALUE); 
     } 
    } 

    public boolean isFull() { 
     return 0 == numUninitialized; 
    } 
} 

現在,這是我的理解是在每次調用時generateRandom你採取隨機空間(包括那些已經初始化)。如果您每次調用時都應該只選擇一個隨機未初始化的空間,那麼您最好保留所有可能的網格位置的輔助數據結構,以便您可以輕鬆找到下一個隨機的開放空間並分辨結構已滿。 (2)哪種通知方法適合讓其他類知道數組現在是不可變的?這很難說,因爲它取決於用例以及所用系統其餘部分的架構。如果這是一個MVC應用程序,它在數據模型和控制器之間大量使用通知,那麼觀察者/可觀察模式很有意義。但是如果你的應用程序不在其他任何地方使用,那麼也許只是讓關心檢查isFull方法的類更有意義。

(3)Java在創建和釋放短暫對象方面非常高效。然而,由於數組可能非常大,我想說,每次更改數組時,分配一個新的數組對象(並複製數據)看起來效率最低。Java有能力做一些功能類型的編程(特別是在Java 8中包含lambda表達式),但只能使用不可變對象和純功能類型,就像Java的平方釘住圓孔一樣。

+0

感謝您的輸入!這實際上是一個CS任務,我有點沮喪,我不得不重寫,以便在打破需要2d陣列/ n^2的標準接口後與其他學生兼容。我的教授有點老派(即

相關問題