首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#及时找到所有缺失的片段

C#及时找到所有缺失的片段
EN

Stack Overflow用户
提问于 2015-11-16 04:16:00
回答 2查看 579关注 0票数 3

我需要在10分钟内找到缺失的部分,我想知道最好的路线。

让我说我有三段时间。

  1. 2:30-3:43分段。
  2. 4:25-4:59分钟。
  3. 7:21-9:55分钟。

与C#,我有一个完整的10:20分钟的时间段。当我已经从上面找到了3段时,我需要找到缺少的部分。

因此,我需要用C#计算的分段如下

  1. 0:00 - 2:29分。
  2. 3:44-4:24分钟。
  3. 5:00-7:20段。
  4. 9:56-10:20分钟。

那么,我是否从我已经知道的3段中计算出这4段呢?

我认为我最好的路线是做一个for循环,数到10:20在秒内,并检查当前秒是否存在于3段中。如果没有,将第二个添加到缺少的段中。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-16 09:21:00

我不认为检查每一秒是否属于一个间隔是一个好主意。我认为使用O(n)复杂性可以解决这个问题,当然可以使用一些.NET类来构造输入,从而使一切变得更容易。全小提琴这里

代码语言:javascript
复制
private static List<Tuple<TimeSpan,TimeSpan>> ComputeMissingTimeSpans(List<Tuple<TimeSpan,TimeSpan>> availableIntervals, TimeSpan minSpan, TimeSpan maxSpan)
    {
        List<Tuple<TimeSpan,TimeSpan>> missingTime = new List<Tuple<TimeSpan,TimeSpan>>();
        if(availableIntervals.Count == 0)
        {
            missingTime.Add(new Tuple<TimeSpan, TimeSpan>(minSpan, maxSpan));
            return missingTime;
        }

        foreach(var interval in availableIntervals){
            if((interval.Item1 - minSpan).TotalSeconds > 1 ) 
            {
                missingTime.Add(new Tuple<TimeSpan, TimeSpan>(minSpan, interval.Item1.Add(TimeSpan.FromSeconds(-1))));
            }

            minSpan = interval.Item2.Add(TimeSpan.FromSeconds(1));
        }

        if((maxSpan - minSpan).TotalSeconds > 1)
            missingTime.Add(new Tuple<TimeSpan, TimeSpan>(minSpan, maxSpan));

        return missingTime;
    }

您可以轻松地使此功能适应您的需要。

票数 2
EN

Stack Overflow用户

发布于 2015-11-16 15:05:07

遵循@Matt的好主意,对于同样适合长期和/或周期的更通用的解决方案,您可以创建一个TimeSlot结构:

代码语言:javascript
复制
public struct TimeSlot
{
    private DateTime _start;
    private TimeSpan _span;

    public DateTime Start
    {
        get
        {
            if (_start == null)
            {
                _start = DateTime.Today;
            }
            return _start;
        }

        set
        {
            _start = value;
        }
    }

    public TimeSpan Span
    {
        get
        {
            if (_span == null)
            {
                _span = new TimeSpan(0);
            }
            return _span;
        }

        set
        {
            if (value.Ticks >= 0)
            {
                _span = value;
            }
        }
    }

    public DateTime End
    {
        get
        {
            return Start.Add(Span);
        }
    }

    public TimeSlot(DateTime start, TimeSpan span)
    {
        _start = start;
        _span = span.Ticks >= 0 ? span : new TimeSpan(0);
    }
}

然后,您可以运行这样的代码,首先找到前导段,然后是中间的那些段,最后是尾随段:

代码语言:javascript
复制
public static void SlotDemo()
{
    DateTime startTime = DateTime.Today;
    DateTime endTime = startTime.Add(new TimeSpan(0, 10, 20));

    List<TimeSlot> segments = new List<TimeSlot>();
    segments.Add(new TimeSlot(startTime.Add(new TimeSpan(0, 2, 30)), new TimeSpan(0, 1, 13)));
    segments.Add(new TimeSlot(startTime.Add(new TimeSpan(0, 4, 25)), new TimeSpan(0, 0, 35)));
    segments.Add(new TimeSlot(startTime.Add(new TimeSpan(0, 7, 21)), new TimeSpan(0, 2, 34)));

    for (int i = 0; i < segments.Count; i++)
    {
        Console.WriteLine("s: {0:mm':'ss}  d: {1:mm':'ss}  e: {2:mm':'ss}", segments[i].Start, segments[i].Span, segments[i].End);
    }
    Console.WriteLine();

    if (!segments[0].Start.Equals(startTime))
    {
        TimeSlot firstSlot = new TimeSlot(startTime, segments[0].Start.Subtract(startTime));
        segments.Insert(0, firstSlot);
    }

    for (int i = 0; i < segments.Count; i++)
    {
        Console.WriteLine("s: {0:mm':'ss}  d: {1:mm':'ss}  e: {2:mm':'ss}", segments[i].Start, segments[i].Span, segments[i].End);
    }
    Console.WriteLine();

    for (int i = 0; i < segments.Count - 1; i++)
    {
        if (segments[i].End != segments[i + 1].Start)
        {
            TimeSlot slot = new TimeSlot(segments[i].End, segments[i + 1].Start.Subtract(segments[i].End));
            segments.Insert(i + 1, slot);
            i++;
        }
    }

    for (int i = 0; i < segments.Count; i++)
    {
        Console.WriteLine("s: {0:mm':'ss}  d: {1:mm':'ss}  e: {2:mm':'ss}", segments[i].Start, segments[i].Span, segments[i].End);
    }
    Console.WriteLine();

    int lastIndex = segments.Count - 1;
    if (!segments[lastIndex].End.Equals(endTime))
    {
        TimeSlot lastSlot = new TimeSlot(segments[lastIndex].End, endTime.Subtract(segments[lastIndex].End));
        segments.Add(lastSlot);
    }

    for (int i = 0; i < segments.Count; i++)
    {
        Console.WriteLine("s: {0:mm':'ss}  d: {1:mm':'ss}  e: {2:mm':'ss}", segments[i].Start, segments[i].Span, segments[i].End);
    }
    Console.ReadKey();
}

它将提供这一产出:

代码语言:javascript
复制
s: 02:30  d: 01:13  e: 03:43
s: 04:25  d: 00:35  e: 05:00
s: 07:21  d: 02:34  e: 09:55

s: 00:00  d: 02:30  e: 02:30
s: 02:30  d: 01:13  e: 03:43
s: 04:25  d: 00:35  e: 05:00
s: 07:21  d: 02:34  e: 09:55

s: 00:00  d: 02:30  e: 02:30
s: 02:30  d: 01:13  e: 03:43
s: 03:43  d: 00:42  e: 04:25
s: 04:25  d: 00:35  e: 05:00
s: 05:00  d: 02:21  e: 07:21
s: 07:21  d: 02:34  e: 09:55

s: 00:00  d: 02:30  e: 02:30
s: 02:30  d: 01:13  e: 03:43
s: 03:43  d: 00:42  e: 04:25
s: 04:25  d: 00:35  e: 05:00
s: 05:00  d: 02:21  e: 07:21
s: 07:21  d: 02:34  e: 09:55
s: 09:55  d: 00:25  e: 10:20
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33728447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档