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 // 检查总数不为空

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位数 否则,对应的位为零。kint

例如,您的插图将转换为010 001 101 011二进制数字(空格用于分隔组)。请注意,这些位是相反的,因为单元格#1 在左侧,而第 0 位在右侧。这对应于八进制数2153(当您考虑三倍位时,八进制很方便)。

给定这样的掩码,您可以检查每个三元组的有效性。只有八种可能性 - 000, 001, 010, 011, 100, 101, 110, 和111。其中只有000,011101是有效的。

这是实现这一点的一种方法:

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 回答