2010-04-23 5 views

답변

0

당신은 값을 정렬 할 경우에

  • 먼저 하한
  • 그 다음에 상단이 순서대로 그들을 통해 반복하고, 하나를 확인하실 수 있습니다 그리고

바운드 다음 범위. 겹치는 범위는 순서에서 서로 옆에 있습니다. 당신의 예에서

:

  • 이 10 ~ 15과 16을 비교 (중복)
  • 가 15-25과 10-15을 비교
을 (가능한 중복, 당신은 중복 정의하는 방법에 따라 달라집니다)

그러나이 알고리즘은 " 범위가 겹치나요?"라는 질문에만 답합니다. 모든 겹치는 조합을 제공하지는 않습니다. 예를 들어, 위의 코드에서 1-16과 15-25는 겹칩니다 만이 구현과의 조합을 얻지는 못합니다.

필요한 경우 훨씬 더 똑똑한 알고리즘이 필요합니다.

여기 Visual Studio 2008 프로젝트를 게시했습니다 : Subversion Repository for SO2696398.

의 기본 응용 프로그램 코드는 다음과 같습니다

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 프로젝트의 클래스입니다.

+0

안녕하세요, 나는 색인 생성과 모든 다른 방법으로 모든 조건을 만족시킬 수는 없지만 ... 시도했습니다. – sabita

+0

중복되는 범위의 모든 조합을 정말로 알아야합니까? 그렇다면 어떤 프로그래밍 언어가 필요할 것입니까? 나는 당신을 도울 수있는 C# 클래스를 가지고 있습니다. –

+0

예 모든 조합을 확인해야하고 C#을 사용하면 도움이 될 것이라고 생각합니다. – sabita

1

각 속도 범위를 연속 번호 줄의 선분으로 생각하십시오. 모든 겹침을 찾으려면 모든 선분 겹치기에서 번호 선을 분할하십시오.

먼저 각 범위를 시작 지점과 끝 지점으로 구분하십시오. 의 당신의 범위가 가정 해 봅시다 :

(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)에서 실행됩니다.

+0

안녕하세요, 고마워요 UR 대답에 대한하지만 내 질문에 잘못된 경우 미안 해요 내가 원하는 모든 데이터베이스에 데이터를 추가하는 것입니다. net 프론트 엔드, 나는 범위를 추가 할 필요가 있습니다. 엉망이 – sabita

+0

그래서 뭐가 문제 야? 데이터베이스를 사용하든 사용하지 않든 위에서 언급 한 내용을 여전히 수행 할 수 있습니다. – RarrRarrRarr

0

데이터베이스에이 비즈니스 논리를 쉽게 구현하여 향후 응용 프로그램이이 제약 조건을 준수하도록 할 수 있습니다.

는이 같은 뭔가 저장 프로 시저 (또는 트리거)와 같은 논리를 구현하는 것이 : -1이 반환되는 경우

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 

그런 다음 응용 프로그램에서, 당신의 선택의 오류 메시지를 보여줍니다.

관련 문제