2014-10-28 65 views
1

我想在地圖上生成5個隨機位置。我只能想出下面的代碼,它使用while (1)break如何獲得N個唯一的隨機數量而不是無限循環?

int map[10][10]; 
memset(map,0,sizeof(map)); 

for (int i = 0; i < 5; i++) { 
    while (1) { 
     int x = RAND_FROM_TO(0, 10); 
     int y = RAND_FROM_TO(0, 10); 
     if (map[x][y]==0) { 
      map[x][y]=1; 
      break; 
     } 
    } 
} 

是否有任何其他的方式做不同時,同樣的工作(1),因爲我已被告知,而(1)很壞。

我只是想找到一個簡單的方法來做到這一點,所以生成隨機數的效率不在我的考慮之下。

+0

爲什麼你認爲你需要'while(1)'?如果刪除'while(1)'和'break'語句會發生什麼? – 2014-10-28 16:21:49

+0

@jeffamaphone我想,如果已經有一個「1」的風險。 – AntonH 2014-10-28 16:22:22

+0

@jeffamaphone因爲我想生成不同的5位置。但我不知道隨機數能滿足它多少次。所以我把(1)放在那裏。 – AlexWei 2014-10-28 16:24:32

回答

3

您可以使用洗牌算法,如Fisher-Yates。我會提出一個修改(截斷)版本,如下所示:

  1. 將您的XY座標表示爲單個數字。
  2. 構建所有座標的列表。
  3. 隨機挑選一個標記它。
  4. 從列表中移除該座標(將其與列表末尾的座標交換,並將列表視爲1個元素更短)
  5. 重複列表中不再包含標記的座標。

這種方式,而不是從0-99選擇5個數字,你選擇一個0-99,0-98,... 0-95,這保證你可以完成5個選擇的任務。

編輯:經過進一步的考慮,第1步不是嚴格必要的,如果你這樣做,你可以在稀疏座標系統上使用它。

2

大約是這樣的內容:

// Create an array of valid indexes for both x and y. 
NSMutableArray *xCoords = [NSMutableArray array]; 
NSMutableArray *yCoords = [NSMutableArray array]; 
for (int i = 0; i < 9; ++i) { 
    [xCoords addObject:@(i)]; 
    [yCoords addObject:@(i)]; 
} 

int map[10][10]; 
memset(map, 0, sizeof(map)); 

for (int i = 0; i < 5; ++i) { 
    // Pick a random x coordinate from the valid x coordinate list. 
    int rand = RAND_FROM_TO(0, [xCoords count]); 
    int x = [xCoords objectAtIndex:rand]; 

    // Now remove that coordinate so it cannot be picked again. 
    [xCoords removeObjectAtIndex:rand]; 

    // Repeat for y. 
    rand = RAND_FROM_TO(0, [yCoords count]); 
    int y = [yCoords objectAtIndex:rand]; 
    [yCoords removeObjectAtIndex:rand]; 

    assert(map[x][y] == 0); 
    map[x][y] = 1; 
} 

注:我使用NSMutableArray因爲最初指定的Objective-C作爲標記。注意2:有效索引數組不是最有效的表示法。改爲使用NSMutableIndexSet作爲練習給讀者。正如使用基本的C原語,如果你不/不能使用NSMutableArray。注意3:這有一個錯誤,如果你第一次選擇x = 3,沒有進一步的選擇將以x = 3結束,即使在x = 3但是y是有效的選項不同。解決這個問題也是一個練習,但這確實能夠滿足您的要求。