comparison src/main/java/de/mpiwg/itgroup/ismi/utils/NaturalOrderComparator.java @ 1:2e911857a759

(none)
author jurzua
date Wed, 29 Oct 2014 14:00:28 +0000
parents
children
comparison
equal deleted inserted replaced
0:74df02964906 1:2e911857a759
1 package de.mpiwg.itgroup.ismi.utils;
2
3 /*
4 NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
5 Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>
6
7 Based on the C version by Martin Pool, of which this is more or less a straight conversion.
8 Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
9
10 This software is provided 'as-is', without any express or implied
11 warranty. In no event will the authors be held liable for any damages
12 arising from the use of this software.
13
14 Permission is granted to anyone to use this software for any purpose,
15 including commercial applications, and to alter it and redistribute it
16 freely, subject to the following restrictions:
17
18 1. The origin of this software must not be misrepresented; you must not
19 claim that you wrote the original software. If you use this software
20 in a product, an acknowledgment in the product documentation would be
21 appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and must not be
23 misrepresented as being the original software.
24 3. This notice may not be removed or altered from any source distribution.
25 */
26
27 import java.util.*;
28
29 public class NaturalOrderComparator
30 {
31 private static int compareRight(String a, String b)
32 {
33 int bias = 0;
34 int ia = 0;
35 int ib = 0;
36
37 // The longest run of digits wins. That aside, the greatest
38 // value wins, but we can't know that it will until we've scanned
39 // both numbers to know that they have the same magnitude, so we
40 // remember it in BIAS.
41 for (;; ia++, ib++)
42 {
43 char ca = charAt(a, ia);
44 char cb = charAt(b, ib);
45
46 if (!Character.isDigit(ca) && !Character.isDigit(cb))
47 {
48 return bias;
49 }
50 else if (!Character.isDigit(ca))
51 {
52 return -1;
53 }
54 else if (!Character.isDigit(cb))
55 {
56 return +1;
57 }
58 else if (ca < cb)
59 {
60 if (bias == 0)
61 {
62 bias = -1;
63 }
64 }
65 else if (ca > cb)
66 {
67 if (bias == 0)
68 bias = +1;
69 }
70 else if (ca == 0 && cb == 0)
71 {
72 return bias;
73 }
74 }
75 }
76
77
78
79 public static int compare(String a, String b)
80 {
81 //String a = o1.toString();
82 //String b = o2.toString();
83
84 int ia = 0, ib = 0;
85 int nza = 0, nzb = 0;
86 char ca, cb;
87 int result;
88
89 while (true)
90 {
91 // only count the number of zeroes leading the last number compared
92 nza = nzb = 0;
93
94 ca = charAt(a, ia);
95 cb = charAt(b, ib);
96
97 // skip over leading spaces or zeros
98 while (Character.isSpaceChar(ca) || ca == '0')
99 {
100 if (ca == '0')
101 {
102 nza++;
103 }
104 else
105 {
106 // only count consecutive zeroes
107 nza = 0;
108 }
109
110 ca = charAt(a, ++ia);
111 }
112
113 while (Character.isSpaceChar(cb) || cb == '0')
114 {
115 if (cb == '0')
116 {
117 nzb++;
118 }
119 else
120 {
121 // only count consecutive zeroes
122 nzb = 0;
123 }
124
125 cb = charAt(b, ++ib);
126 }
127
128 // process run of digits
129 if (Character.isDigit(ca) && Character.isDigit(cb))
130 {
131 if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0)
132 {
133 return result;
134 }
135 }
136
137 if (ca == 0 && cb == 0)
138 {
139 // The strings compare the same. Perhaps the caller
140 // will want to call strcmp to break the tie.
141 return nza - nzb;
142 }
143
144 if (ca < cb)
145 {
146 return -1;
147 }
148 else if (ca > cb)
149 {
150 return +1;
151 }
152
153 ++ia;
154 ++ib;
155 }
156 }
157
158 static char charAt(String s, int i)
159 {
160 if (i >= s.length())
161 {
162 return 0;
163 }
164 else
165 {
166 return s.charAt(i);
167 }
168 }
169
170 /*
171 public static void main(String[] args)
172 {
173 String[] strings = new String[] { "1-2", "1-02", "1-20", "10-20", "fred", "jane", "pic01",
174 "pic2", "pic02", "pic02a", "pic3", "pic4", "pic 4 else", "pic 5", "pic05", "pic 5",
175 "pic 5 something", "pic 6", "pic 7", "pic100", "pic100a", "pic120", "pic121",
176 "pic02000", "tom", "x2-g8", "x2-y7", "x2-y08", "x8-y8" };
177
178 List orig = Arrays.asList(strings);
179
180 System.out.println("Original: " + orig);
181
182 List scrambled = Arrays.asList(strings);
183 Collections.shuffle(scrambled);
184
185 System.out.println("Scrambled: " + scrambled);
186
187 Collections.sort(scrambled, new NaturalOrderComparator());
188
189 System.out.println("Sorted: " + scrambled);
190 }
191 */
192 }