5

先日、インタビューで興味深い質問がありましたが、それには本当に苦労しました。(非常に野心的な) 仕様では、C# で 2 つの異なるデータ ストリーム用のパーサーを作成する必要がありました。最初のストリームの構成例を次に示します。

30=EUR/USD,35=3,50=ON,51=12.5,52=13.5,50=6M,51=15.4,52=16.2,50=1Y,51=17.2,52=18.3

ここで、30 は通貨ペア、35 はテナー数、50、51、52 ​​はそれぞれテナー、ビッド、アスクです。ビッドとアスクはオプションですが、正しいテナービッドアスクのタプルには、2 つの価格のうち少なくとも 1 つが含まれます。彼らが提供したフレームワーク コードは、この行を解析した結果が 3 つの個別のオブジェクト (DataElement インスタンス) になることを暗示していました。私はかなり厄介なスイッチステートメントとループベースの実装になりましたが、実際に機能したかどうかはわかりません.

この種のストリームを読み取るには、どのような手法がありますか? 再帰で何かを理解しようとしましたが、うまくいきませんでした。

編集:@evanmcdonnallの回答(承認済み)に基づいて、他の人に役立つ場合に備えて、完全にコンパイルおよび動作するコードを次に示します。

        List<DataElement> Parse(string row)
    {
        string currency=string.Empty;
        DataElement[] elements = null;
        int j = 0;
        bool start = false;
        string[] tokens = row.Split(',');
        for (int i = 0; i < tokens.Length; i++)
        {
            string[] kv = tokens[i].Split('=');

            switch (kv[0])
            {
                case "30":
                    currency = kv[1];
                    break;
                case "35":
                    elements = new DataElement[int.Parse(kv[1])];
                    break;
                case "50":
                    if (start)
                        j++;
                    elements[j] = new DataElement() { currency = currency, tenor = kv[1] };
                    start = true;
                    break;
                case "51":
                    elements[j].bid = double.Parse(kv[1]);
                    break;
                case "52":
                    elements[j].ask = double.Parse(kv[1]);
                    break;
            }
        }
        return elements.ToList();
    }

主な概念は次のとおりです。

  • 各行でアイテムを繰り返す「内部ループ」用に個別のカウンターを用意する
  • その「内側のループ」がいつ始まるかを示すブール値フラグを用意する
  • オブジェクトの配列を割り当てて、長さがわかっているポイント (つまり、タグ 50) で「内部ループ」の結果を格納します。
  • 簡単かつ明確にするために、1 行だけを読み取る関数を用意し、別の関数から複数回呼び出します。
4

2 に答える 2

2

何がそんなにトリッキーなのかわかりません。ただし、私が念頭に置いている多くの条件付きソリューションを使用した非常に具体的な反復よりも優れたソリューションはありません。

最初にコンマで分割し、次にそれらのトークンをループして、それぞれを等号で分割してキーと値のペアを取得します。各キーのチェックと、アイテムの開始/終了時に追跡するブールがあります。通貨を読み取り、それを各オブジェクトに使用します。key を読み取る35と、3 つのオブジェクトがあることがわかります。そのため、それぞれに 3 つのプロパティを持つ 3 つのオブジェクトの配列を割り当てます。テナー、ビッド、アスク。50 に遭遇したら、開始を true に設定する必要があります。そこにある場合は、50、51、および 52 を設定します。以下はサンプルコードです。

  string currency;
  int j = 0;
  bool start = false;
  string[] tokens = line.Split(',');
  for (int i =0; i < tokens.length; i++)
  {
        string[] kv = tokens[i].Split('=')
        if (kv[0] == 30)
             currency = kv[1]
        elseif (kv[0] == 35)
        {
             DateElement[] elements = new DataElement[kv[1]];
        }
        elseif (kv[0] == 50)
        {
             if (start)
                 j++;
             start = true; // flip your flag after the condition so it works for element 0
             elements[j].currency = currency;
             elements[j].tenor = kv[1];
        }
        elseif (kv[0] == 51)
             elements[j].bid = kv[1];
        elseif (kv[0] == 52)     
            elements[j].ask = kv[1];
       // if these optional values aren't there we'll just fall back into the case for 50
      // and everything will work as expected.
  }

コードはきれいではないかもしれませんが、ロジックはかなり単純で、行の形式が正しいと仮定すると、常に機能します。

于 2013-04-22T22:05:37.543 に答える
0

30=ユーロ/米ドル、35=3,50=オン、51=12.5、52=13.5、50=6M、51=15.4、52=16.2、50=1年、51=17.2、52=18.3

私が試してみましょう。私はC#コードを書いているのではなく、私のアプローチの概要を説明しているだけです

これを 2 つのセグメントに分割します Chain1={P0 , P1} と Chain2={P2......PN}

P1 の値に基づいてチェーン 2 を均等に分割します。コンマの位置に基づいています。

substr=Chain.substring(0,Chain2.IndexOf(",", P1=3));

タプルクラス コレクションを作成できます-

here either i can use regex to split the string or simple substring and indexof("=")  to extract value  

var seg= new Tuple<string, int, int, >("ON", 12.5, 13.5);
于 2013-04-22T22:07:16.787 に答える