我有一个有坐标的对象列表。对象是这样的:
private class Seats
{
public string Code { get; set; }
public long PosX { get; set; }
public long PosY { get; set; }
}
对于列表中的所有座位,我需要知道它们是4个一组,在水平行中。例如,下面的列表很好:
List<Seats> good = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0}
};
下面的列表也可以(两行):
List<Seats> good = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0},
new Seats {Code = "B1", PosX = 0, PosY = 1},
new Seats {Code = "B2", PosX = 1, PosY = 1},
new Seats {Code = "B3", PosX = 2, PosY = 1},
new Seats {Code = "B4", PosX = 3, PosY = 1}
};
下面的列表也没问题(同一行,两组,差距为(4,0)):
List<Seats> good = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0},
new Seats {Code = "A6", PosX = 5, PosY = 0},
new Seats {Code = "A7", PosX = 6, PosY = 0},
new Seats {Code = "A8", PosX = 7, PosY = 0},
new Seats {Code = "A9", PosX = 8, PosY = 0}
};
但是下面的列表不合适,因为(3,0)存在差距:
List<Seats> bad1 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A5", PosX = 4, PosY = 0}
};
下面的列表也不行,因为有五个:
List<Seats> bad2 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0},
new Seats {Code = "A5", PosX = 4, PosY = 0}
};
下面的列表也不正常,因为四个座位需要在水平行中:
List<Seats> bad3 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "B1", PosX = 0, PosY = 1},
new Seats {Code = "B2", PosX = 1, PosY = 1}
};
为了检查4的乘法(它可以是8,12,......),我可以这样做:
list.Count % 4 == 0
但我需要帮助来检查'连续'。
答案 0 :(得分:1)
按Y值拆分列表中的所有值。
然后为每个拆分列表:
假设点是有序的(如在您的示例中),至少对于X坐标。
答案 1 :(得分:1)
功能:
static bool IsGood(List<Seats> seats)
{
int size = 4;
return seats.GroupBy(s => s.PosY)
.Select(yGroup => new {
yCount = yGroup.Count(),
xCount = yGroup.GroupBy(x => x.PosX).Count(),
xDistance = yGroup.Max(x => x.PosX) - yGroup.Min(x => x.PosX)
})
.All(g => g.yCount == size && g.xCount == size && g.xDistance == size - 1);
}
测试:
Console.WriteLine("{0} is {1}", "good1", IsGood(good1) ? "good" : "bad");
Console.WriteLine("{0} is {1}", "good2", IsGood(good2) ? "good" : "bad");
Console.WriteLine("{0} is {1}", "bad1", IsGood(bad1) ? "good" : "bad");
Console.WriteLine("{0} is {1}", "bad2", IsGood(bad2) ? "good" : "bad");
Console.WriteLine("{0} is {1}", "bad3", IsGood(bad3) ? "good" : "bad");
Console.WriteLine("{0} is {1}", "bad4", IsGood(bad4) ? "good" : "bad");
输出:
good1 is good
good2 is good
bad1 is bad
bad2 is bad
bad3 is bad
bad4 is bad
测试数据:
List<Seats> good1 = new List<Seats>
{
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0}
};
List<Seats> good2 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0},
new Seats {Code = "B1", PosX = 0, PosY = 1},
new Seats {Code = "B2", PosX = 1, PosY = 1},
new Seats {Code = "B3", PosX = 2, PosY = 1},
new Seats {Code = "B4", PosX = 3, PosY = 1}
};
List<Seats> bad1 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A5", PosX = 4, PosY = 0}
};
List<Seats> bad2 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "A3", PosX = 2, PosY = 0},
new Seats {Code = "A4", PosX = 3, PosY = 0},
new Seats {Code = "A5", PosX = 4, PosY = 0}
};
List<Seats> bad3 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 1, PosY = 0},
new Seats {Code = "B1", PosX = 0, PosY = 1},
new Seats {Code = "B2", PosX = 1, PosY = 1}
};
List<Seats> bad4 = new List<Seats> {
new Seats {Code = "A1", PosX = 0, PosY = 0},
new Seats {Code = "A2", PosX = 0, PosY = 0},
new Seats {Code = "B1", PosX = 0, PosY = 0},
new Seats {Code = "B2", PosX = 0, PosY = 0}
};
答案 2 :(得分:1)
首先,检查PosY是否完全相同,然后检查最后一个PosX是否等于第一个PosX +元素数。
即。如果第一个X是2,并且有4个元素,那么最后的X必须是5。
public bool IsGoodSeats(List<Seats> seats, int goodNumber)
{
if(seats.Count( seat => seat.PosY == seats[0].PosY) == goodNumber)
{
//var orderedSeats = seats.OrderBy(seat => seat.PosX);
//return orderedSeats.Last().PosX == (orderedSeats.First().PosX + goodNumber - 1);
// Actually Min and Max are better than ordering the list twice
return seats.select(s => s.PosX).Max() == (seats.select(s => s.PosX).Min() + goodNumber - 1);
}
return false;
}
更新我看到问题已经扩展,现在允许在每组4之后出现差距。 假设列表按Y排序,然后是X,样本是。
public bool IsAllGoodSeats(List<Seat> seats, int goodNumber)
{
if(seats.Count % goodNumber != 0)
return false;
for(int i = 0; i < seats.Count; i += goodNumber)
{
var subSeats = new List<Seat>();
for(int s = i; s < i + goodNumber; s++)
subSeats.Add(seats[s]);
if(!IsGoodSeats(subSeats, goodNumber))
return false;
}
return true;
}
另外因为我们现在假设座位按Y排序,然后X,IsGood座位可以成为
public bool IsGoodSeats(List<Seats> seats, int goodNumber)
{
if(seats.Count( seat => seat.PosY == seats[0].PosY) == goodNumber)
{
return seats[goodNumber - 1].PosX == (seats[0].PosX + goodNumber - 1);
}
return false;
}
答案 3 :(得分:1)
我认为你必须做多次检查:
var result = seats.GroupBy(seat => seat.PosY)
和result.All(group => group.Count == 4)
检查每个PosY中是否有四个元素。var noGaps = groups.All(group => SeatGapFinder.Check(group.OrderBy(seat => seat.PosX)));
这里是差距查找器的代码:
public static class SeatGapFinder
{
public static bool Check(IEnumerable<Seats> seats)
{
using (var enumerator = seats.GetEnumerator())
{
if (!enumerator.MoveNext())
{
return false;
}
var lastValue = enumerator.Current.PosX;
while (enumerator.MoveNext())
{
lastValue++;
if (enumerator.Current.PosX != lastValue)
{
return false;
}
}
return true;
}
}
}
由于间隙查找器始终使用最后一个值,它还可以处理从7 - 11开始的行等。您只需要确保座位是有序的(这将通过{{1完成) }})。
答案 4 :(得分:0)
这个函数应检查一系列整数中有四个,它们都是不同的,并且min比最小值小3 - 因此连续有四个。它不需要四个有序。
Func<IEnumerable<int>, bool> rowIsGood = xVals =>
xVals.Count() == 4 &&
xVals.Distinct().Count() == 4 &&
xVals.Min() + 3 == xVals.Max();
这应该按行分组并检查每行是否正常。
bool allRowsGood = seats.GroupBy(s => s.PosY).All(r => rowIsGood(r.Select(s => s.PosX)));
答案 5 :(得分:0)
已编辑:这似乎也通过了添加的good3
案例。
static bool CheckNGroups(IEnumerable<long> groupCont, int n = 4) {
var lst = groupCont.ToList();
lst.Sort();
for(int i = 0; i < lst.Count; i+=n) {
if (lst[i + (n - 1)] - lst[i] != n - 1) return false;
}
return true;
}
/* ... */
var bad = seatlist.GroupBy(s => s.PosY).Select((group) => group.Select(seat => seat.PosX).Distinct()).Any(xs => xs.Count() % 4 != 0 || !CheckNGroups(xs));