我有一个网站,允许多个用户突出显示html文档的多个部分(主要是文本)。
每个突出显示都以开头,字符位置,长度和用户ID标记。
我需要找出最突出显示的部分(大多数重叠的部分),但不同的用户可能没有相同的开始和结束位置。实现此类功能的最佳方法是什么?最好是在c#
答案 0 :(得分:4)
将所有用户的开始和结束选择放入列表中,进行排序。从列表顶部开始,为您找到的每个起点递增一个计数器,递减每个您找到的终点。计数器的最高值是最突出显示/最重叠的文本部分的开头。列表中的下一个项目是该选择的结束。
答案 1 :(得分:1)
这应该将您的数据转换为dthorpe算法所需的结构。如果我有更多的时间,我可能会Linq-ify其余的。
更新:好的,现在完成(如果还没有测试......) 更新2:现在,实际测试和&工作!
// Existing data structure
class StartLen
{
public int Start {get; set;}
public int Len {get; set;}
public string UserId {get; set;}
}
// Needed data struct
class StartEnd
{
public int Pos {get; set;}
public bool IsStart {get; set;}
}
class Segment
{
public int Start { get; set; }
public int End { get; set; }
public int Count { get; set; }
}
int count = 0, lastStart = -1; // next rev, I figure a way to get rid of these.
// this can't be a lambda, it has to be a real function
IEnumerable<StartEnd> SplitSelection(StartLen sl)
{
yield return new StartEnd() {Pos = sl.Start, IsStart = true} ;
yield return new StartEnd() {Pos = sl.Start+sl.Len -1 , IsStart = false} ;
}
List<StartLen> startLen = new List<StartLen>();
// we fill it with data for testing
// pretending to be the real data
startLen.Add(new StartLen() { Start=10, Len=10, UserId="abc123" });
startLen.Add(new StartLen() { Start=15, Len=10, UserId="xyz321" });
var mostSelected =
startLen.SelectMany<StartLen, StartEnd>(SplitSelection)
.OrderBy(se=>se.Pos)
.Select(se=>
{
if (se.IsStart)
{
lastStart = se.Pos;
count++;
}
else
{
count--;
if (lastStart > 0)
{
var seg = new Segment
{ Start = lastStart, End = se.Pos, Count = count };
lastStart = -1;
return seg;
}
}
// Garbage, cuz I need to return something
return new Segment { Start = 0, End = 0, Count = -1 };
})
.OrderByDescending(seg => seg.Count)
.First();
// mostSelected holds Start & End positions
}