Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
数字线的C#实现_C#_Range_Line Numbers - Fatal编程技术网

数字线的C#实现

数字线的C#实现,c#,range,line-numbers,C#,Range,Line Numbers,NumberLine是一个表示数字行的类。我想在上面标出不同的数字范围。CheckRange方法应该返回10-25中我标记的部分和我没有标记的部分。在这种情况下,它应该返回未标记的10-20,以及标记的20-25 我怎样才能有效地实现这一点,哪一点做不到o(n) 多谢各位 注意:这不是作业。我需要这个用于我的自定义数据库实现事务。我正在独自学习编程解决方案很简单:将所有突出显示的值添加到or树。我的意思是,当您添加范围(1,3)时,在树中插入整数值1,2和3 检查范围时,只需查找端点值。这需要O

NumberLine
是一个表示数字行的类。我想在上面标出不同的数字范围。
CheckRange
方法应该返回
10-25
中我标记的部分和我没有标记的部分。在这种情况下,它应该返回未标记的
10-20
,以及标记的
20-25

我怎样才能有效地实现这一点,哪一点做不到o(n)

多谢各位


注意:这不是作业。我需要这个用于我的自定义数据库实现事务。我正在独自学习编程

解决方案很简单:将所有突出显示的值添加到or树。我的意思是,当您添加范围(1,3)时,在树中插入整数值1,2和3

检查范围时,只需查找端点值。这需要O(logn)这比O(n)快得多


注意:插入和删除所有takeO(log n)

解决方案很简单:将所有突出显示的值添加到or树。我的意思是,当您添加范围(1,3)时,在树中插入整数值1,2和3

检查范围时,只需查找端点值。这需要O(logn)这比O(n)快得多

注:插入和删除所有takeO(logn)O(n)的意思随元素的数量而变化 O(1)表示恒定时间

我也想不出一个O(1)的方法来实现这一点。

O(n)的意思随着元素的数量而变化 O(1)表示恒定时间


我也想不出一个O(1)方式来实现这一点。

好的,我明白你的意思了

使用非常大的位字段执行此操作

假设您可能的数字范围从1到64,这些数字中的每一个都对应于64位int上该位置的位(1是位0,2是位1)

如果在一个范围中添加一个数字,则打开该位(在您的示例中,您将打开位0到4和19到29)

现在,要检查一个数字范围,您需要在打开该范围的位的情况下创建另一个64位int,并对两位字段执行按位and(&)。结果中的1位是重叠范围

对于大于64的数字,只需放大位数(可能通过使用数组或整数列表)

希望这有帮助:)

更新:可扩展性

假设您使用的是64位体系结构,您可以在一次操作中使用64位和64位整数。理想情况下,您应该使用64位整数

现在,假设您可能的数字范围从1到64000,为此您需要1000个64位整数

现在让我们看几个用例

  • 我想检查70-80的范围。 要做到这一点,我们不需要再检查1000个int,只需要一个int,我们知道我们正在对照数组中的第二个元素检查它

  • 我想检查一下2000-10000的范围 同样,我们只需要一个int,计算它在数组31中的位置(我想),并相应地设置位并进行比较。然后遍历该列表,直到达到10000(位置156?),一路上进行比较,并构建要返回的整数列表

  • 更新2:这不是O(1)

    根据要检查的范围的大小,可以将其实现为O(1)


    然而,使用这个算法,一般情况仍然是O(n)

    好的,我明白你的意思了

    使用非常大的位字段执行此操作

    假设您可能的数字范围从1到64,这些数字中的每一个都对应于64位int上该位置的位(1是位0,2是位1)

    如果在一个范围中添加一个数字,则打开该位(在您的示例中,您将打开位0到4和19到29)

    现在,要检查一个数字范围,您需要在打开该范围的位的情况下创建另一个64位int,并对两位字段执行按位and(&)。结果中的1位是重叠范围

    对于大于64的数字,只需放大位数(可能通过使用数组或整数列表)

    希望这有帮助:)

    更新:可扩展性

    假设您使用的是64位体系结构,您可以在一次操作中使用64位和64位整数。理想情况下,您应该使用64位整数

    现在,假设您可能的数字范围从1到64000,为此您需要1000个64位整数

    现在让我们看几个用例

  • 我想检查70-80的范围。 要做到这一点,我们不需要再检查1000个int,只需要一个int,我们知道我们正在对照数组中的第二个元素检查它

  • 我想检查一下2000-10000的范围 同样,我们只需要一个int,计算它在数组31中的位置(我想),并相应地设置位并进行比较。然后遍历该列表,直到达到10000(位置156?),一路上进行比较,并构建要返回的整数列表

  • 更新2:这不是O(1)

    根据要检查的范围的大小,可以将其实现为O(1)


    然而,使用这种算法,一般情况下仍然是O(n)

    我不确定应用程序的具体细节,但我的直觉告诉我,这在数据库中处理会更好,因为它是基于集合的操作

    选择
    *
    来自Numberline
    哪里
    编号\u组=@group\u id
    标记=1
    和编号>=@min\u范围
    
    我不确定这个应用程序的具体细节,但我的直觉告诉我,在数据库中处理这个问题会更好,因为它是一个基于集合的操作

    选择
    *
    来自Numberline
    哪里
    编号\u组=@group\u id
    标记=1
    和编号>=@min\u范围
    和数字使用哈希集:

    但它应该会让您走上正确的轨道。

    使用哈希集:

    但它应该是g
    NumberLine line = new NumberLine();
    line.AddRange(1, 5);
    line.AddRange(20, 30);
    
    line.CheckRange(10, 25);
    
    Select
    *
    from numberlines
    where 
    number_group = @group_id
    marked = 1
    and number >= @min_range
    and number <= @max_range
    
    public class NumberLine : HashSet<int>
    {
        public void AddRange(int start, int end)
        {
            int count = (end-start)+1;
    
            UnionWith(Enumerable.Range(start, count));
        }
    
        public IEnumerable<int> CheckRange(int start, int end)
        {
            NumberLine other = new NumberLine();
    
            other.AddRange(start, end);
    
            other.IntersectWith(this); // marked
            // other.ExceptWith(this); // not marked
    
            return other;
        }
    }
    
    public string CheckRange(int start, int end)
    {
        NumberLine other = new NumberLine();
    
        other.AddRange(start, end);
    
        IEnumerable<int> marked = other.Intersect(this);
        IEnumerable<int> notMarked = other.Except(this);
    
        int markedMin = marked.Min();
        int markedMax = marked.Max();
        int notMarkedMin = notMarked.Min();
        int notMarkedMax = notMarked.Max();
    
        string markedString = (markedMin == markedMax)
                ? markedMin.ToString()
                : string.Format("{0} - {1}", markedMin, markedMax);
    
        string notMarkedString = (notMarkedMin == notMarkedMax)
                ? notMarkedMin.ToString()
                : string.Format("{0} - {1}", notMarkedMin, notMarkedMax);
    
        return string.Format("Marked: {0}\r\nNot Marked: {1}", markedString, notMarkedString);
    }
    
    Marked: 10-15, 20-25
    Not Marked: 16-19
    
    LineNumber {
     List<Range> ranges;
     aadRange(a,b);
     // Loops through all ranges and calls isInRange on each method
     isInRange(a);
    
     //just iterates over isInRange from a to b
     checkRange(a,b)
    
    }
    
    Range {
     Range(a,b)
     isInRange(a);
    }
    
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    
    namespace NumberLine
    {
        class Program
        {
            static void Main(string[] args)
            {
                NumberLine line = new NumberLine();
                line.AddRange(1, 5);
                line.AddRange(10, 12);
                line.AddRange(20, 30);
    
                List<Range> ranges = line.CheckRange(10, 25);
                foreach (Range r in ranges)
                {
                    for (int i = r.Start; i <= r.End; i++)
                    {
                        Console.WriteLine(i);
                    }
                }
            }
        }
    
        class Range
        {
            public int Start;
            public int End;
        }
    
        class NumberLine
        {
            private SortedList<int, Range> Ranges = new SortedList<int, Range>();
    
            public void AddRange(int start, int end)
            {
                if (Ranges.Count == 0)
                {
                     Ranges.Add(start, new Range() { Start = start, End = end });
                }
                else
                {
                    foreach (Range currentRange in Ranges.Values)
                    {
                        if (start <= currentRange.Start) 
                        {
                            if (end >= currentRange.End)
                            {
                                currentRange.Start = start;
                                currentRange.End = end;
                            }
                            else
                            {
                                currentRange.Start = start;
                            }
                            Ranges.RemoveAt(start);
                            Ranges.Add(start, currentRange);
                            break;
                        } 
                        else
                        {
                            if (start <= currentRange.End)
                            {
                                currentRange.End = end;
                                break;
                            }
                            else
                            {
                                Ranges.Add(start, new Range(){ Start = start, End = end });
                                break;
                            }
                        }
                    }           
                }
            }
    
            public List<Range> CheckRange(int start, int end)
            {
                List<Range> result = new List<Range>();
                foreach (Range currentRange in Ranges.Values)
                {
                    if (start <= currentRange.End)
                    {
                        if (end <= currentRange.End)
                        {
                            result.Add(new Range() { Start = currentRange.Start, End = end });
                            break;
                        }
                        else
                        {
                            if (start <= currentRange.Start)
                            {
                                result.Add(new Range() { Start = currentRange.Start, End = currentRange.End });
                            }
                            else
                            {
                                result.Add(new Range() { Start = start, End = currentRange.End });
                            }
                        }
                    }
                }
                return result;
            }
        }
    
    }