2013-03-26 81 views
1

我正在創建一個iPhone遊戲,並創建了具有各自屬性的Line對象,例如它們的(x,y)座標和「連接」數組詳細介紹當前正在觸摸'this'行的所有其他行。在Objective-C中循環遍歷X個嵌套數組的動態方法

我想要做的是從起始行(Line1)開始,遍歷其他連接行的數組,然後從那裏隨機選擇另一行(如Line2)。然後,我想重複這個邏輯並查看所有Line2s連接的線陣列,並選擇另一條連接線,除了它剛剛來自的線(即不是Line1)。總之,我想看看一組線完整了「電路」,那就是,在最後一行==第一所以

僞代碼:

Line1-> Line1Array-> Line2-> Line2Array-> Line3-> Line3Array-> Line4-> Line4Array-> Line1->停止!

可視化表示:

lines

我已經成功地得到它通過辛勤工作的編碼這個特殊的視覺表現我已經如下圖所示。問題是,電路可能並不總是由4條邊組成,而且這種解決方案看起來並不健壯也不優雅。如果我有一個方法可以迭代X個數組並簡單地返回是否檢測到電路,那就太好了。我遇到了使用遞歸,但由我如何將它應用於這個特定問題而感到困惑。

實際代碼:

for(Line* line1 in allLines) { 

    // contains all lines connected to this line 
    NSMutableArray* connectedTo = [line1 getConnectedTo]; 

// lets loop through all lines connected to our line1 
for(Line* line2 in connectedTo) { 

     // contains all lines connected to line2 
     NSMutableArray* secondConnectedTo = [line2 getConnectedTo]; 

// lets loop through all lines connected to line2 
for(Line* line3 in secondConnectedTo) { 

// don't look back at line1 from line2 
if([line3 getLineCreationNumber] != [line1 getLineCreationNumber]) { 

    // contains all lines connected to the 3rd line 
    NSMutableArray* thirdConnectTo = [line3 getConnectedTo]; 

// lets loop through all lines connected to our 3rd line 
for(Line* line4 in thirdConnectTo) { 

     // contains all lines connected to the 4th line 
     NSMutableArray* fourthConnectTo = [line4 getConnectedTo]; 

// 'line5' here is actually the same as line1 so check to confirm for circuit 
for(Line* line5 in fourthConnectTo) {     
     if([line5 getLineCreationNumber] == [line1 getLineCreationNumber]) { 
     CCLOG(@"CIRCUIT FOUND"); 
}}}}}}} 

更新的代碼:

喜@dasblinkenlight感謝您的回答,它是有用的。我覺得我非常接近解決這個問題,但我仍然面臨一個問題。下面的代碼迄今(注意我最初傳遞一個空數組作爲每個指令):

-(bool) findCircuit:(NSMutableArray*) circuit { 

for(Line* l in [self getConnectedTo]) { 

// ensure line isn't in circuit found so far 
if(![circuit containsObject: self]) { 
    // add connected line to end of circuit 
    [circuit addObject: l]; 
    // call find circuit on the latest connected line 
    if([l findCircuit: circuit]) 
    return YES; 
} else { 
    [circuit removeLastObject]; 
    continue; 
}}} 

我仍然歌廳在後者部件即混淆何時返回YES/NO和如何佔用了。我可以通過輸出線路ID來看到,當有3條線路時,線路正在按照預期進行拖網。這裏的有3條線路的流量:

Line1-> Line2-> Line1-> Line2-> line3-> 2號線

不幸的是,當4線鏈接,程序進入極其緩慢(我可以看到很多線程創建),我得到下面的循環,而不是:

Line1-> Line2-> Line1-> Line4-> Line3-> Line4->線路1

回答

4

遞歸是朝着正確方向邁出的一步。正確應用它的訣竅是認爲你一次只使用一行,並假裝你的遞歸方法已經完成。當你完成之後,這個方法就會完成,所以你的代碼將起作用(起初,這聽起來有點像魔術)。

開始,此方法添加到您的Line類:

-(BOOL)findCircuit:(NSMutableArray*)circuit { 
    ... 
} 

circuit陣列將包含已迄今發現的行列表;呼叫者會將最初爲空的NSMutableArray傳遞給您的功能。 Line對象本身會提供您需要嘗試的連接線路。連接線路上會有一個循環。在每次迭代中,你的代碼將

  • 檢查連接線上,你發現了circuit到目前爲止
  • 如果不是,該連接線增加的circuit結束並致電findCircuit就可以了。這就是魔法發生的地方:你還沒有完成你的方法,但你可以稱它!
  • 如果findCircuit回報YES,你的函數返回YES
  • 如果返回NO,你的循環刪除您添加到circuit的最後一行,並移動到下一個
  • 一旦在所有連接線循環用完而沒有返回YES,該方法返回NO給它的調用者。

就是這樣,真的!在要創建電路的線路上調用此方法,將其傳遞給空的NSMutableArray,然後查看該方法是否返回YES。如果是這樣,你傳遞的數組將包含你的電路。

+0

感謝您的回答。到目前爲止,我已經用我的進度更新了這個問題。我在建立電路檢測方面仍然存在問題。看起來好像我有一個遞歸循環的地方,當4行被鏈接時,我可以看到正在創建的線程數量不變。 – cbros2008 2013-03-27 00:11:43

+0

@ cbros2008您錯過了「return NO;」在你的方法結束時。 – dasblinkenlight 2013-03-27 01:16:24