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 からエース) に 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 │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴──┴──┴──┘

4 つの名詞または配列を持つ構造体が必要ですが、どちらが長さ 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

コードの for ループで次のプロセスが必要です。

   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 x 4 配列の範囲番号が含まれています。ハートが選択されたら、行 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

検索タスクを見越して結果を保存する方法を学びたいと思います。各メンバーに整数のボード番号 (1 ~ 36 の数字) と 4 つの文字列が含まれる C 構造体を作成できますか? たとえば、以下の構造体は機能しますか? もしそうなら、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
4

1 に答える 1

0

この質問は、「どうすれば X を実行できますか?」という質問からかなり離れているように感じます。そして、「私のためにXをしてください」に本当に近づき始めました。そうは言っても、私は昨夜それについて少し考えました。あなたが前進する際に役立つかもしれないいくつかの考えを共有したいと思います.

まず、はい、これは任意の数の C 構造体でモデル化できます。すでにそれらのいくつかを調べました。あなたがまだ提案していない考えの 1 つは、ビットマップを使用して手を表すことです。デッキには 52 枚のカードがあります。手を格納する 1 つの方法は、64 ビット整数を使用し、52 ビットをデッキ内のカードに対応させることです。特定のカードに対応するビットがセットされている場合、手札には特定のカードが含まれています。これらのハンドの検索は、単純なビットごとの AND 演算になります。インターフェイスを工夫して、 C を使用unionして基本表現を 64 ビット型にする一方で、サブセット (スーツや位置など) への構造化されたアクセスを可能にすることもできます。

とはいえ、ここでのデータセットのサイズを考えると、パフォーマンスの問題に陥る方法は比較的少なく、少し噛んだ後、最良の、または「最も迅速に検索可能な」データ構造を見つける努力のように感じ始めました時期尚早の最適化を構成しました。このアプリケーションのデータ モデルを完全に拡張された Objective-C オブジェクト グラフにしたとしても、ボード、各ポジション、各ハンド、さらには各カードのオブジェクト インスタンスのクラスを使用しても、「一定サイズ」の問題を解決していることになります ( 「一定時間」のパフォーマンスの機会があります。) IIUC、デッキに 52 枚を超えるカード、4 枚を超えるポジション、または 36 枚を超えるボードがゲームに存在することは決してありません。これはかなり制約の多い問題です。これらの数万のゲームをインポートして、それらすべてに対してクエリを実行することを計画していた場合、

次に、行の内容を解析する際に正規表現を使用しないことをお勧めします[Deal "..."]。正規表現を使用できますか?もちろん。const char*ただし、引用符で囲まれた文字列を として取得し( を参照)、文字を順番に調べる方が簡単-[NSString UTF8String]です。最初の文字は[NSEW]であり、最初の位置を識別します (構造に格納する必要がある可能性がありますが、今のところ不足しています)。それから:無視するのは無用です。次に、スペードのカードを読み始めます。.刻むとスーツが上がります。ヒットする<space>と位置がインクリメントされます。あなたができるこれらの部分を引き出すには正規表現を使用しますが、単純な方法の方がはるかに簡単なので、正規表現で実行することをお勧めします。(コンテキストを考えると、このより単純な方法も大幅に高速であることに言及する必要がありますが、パフォーマンスのためだけにこの方法を選択すると、時期尚早の最適化になると私は主張します。したがって、パフォーマンスのためにこの方法を選択するのではなく、単純にするために選択してください。 !)

最後に、私の 2 分間の google-fu はオープン ソースの C PBN 読み取り実装 (したがってモデル データ構造) を見つけることができませんでしたが、それが適切であるとは信じがたいと思います。そこにはありません。私の検索は、「ブリッジ」があまりにも過負荷の英語であるため、やや複雑でした。独自のものを作成するのではなく、そのまま使用するか、インスピレーションとして使用する成熟したオープンソース実装を見つけることができるかどうかを確認することをお勧めします。

編集:

あなたが提案する構造を設定するためのループの可能性を1つ書きました:

// 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.

これが役立つことを願っています。

于 2013-02-05T14:42:58.523 に答える