1+ package test ;
2+
3+ import java .util .ArrayList ;
4+ import java .util .Arrays ;
5+ import java .util .Comparator ;
6+ import java .util .List ;
7+ import java .util .Random ;
8+
9+ class Test_Interval extends Test_ {
10+
11+ static int [] i0 = new int [0 ];
12+
13+ static int [][] a = new int [][] {
14+ { 1 , 7 },
15+ { 2 , 4 },
16+ { 3 , 5 },
17+ { 3 , 6 },
18+ { 4 , 5 },
19+ { 7 , 8 },
20+ { 9 , 10 }
21+
22+ };
23+
24+ public static void main (String [] args ) {
25+
26+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
27+ int [] ap = new int [] { 10 , 20 , 30 , 40 , 50 , 50 , 50 , 60 , 70 , 80 , 90 , 100 , 110 , 120 };
28+
29+ System .out .println (findClosestPoint (ap , 11 , true )); // 0
30+ System .out .println (findClosestPoint (ap , 11 , false )); // 1
31+ System .out .println (findClosestPoint (ap , 51 , true )); // 6
32+ System .out .println (findClosestPoint (ap , 51 , false )); // 7
33+ System .out .println (findClosestPoint (ap , 130 , true ));// -1
34+ System .out .println (findClosestPoint (ap , 130 , false )); // -1
35+ System .out .println (findClosestPoint (ap , 0 , true )); // -1
36+ System .out .println (findClosestPoint (ap , 0 , false )); // -1
37+ System .out .println (findClosestPoint (ap , 30 , true )); // 2
38+ System .out .println (findClosestPoint (ap , 60 , true )); // 7
39+ System .out .println (findClosestPoint (ap , 50 , true )); // 6
40+ System .out .println (findClosestPoint (ap , 50 , false )); // 4
41+
42+ assert (findClosestPoint (ap , 11 , true ) == 0 );
43+ assert (findClosestPoint (ap , 11 , false ) == 1 );
44+ assert (findClosestPoint (ap , 51 , true ) == 6 );
45+ assert (findClosestPoint (ap , 51 , false ) == 7 );
46+ assert (findClosestPoint (ap , 130 , true ) == -1 );
47+ assert (findClosestPoint (ap , 130 , false ) == -1 );
48+ assert (findClosestPoint (ap , 0 , true ) == -1 );
49+ assert (findClosestPoint (ap , 0 , false ) == -1 );
50+ assert (findClosestPoint (ap , 30 , true ) == 2 );
51+ assert (findClosestPoint (ap , 60 , true ) == 7 );
52+ assert (findClosestPoint (ap , 50 , true ) == 6 );
53+ assert (findClosestPoint (ap , 50 , false ) == 4 );
54+
55+ new Test_Interval ().findIntervals (a , 3 );
56+ new Test_Interval ().findIntervals (a , 5 );
57+ new Test_Interval ().findIntervals (a , 9 );
58+
59+ System .out .println ("Test_Interval OK" );
60+ }
61+
62+ private static Interval [] ints ;
63+
64+ private void findIntervals (int [][] a , int pos ) {
65+ try {
66+ Thread .sleep (500 );
67+ } catch (InterruptedException e ) {
68+ // TODO Auto-generated catch block
69+ e .printStackTrace ();
70+ }
71+ Random rand = new Random ();
72+ int n = a .length ;
73+ Interval [] intervals = new Interval [n ];
74+ for (int i = 0 ; i < n ;) {
75+ int r = rand .nextInt (n );
76+ if (intervals [r ] == null ) {
77+ intervals [r ] = new Interval (a [i ][0 ], a [i ][1 ], i );
78+ i ++;
79+ }
80+ }
81+ System .out .println ("=====" );
82+ //dumpIntervals(intervals);
83+ System .out .println ("-----" );
84+ ints = intervals ;
85+ Arrays .sort (intervals , new IComparator ());
86+ linkIntervals (intervals );
87+ //dumpIntervals(intervals);
88+ List <Interval > result = new ArrayList <>();
89+ findInterval (intervals , pos , result );
90+ for (int i = 0 ; i < result .size (); i ++)
91+ System .out .println (pos + " " + result .get (i ));
92+
93+ }
94+
95+ private void findInterval (Interval [] intervals , int pos , List <Interval > result ) {
96+ Interval ithis = findClosestInterval (intervals , pos );
97+ while (ithis != null ) {
98+ if (ithis .end >= pos )
99+ result .add (ithis );
100+ ithis = ithis .containedBy ;
101+ }
102+ }
103+
104+ private Interval findClosestInterval (Interval [] l , int pos ) {
105+ int low = 0 ;
106+ int high = l .length - 1 ;
107+ int mid = 0 ;
108+ while (low <= high ) {
109+ mid = (low + high ) >>> 1 ;
110+ int f = l [mid ].begin ;
111+ switch (Long .signum (f - pos )) {
112+ case -1 :
113+ low = mid + 1 ;
114+ continue ;
115+ case 1 :
116+ high = mid - 1 ;
117+ continue ;
118+ case 0 :
119+ while (++mid <= high && l [mid ].begin == pos ) {
120+ ;
121+ }
122+ mid --;
123+ return l [mid ];
124+ }
125+ }
126+ return (high < 0 || low >= l .length ? null : l [high ]);
127+ }
128+
129+ static void dumpIntervals (Interval [] intervals ) {
130+ for (int i = 0 ; i < intervals .length ; i ++) {
131+ System .out .println (intervals [i ]);
132+ }
133+ System .out .println ("" );
134+ }
135+
136+ public void linkIntervals (Interval [] intervals ) {
137+ if (intervals .length < 2 )
138+ return ;
139+ int maxEnd = intervals [0 ].end ;
140+ for (int i = 1 , n = intervals .length ; i < n ; i ++) {
141+ Interval ithis = intervals [i ];
142+ if (ithis .begin <= maxEnd )
143+ ithis .containedBy = getContainedBy (intervals , i );
144+ if (ithis .end > maxEnd )
145+ maxEnd = ithis .end ;
146+ }
147+
148+ }
149+
150+ private Interval getContainedBy (Interval [] intervals , int i ) {
151+ Interval ithis = intervals [i ];
152+ while (--i >= 0 ) {
153+ Interval ilast = intervals [i ];
154+ if (ithis .begin <= ilast .end ) {
155+ return ilast ;
156+ }
157+ }
158+ return null ;
159+ }
160+
161+ class Interval {
162+ int begin , end , index ;
163+ Interval containedBy ;
164+
165+ Interval (int begin , int end , int index ) {
166+ this .begin = begin ;
167+ this .end = end ;
168+ this .index = index ;
169+ }
170+
171+ @ Override
172+ public String toString () {
173+ return "I" + index + " begin:" + begin + " end:" + end + " cont:"
174+ + (containedBy == null ? "?" : containedBy .index );
175+ }
176+
177+ }
178+
179+ class IComparator implements Comparator <Interval > {
180+
181+ @ Override
182+ public int compare (Interval a , Interval b ) {
183+ int val = (a .begin < b .begin ? -1 : a .begin > b .begin ? 1 : a .end > b .end ? 1 : a .end < b .end ? -1 : 0 );
184+ return val ;
185+ }
186+
187+ }
188+
189+ static private int findClosestPoint (int [] l , int pos , boolean isStart ) {
190+ int low = 0 ;
191+ int high = l .length - 1 ;
192+ int mid = 0 ;
193+ while (low <= high ) {
194+ mid = (low + high ) >>> 1 ;
195+ int f = l [mid ];
196+ switch (Long .signum (f - pos )) {
197+ case -1 :
198+ low = mid + 1 ;
199+ continue ;
200+ case 1 :
201+ high = mid - 1 ;
202+ continue ;
203+ case 0 :
204+ if (isStart ) {
205+ while (--mid >= low && (f = l [mid ]) != -1 && f == pos ) {
206+ ;
207+ }
208+ ++mid ;
209+ } else {
210+ while (++mid <= high && (f = l [mid ]) != -1 && f == pos ) {
211+ ;
212+ }
213+ mid --;
214+ }
215+ return mid ;
216+ }
217+ }
218+ // -1 here?
219+ System .out .println (isStart + " " + low + " " + mid + " " + high );
220+ return (high < 0 || low >= l .length ? -1 : isStart ? high : low );
221+ }
222+
223+ }
0 commit comments