2013-02-04 56 views
1

更新1在字符串

建立在以前的更新與焦炭循環,我想我有一個更好地瞭解這樣做,但我需要回答這個問題。在當前的for循環中有一個名爲tstring的變量。我需要做一些類似於以下的事情,但它不起作用。我收到錯誤Collection expression type 'NSString *' may not respond to countByEnumeratingWithState:objects:count:'如何修復for子句?

for (NSUInteger i = 1; i < match.numberOfRanges; ++i) 
     { 
      NSRange matchedRange = [match rangeAtIndex: i]; 
      NSString* tstring = [string substringWithRange: matchedRange]; 
      for (char* suit in tstring){ // error here ******** 
      NSLog(@"char: %@",suit);} 
      NSLog(@"range %lu string: %@", (unsigned long)i, tstring); 
     } 

更新1

更新0

這裏是另一種方法,不需要進行搜索,但我仍然沒有任何想法如何做到這一點的方法for循環的上下文。

我需要一個字典,如下面的示意圖表示,它與每個卡(2到Ace)從0到12的整數相關聯。(我想我知道如何在C中創建字典;也許不在Objective-C中。 )

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬──┬──┬──┐ 
│0│1│2│3│4│5│6│7│8│9│10│11│12│ 
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼──┼──┼──┤ 
│2│3│4│5│6│7│8│9│T│J│Q │K │A │ 
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴──┴──┴──┘ 

我需要一個結構與四個名詞或數組,我不知道哪個,每個長度13這樣。這與原始結構類似,但現在成員是卡牌套裝,而不是玩家的職位。

struct board { 
int num; 
char spade[13] 
char heart[13] 
char diamond[13] 
char club[13] 
}; 

假設局數1以下的交易,

Q952.652.KJT4.95 T.KQT84.A865.J73 K8763.A7.Q.KQT84 AJ4.J93.9732.A62

我需要爲我的代碼迴路在下面的過程。

spade[10] = N 
    spade[7] = N 
    spade[3] = N 
    spade[0] = N 
    heart[4] = N 
    heart[3] = N 
    etc. 

的問題是,「你怎麼做到這一點的處理在for循環中?」

更新0

下面的代碼爲我工作,但我需要改變它下面描述的目的。我的控制檯輸出(至少,開頭)也在下面提供。從輸出中,我需要以特殊的方式保留範圍1和範圍4到19的結果。

下面的小表包含4乘4陣列中的範圍數字,帶有標記爲黑桃,心形,鑽石,俱樂部和標爲北,東,南和西的列的行。當選擇Heart時,我需要搜索行H的內容以確定該卡是否在N,E,S或W中並報告結果。請注意,在表格中,每個單元格的內容都是一個字符串,其中包含任何內容(爲空)或來自'23456789TJQKA'的一組字母,每行都包含13個字母。表格中的數字僅指當前輸出中的範圍編號。

 N E S W  
S 4 8 12 16 
H 5 9 13 17 
D 6 10 14 18 
C 7 11 15 19 

我想了解如何將結果存儲在預期的搜索任務中。我可以創建一個C結構,每個成員都包含整數板號(1到36之間的數字)和4個字符串嗎?例如,下面的結構可以工作嗎?如果是這樣,那麼如何在objective-c中的這樣的結構中進行搜索?我也可以使用一些幫助填充循環中的結構。

struct board { 
int num; 
char N[13] 
char E[13] 
char S[13] 
char W[13] 
}; 

代碼摘錄如下。

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:toMatch options:NSRegularExpressionDotMatchesLineSeparators error:&error]; 
NSLog(@"pattern length: %lu", (unsigned long)[toMatch length]); 
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])]; 
NSLog(@"number of matches: %lu", (unsigned long)numberOfMatches); 
for (NSTextCheckingResult* match in [regex matchesInString:string options:NSRegularExpressionDotMatchesLineSeparators range:NSMakeRange(0, [string length])]) 
{ 
    NSLog(@"Number of ranges in match: %u", match.numberOfRanges); 
    for (NSUInteger i = 0; i < match.numberOfRanges; ++i) 
    { 
     NSRange matchedRange = [match rangeAtIndex: i]; 
     NSString* tstring = [string substringWithRange: matchedRange]; 
     NSLog(@"range %lu string: %@", (unsigned long)i, tstring); 
    } 
} 

樣本輸出如下。

2013-02-04 16:24:06.583 [71684:11303] string length: 22365 
2013-02-04 16:24:06.591 [71684:11303] pattern length: 347 
2013-02-04 16:24:06.602 [71684:11303] number of matches: 36 
2013-02-04 16:24:06.613 [71684:11303] Number of ranges in match: 20 
2013-02-04 16:24:06.613 [71684:11303] range 0 string: 
[Board "1"] 
[West ""] 
[North ""] 
[East ""] 
[South ""] 
[Dealer "N"] 
[Vulnerable "None"] 
[Deal "N:Q952.652.KJT4.95 T.KQT84.A865.J73 K8763.A7.Q.KQT84 AJ4.J93.9732.A62"] 
2013-02-04 16:24:06.613 [71684:11303] range 1 string: 1 
2013-02-04 16:24:06.613 [71684:11303] range 2 string: N 
2013-02-04 16:24:06.614 [71684:11303] range 3 string: None 
2013-02-04 16:24:06.614 [71684:11303] range 4 string: Q952 
2013-02-04 16:24:06.614 [71684:11303] range 5 string: 652 
2013-02-04 16:24:06.614 [71684:11303] range 6 string: KJT4 
2013-02-04 16:24:06.614 [71684:11303] range 7 string: 95 
2013-02-04 16:24:06.614 [71684:11303] range 8 string: T 
2013-02-04 16:24:06.614 [71684:11303] range 9 string: KQT84 
2013-02-04 16:24:06.614 [71684:11303] range 10 string: A865 
2013-02-04 16:24:06.615 [71684:11303] range 11 string: J73 
2013-02-04 16:24:06.615 [71684:11303] range 12 string: K8763 
2013-02-04 16:24:06.615 [71684:11303] range 13 string: A7 
2013-02-04 16:24:06.615 [71684:11303] range 14 string: Q 
2013-02-04 16:24:06.615 [71684:11303] range 15 string: KQT84 
2013-02-04 16:24:06.616 [71684:11303] range 16 string: AJ4 
2013-02-04 16:24:06.616 [71684:11303] range 17 string: J93 
2013-02-04 16:24:06.616 [71684:11303] range 18 string: 9732 
2013-02-04 16:24:06.616 [71684:11303] range 19 string: A62 
+0

什麼是「搜索任務」在這裏?尋找包含特定卡的電路板?我們需要更多細節。 – ipmcc

+0

每塊板上有52張牌,黑桃,心形,鑽石和俱樂部各有13張。當52張牌中的每一張都是隨機出現時,每次一張,搜索就是找出哪個人獲得了牌:北,南,西或東。 – zerowords

+0

你想根據其中一個'board'結構來查看它,這些結構已經從輸入中的一個'[Deal ...]'行填充了嗎? – ipmcc

回答

0

我覺得這個問題偏離了「我該怎麼做X?」。並開始走近真正接近「請爲我做X」。也就是說,我昨天想了一會兒,我有一些想法可以分享,這可能對你有所幫助,因爲你前進。

首先,是的,這可以用任意數量的C結構建模。你已經探索了其中的幾個。一個人認爲你還沒有提出的是使用位圖來表示手。甲板上有52張牌;一種儲存手牌的方法是使用64位整數,並使52位對應於卡組中的卡。如果與特定卡對應的位被設置,則手包含特定的卡。搜索這些手然後變成簡單的按位AND操作。您甚至可以通過界面獲得創意,並使用C union s來使底層表示成爲64位類型,同時允許對子集(如套裝或位置)進行結構化訪問,也許通過說每個套裝對應於底層類型的16位。

這就是說,考慮到這裏的數據集的大小,進入性能問題的方法相對較少,並且在咀嚼它之後,我開始想要努力尋找最好或最快的可搜索「數據結構構成了過早優化。即使你使這個應用程序的數據模型成爲一個完整的Objective-C對象圖,包含每個卡的類,每個位置,每一隻手,甚至是每個卡的對象實例,你仍然在解決一個「恆定大小」的問題「持續時間」表演的機會。)IIUC,甲板上將不會有超過52張牌,也不會超過4個位置,在遊戲中也不會超過36張。這是一個很好的約束問題。如果您打算導入數以萬計的這些遊戲,然後查詢所有這些遊戲,那麼您挑選的數據結構可能會開始變得重要,但在此時(攝取一款遊戲),當我說任何Mac或者iOS設備即使採用最強大的方法,也不會遇到足夠的性能來消除這個問題。

接下來,我建議放棄使用正則表達式來解析[Deal "..."]行的內容。你可以使用正則表達式嗎?當然。但是,將引用的字符串作爲const char*(請參閱-[NSString UTF8String])並依次遍歷字符會更簡單:第一個字符是[NSEW],並標識第一個位置(這可能需要存儲在您的結構中,但缺少這樣的位置遠)。然後一個無用的:忽略。然後開始讀黑桃卡片。當你點擊.遞增套裝。當你點擊一個<space>增加位置。你可能使用正則表達式來拉出這些部分,但簡單的方法是非常直接,我建議與它一起運行。 (根據上下文,我應該提一下,這種簡單的方法也快得多,但我堅持認爲選擇這種方法僅僅是爲了性能會是過早的優化。因此,請不要選擇這種方法來提高性能,而是爲了簡單!)

最後,我覺得我應該提到,雖然我的2分鐘谷歌福未能找到一個開放源碼,C PBN閱讀實現(因此模型數據結構),這是任何好處,我發現它真的很難相信那裏沒有一個。我的搜索有點複雜,「橋」就是這樣一個超載的英語單詞。我可能會建議多嗅探一下,看看你是否可以找到一個成熟的開源實現來使用,或者作爲靈感來使用,而不是自己動手。

編輯:

我寫了一個潛在的循環來填充你提出的結構:

// Your structure, but as a typedef for clarity. 
typedef struct { 
    int num; 
    char spade[13]; 
    char heart[13]; 
    char diamond[13]; 
    char club[13]; 
} board; 

// The quoted string in the [Deal "..."] line; you already know how to get this. 
NSString* dealString = @"N:A8.J762.KQ742.98 KQ53.K93.A85.T52 J97.A8.J963.J743 T642.QT54.T.AKQ6"; 

// Set up some arrays to use as maps between ints and chars... 
// ...for positions: 
const char* const positionIntToCharMap = "NESW"; 
int positionCharToIntMap['Z'] = { 0 }; 
for (int i = 0, len = (int)strlen(positionIntToCharMap); i < len; ++i) positionCharToIntMap[positionIntToCharMap[i]] = i; 

// and cards: 
const char* const cardIntToCharMap = "23456789TJQKA"; 
int cardCharToIntMap['Z'] = { 0 }; 
for (int i = 0, len = (int)strlen(cardIntToCharMap); i < len; ++i) cardCharToIntMap[cardIntToCharMap[i]] = i; 

// and suits: 
const char* const suitIntToCharMap = "SHDC"; 
int suitCharToIntMap['Z'] = { 0 }; 
for (int i = 0, len = (int)strlen(suitIntToCharMap); i < len; ++i) suitCharToIntMap[suitIntToCharMap[i]] = i; 

const char* dealCString = [dealString UTF8String]; 
const size_t dealCStringLen = strlen(dealCString); 

board thisBoard = { 0 }; 

if (dealCStringLen) 
{ 
    char suit = 'S'; // start with spades 
    char pos = dealCString[0]; // first character is starting position 

    for (off_t i = 1; i < dealCStringLen; ++i) 
    { 
     if (dealCString[i] == ':') 
     { 
      continue; 
     } 
     else if (dealCString[i] == '.') // advance the suit 
     { 
      const int currentSuitInt = suitCharToIntMap[suit]; 
      const int nextSuitInt = (currentSuitInt + 1) % 4; 
      suit = suitIntToCharMap[ nextSuitInt ]; 
     } 
     else if (dealCString[i] == ' ') // advance the position and reset the suit 
     { 
      const int currentPosInt = positionCharToIntMap[pos]; 
      const int nextPosInt = (currentPosInt + 1) % 4; 
      pos = positionIntToCharMap[ nextPosInt ]; 
      suit = 'S'; 
     } 
     else // read the card 
     { 
      const char charForCard = dealCString[i]; 
      const int intForCard = cardCharToIntMap[charForCard]; 

      // Mark the current position in the appropriate array. 
      if (suit == 'S') 
      { 
       thisBoard.spade[intForCard] = pos; 
      } 
      else if (suit == 'H') 
      { 
       thisBoard.heart[intForCard] = pos; 
      } 
      else if (suit == 'D') 
      { 
       thisBoard.diamond[intForCard] = pos; 
      } 
      else if (suit == 'C') 
      { 
       thisBoard.club[intForCard] = pos; 
      } 
     } 
    } 
} 

// thisBoard is now populated. 

我希望這有助於。

+0

我同意你所說的一切,尤其是這個問題偏離了很多。我有正則表達式工作,所以我認爲沒有必要簡化它,你似乎同意。我認爲現在處理的需求就像你說的那樣,非常有限,效率不是非常必要的。我想我可以在字典中使用我在「update 0」中概述的方法,並避免需要搜索,如果我可以用正確位置的值NESW填充新的結構。要做到這一點,我需要幫助儘可能填充結構的最內層for循環的結構。你能告訴我該怎麼做嗎? – zerowords

+0

我在Objective-C上的源碼告訴我一個字符串實際上是一個數組,我可以用「indexOfObject:」遍歷數組。但是我沒有看到如何「遍歷」每個字符串(並使用字符串中的每個字符),這是由這個循環產生的,因爲字符串也不同於數組。 – zerowords

+0

沒關係,我明白了。 (for NSUInteger i = 0; i zerowords