繁体   English   中英

我想添加一些精细的速度范围并将其保存到数据库中

[英]i want to add speed ranges with some fine amounts and save them into database

..我的问题是我应该检查速度范围是否重叠,如果它们重叠,我应该显示一条消息,说明速度范围不能重叠。

Minimum  Maximum     Rate
1           15        10

16          25        15 

将每个速度范围视为连续数字线上的线段。 为了找到所有重叠,请在每个线段重叠处对数字线进行分区。

首先,将每个范围分为起点和终点。 假设您的范围是:

(5,8) (1,5) (14,17) (3,4) (5,10)

为了清楚起见,我将给他们分配字母:

A=(5,8) B=(1,5) C=(14,17) D=(3,4) E=(5,10)

好的,现在,让我们将这些范围划分为离散的起点和终点:

A[start]=5, A[end]=8, B[start]=1, B[end]=5, C[start]=14, C[end]=...等。

按值对这些点进行排序,如果值相等,则起点在终点之前,因此您将获得如下列表:

B[start]=1, D[start]=3, D[end]=4, A[start]=5, E[start]=5, B[end]=5, A[end]=8, ...

容易吧?

现在,只需遍历已排序的列表,并保留当前范围的列表即可。 每次到达[start]时,都将该范围添加到列表中。 每次到达[end]时,请将范围从列表中删除。

因此,对于上面的列表,您可以使用:

B[start]=1  add B =>    (B)
D[start]=3  add D =>    (B,D)
D[end]=3    remove D => (B)
A[start]=4  add A =>    (B,A)
E[start]=5  add E =>    (B,A,E)
B[end]=5    remove B => (A,E)
A[end]=8    remove A => (E)
  ... and so on

只要您的列表包含多个元素,那就是一个重叠。 因此,对于任何范围,您都可以准确确定哪些范围在任何特定点重叠。

假设您使用类似quicksort的算法对存在/结束点进行排序,即运行时间为O(n log n) ,并且检测到实际重叠时间是线性的,那么整个算法将在O(n log n)

如果对值进行排序:

  • 首先在下限
  • 然后在上限

然后,您可以依次遍历它们,并对照下一个检查范围。 重叠范围将在序列中彼此相邻。

在您的示例中:

  • 将1-16与10-15(重叠)进行比较
  • 将10-15与15-25比较(可能重叠,取决于您如何定义重叠)

但是请注意,此算法仅回答“是否有任何范围重叠”的问题,它不能为您提供所有重叠的组合。 例如,在上面的代码中,1-16和15-25重叠,但是在此实现中没有得到这种组合。

如果需要,则需要更智能的算法。

我在这里发布了一个Visual Studio 2008项目: SO2696398的Subversion存储库

主要的应用程序代码如下所示:

using System;
using System.Linq;
using LVK.Collections;

namespace SO2696398
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var ranges = new[]
            {
                new Range<int, double>(1, 15, 10),
                new Range<int, double>(16, 25, 15),
                new Range<int, double>(8, 22, 7),
            };
            var slices = ranges.Ordered<int, double>().Slice();

            foreach (var slice in slices)
            {
                if (slice.Data.Length == 1)
                    continue;

                Console.Out.WriteLine("overlap at " + slice.Start
                    + "-" + slice.End + ": "
                    + string.Join(" with ",
                    (from range in slice.Data
                     select range.ToString() 
                     + " [rate=" + range.Data + "]").ToArray()));
            }
        }
    }
}

输出为:

overlap at 8-15: 1..15 [rate=10] with 8..22 [rate=7]
overlap at 16-22: 8..22 [rate=7] with 16..25 [rate=15]

希望这可以帮助。 项目的班级部分是我在主班级库中拥有的班级的一小部分。 如果您希望链接到完整的库,则可以从Subversion Repository for LVK for .NET下载并编译源代码。 此处使用的类来自LVK.Core项目。

您可以轻松地在数据库中实现此业务逻辑,以要求将来的任何应用程序都遵循此约束。

我将使用以下方式将逻辑实现为存储过程(或触发器):

CREATE PROCEDURE MyDatabase.spInsertSpeedRanges
    @Min int, 
    @Max int,
    @Rate int
AS

select top 1 * 
from tblSpeedRanges 
where (Minimum between @Min and @Max) or (Maximum between @Min and @Max)

if @@RowCount <> 0
  return -1
else
  insert into tblSpeedRanges (Minimum, Maximum, Rate) values (@Min, @Max, @Rate)

GO

然后在您的应用程序中,如果返回-1,则显示您选择的错误消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM