2013-02-04 24 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