1

私は定義されたグリッドのディクショナリを持っています:

Dictionary<Tuple<int, int>, decimal> _details;

キーはItem1 -> ColumnIndexItem2 -> RowIndex です

3 つの辞書項目をグループ化する必要がある複雑なグループ化方法があります。

同じ行から、列は1,2,3または4,5,6または7,8,9または10,11,12であり、それらを処理しますやれ?

私のコード:

private bool IsValid() { // 数量と値、またはその両方ですべての値をチェックします null // 合計が null でないことをチェックします

if (_details.Count() <= 0)
    return false;

var rows = _details.GroupBy(c => c.Key.Item2);
foreach (var item in rows)
{
    foreach (var subItem in item)
    {
        switch (subItem.Key.Item1)
        {
            case 1:
            {
                if (!item.Any(c => c.Key.Item1.In(2, 3)))
                    return false;
                break;
            }
            case 2:
            {
                if (!item.Any(c => c.Key.Item1 == 1) || item.Any(c => c.Key.Item1 == 3))
                    return false;
                break;
            }
            case 3:
            {
                if (!item.Any(c => c.Key.Item1 == 1) || item.Any(c => c.Key.Item1 == 2))
                    return false;
                break;
            }
                        // code continues the same way up to 12 
        return true;
    }

編集:データ

_details = new Dictionary<Tuple<int, int>, decimal>();

_details.Add(new Tuple<int, int>(1, 1), 10);
_details.Add(new Tuple<int, int>(2, 1), 10);
// if abouve data only added return true
_details.Add(new Tuple<int, int>(4, 2), 10);
_details.Add(new Tuple<int, int>(6, 2), 10);
// still true 
_details.Add(new Tuple<int, int>(10, 4), 10);
_details.Add(new Tuple<int, int>(11, 4), 10);
//still true
_details.Add(new Tuple<int, int>(2, 2), 10);
_details.Add(new Tuple<int, int>(8, 1), 10);           
_details.Add(new Tuple<int, int>(10, 3), 10);
// adding the last 3 return false

ここに画像の説明を入力

4

1 に答える 1

2

数値のセットをビットのセットとして解釈することで、これをいくらか単純化できます。

小さい数値のセット 0..11 を単一の数値に変換して、数値がセットに存在intする場合、kビット番号kが に設定されるようにしintます。それ以外の場合、対応するビットはゼロです。

たとえば、イラストは010 001 101 0112 進数の数値に変換されます (スペースはグループを区切るためのものです)。セル #1 が左側にあり、ビット番号 0 が右側にあるため、ビットが逆になっていることに注意してください。これは 8 進数に対応し2153ます (ビットの 3 倍を考慮する場合は 8 進数が便利です)。

そのようなマスクを指定すると、ビットの各トリプレットの有効性を確認できます。、、、、、、、、の8つの可能000性しかありません。、、のみが有効です。001010011100101110111000011101

これを実装する 1 つの方法を次に示します。

var rows = _details.GroupBy(c => c.Key.Item2);
foreach (var item in rows) {
    // Note the -1: this is because your items are numbered 1..12,
    // while bits are numbered 0..11
    int mask = item.Aggregate(0, (p, v) => p | (1 << (v.Key.Item1-1)));
    for (i = 0 ; i != 4 ; i++) {
        int bits = (mask >> (3*i)) & 7; // Shift, and take the las three bits
        if (bits != 0 && bits != 3 && bits != 5) {
            return false;
        }
    }
}
return true;
于 2013-07-28T12:50:55.507 に答える