Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

COmparator with strings that contains numbers, * and #

Status
Not open for further replies.

celia05es

Programmer
Jan 10, 2002
81
0
0
US
Hello,
I have been trying to solve my problem since this morning but I cannot do it!!!
Please, help me.
I have an array. Each element can contain digits, "*" or/and "#". I would like to sort the array using comparator... but I can't seem to find the correct algorithm.

COuld you help me?

Thanks
ELisabeth
 
What's your exact problem?

Java will sort alphabetically an String array for you via the Arrays class. I don't know if that's what you want to know or it's that you need a different kind of sorting.

Cheers,

Dian
 
Well I have an array that can contain 10*, 192304, 100*, 10# etc. (basically digits, * and #
Now, I want to sort the array but I cannot do it correctly.

I want to call something like:
util.CmpElmt cmp=new util.CmpElmt();
Collections.sort(v,cmp);
return v;
==============0

Here is my "bad" code:
package util;

import java.util.*;
public class CmpElmt implements Comparator
{
public int compare(Object o1, Object o2)
{
String s1 = (String) o1;
String s2 = (String) o2;

int s1Length=s1.length();
int s2Length=s2.length();
System.out.println("s1="+s1+" s2="+s2);
int i=-1;
boolean cont=true;
int j=0;
while((cont) && (j<s1Length) && (j<s2Length))
{
char cS1=s1.charAt(j);
char cS2=s2.charAt(j);
if (cS1 != cS2)
{
//if ((Character.isDigit(cS1)) && (Character.isDigit(cS2)))
if (cS1 > cS2)
{
i=1;
cont=false;
}
}
j++;
} // while
if (cont)
{
if (s1Length != s2Length)
{
if (j == s1Length)
i=-1;
if (j == s2Length)
i=1;
}
}
else
{
if (s1Length < s2Length)
i=-1;
}
System.out.println("i="+i);
return i;
}
}

 
Please, bear in mind that I am quite new in Java so any solutions will be welcome.
 
I'll assume that you want to order it by ignoring # and * and then my number so ...


Code:
public int compare(Object o1, Object o2) {

String str1 = (String) o1;
String str2 = (String) o2;

// This will remove non-digits
str1.replace("#","");
str1.replace("*","");
str2.replace("#","");
str2.replace("*","");

int i = 0;

// Now wwe can compare them as numbers
if (Integer.parseInt(str1)) > Integer.parseInt(str2))
i=1
else
i=-1

return i;

}

Cheers,

Dian


 
Actually, I don't want to remove * or #. THe strings are kind of phone numbers so they must be sorted with those characters... this is why I am having the problem.
Do you think you could come with something?


Anyway, I have tried to compile the code you gave me and I got errors with the replace statement:
mpElmt.java:16: replace(char,char) in java.lang.String cannot be applied to (java.lang.String,java.lang.String)
str1.replace("#","");
 
Removing the # & * characters means you can perform an easier comparison. It won't actually remove them forever !

Change str1.replace() to str1.replaceAll()

--------------------------------------------------
Free Database Connection Pooling Software
 
I have tried your code with a array and I get as a result:
1
36
100
900
100#
100*
101*

I suppose this is due to the replaceAll statement.
Now, I would have liked to have
1
36
100
100#
100*
101*
900

It is possible?

===================================
PS: I have tried your code and got the following exception:
Excepción:
java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0 * ^





 
Sorry, my fault, that's

Code:
replace('#','');

Anyway, how do you want to sort the items?

If it's alphabetical order, String class has a compareTo() method.

Cheers,

Dian
 
OK, to start with I made a "small" mistake.... The strings are not in an array but in a Vector.

Now, suppose I have a Vector that contains:
100 100# 1 900 100* 101* 36 1

With the code you provided I get:
100
100#
900
100*
101*
36
1

and I guess I should have
1
36
100
100*
100#
101*
900

Is it possible?
 
My mistake again.... forget what I just wrote.... the code was not compiled.... anyway I cannot compile it but I don't think this is the problem because I don't want to remove the "*" and the "#"
 
It's as above, except that if two elements are equal, look at weather or not one of them contians the * or # to break the tie...
 
I am lost now.... could we summarize what I should do?

Let's say I have the following Vector:
100 100# 1 900 100* 101* 36 1

After the sort, I need to have:
1
36
100
100*
100#
101*
900

Which code should I use?
 
Last chance

Code:
public int compare(Object o1, Object o2) {

String str1 = (String) o1;
String str2 = (String) o2;

int mod1 = 0;
int mod2 = 0;
if (str1.indexOf("#")>-1) mod1 ++;
else if (str1.indexOf("*")>-1) mod1+=2;
if (str2.indexOf("#")>-1) mod2 ++;
else if (str2.indexOf("*")>-1) mod2+=2;

// This will remove non-digits
str1.replace("#","");
str1.replace("*","");
str2.replace("#","");
str2.replace("*","");

int i = 0;

// Now wwe can compare them as numbers
if (Integer.parseInt(str1)) > Integer.parseInt(str2))
i=1
else if (Integer.parseInt(str1)) < Integer.parseInt(str2))
i=-1;
else if (mod2 > mod1)
i=-1;
else if (mod1 < mod2)
 i=1;


return i;

}

Cheers,

Dian
 
I was wondering.... is there a way of sorting strings with numbers and letters correctly.
I mean, I have a code (which I know is not that good) but that works for strings like user, user1 (sorts it correctly)
but if I have strings that only contain numbers the sort is not correct.
For instance, the result of the list that is supposed to be sorted is:
100
200
101
102
usu
usu1

As you can see the 200 element is not at its place!!!

Could you have a quick look at my code and tell me what I should correct?
THanks


package util;

import java.util.*;


/public class CmpSaggsn implements Comparator
{
public int compare(Object o1, Object o2)
{

String saggsn_service1 = (String) o1;
String saggsn_service2 = (String) o2;

int s1Length=saggsn_service1.length();
int s2Length=saggsn_service2.length();
int i=-1;
boolean cont=true;
int j=0;
while((cont) && (j<s1Length) && (j<s2Length))
{
char cS1=saggsn_service1.charAt(j);
char cS2=saggsn_service2.charAt(j);
boolean number=false;
if (cS1 != cS2)
{
if ((Character.isDigit(cS1)) && (Character.isDigit(cS2)))
{
number=true;
if (cS1 > cS2)
i=1;
j++;
}
else
{
cont=false;
}
if (cS1 >cS2)
i=1;
}
else
{
if (number)
cont=false;
j++;
}
}
if (s2Length != s1Length)
{
if (j == s2Length)
i=1;
if (j == s1Length)
i=-1;
}
return i;
}
}

 
To be sincere, I don't fully understand your code, but what I think you're doing is ordering the elements reading them from right to left. That's because the result just depends on the last char comparison if the length of the strings is the same.

I don't know what do you understand by "order correctly", depending on what you're trying to do, the order can vary.

Anyway, if you want Strings to be ordered like numbers, I'd convert it to numbers, I think that's the easiest way.

Cheers,

Dian
 
What a great idea.....Now, can I convert them to number only using "the atoi" command?
 
Suppose I have String s1="usu1";
String s2="100";
Can I use int is1=Integer.parseInt(s1); and
int is2=Integer.parseInt(s2);
and then compare them?
I thought that if I'd use Integer.parseInt() on something that does not only contain numbers I would get a format exception.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top