It does not compare well the string (I think). Java CompareTo ()

2

Well, I have a problem and I do not understand why it does not compare well the value of the string. I would appreciate all the help possible. By not sharing well the "numbers" (passed as string). the final string is larger than a long and gives an error.

EDIT: What it does is go putting Integers stored togetherNumeros in two strings, I do not look for them to add up, but they are equally distributed, that is: If altogether I have 9.9.6,5, 5,3,2,1. The strings should look like this:

s1 = 9 5 5 1

s2 = 9 6 3 2

It is not a sum of the numbers themselves, but it is dividing between the two strings

I do not know if I explained myself well, the compareTo should give me 1 if this were so: "23".compareTo("15") , no?

Here is the code fragment that gives me error:

long[] solucion = new long[2];
int c; //candidato
String cs;

while (!(conjuntoNumeros.isEmpty())){
    //seleccionar candidato
    c = seleccionarCandidato(conjuntoNumeros);
    //eliminar candidato
    conjuntoNumeros.remove(new Integer(c));
    cs = String.valueOf(c);
    if (s1.compareTo(s2)>=1){
        s2 = s2 + cs;
    }else{
        s1 = s1 + cs;
    }
}
System.out.println(s1 + " y " + s2);
solucion[0]=new Long(s1).longValue();
solucion[1]=new Long(s2).longValue();

return solucion;

cs is the string of the int that came out in the select candidate function

setNumeros is an arrayList containing integers

The idea of the code is to distribute equally and finish the two numbers or the same or that are very close to each other.

Here the candidate selection code:

This function searches for the largest number stored in the Arraylist of setNumeros.

int seleccionarCandidato(ArrayList<Integer> conjunto){
    int candidato = conjunto.get(0);

    for (int i=1; i<conjunto.size(); i++){
        if(candidato < conjunto.get(i)) candidato = conjunto.get(i);
    }
    return candidato;
}

And finally the error code:

I get an error because I think the size of the string is much higher and should always be smaller (if it is distributed well).

Error code:

Exception in thread "main" java.lang.NumberFormatException: For input string: "9998777666655555554433322111"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:592)
at java.lang.Long.<init>(Long.java:965)
at NumeroMasCercanos.VorazNumerosCercanos(NumeroMasCercanos.java:55)
at Pruebas.main(Pruebas.java:12)
    
asked by Varox 24.11.2017 в 13:50
source

4 answers

2

It seems that you do not understand how the compareTo works.

The compareTo works by comparing a string byte by byte (character by character), based on the ASCCI code, it returns a value when it finds the first different character in the whole string (the value that returns is the bit difference)

While you're right about what "23" .compareTo ("15") will give you a 1. You have to analyze what happens next, then the next value (suppose it is 2) will be stored in s2 so it will be as follows s1="23" s2="215"

will select a candidate again and suppose it is 1 Where do you think I'll keep it?

I will make a comparison again as follows "23" .compareTo ("215") read byte to byte 2 = 2 so you will continue with the next, 3! = 1 will return a 2 because 3 is 2 bits larger than 1 then it will re-enter the if and it will add the number again in s2 so now you will have s2="1215" and s1="23" and if you have another value it will be saved again in s2 .

Solution

before doing the compareTo compares the size of the strings with length (); in this way you can enter the value in the smallest chain and when they are equal then if you use the compare To

Solution 2

I personally consider it more optimal, you use a sorting method to sort your array of numbers and then you assign the array indexes to s1 and odd numbers to s2 and you do not even need to pass it through string you save it directly in a long if you multiply by units, tens, hundreds etc.

Note

I realized you're assigning

s2 = s2 + cs

or s1 = s1 + cs

I will explain it to you as if you were saving

s2 = cs + s2

s1 = cs + s1

This does not change the logic that I just explained to you because if at any moment you have s2 = 2 and s1 = 1 it will always be saved in s2 since 2 and 1 will always be the first digits that are compared.

What I was going to do is that the goal is to form 2 numbers with the least possible difference.

this implies that if you have 998761 the best way will be saving at the end of the chain so that you get

s1 = 986 and s2 = 971 otherwise you would get a bigger difference s1 = 179 and s2 = 689

but if you have 943211 it would be ideal to save it at the beginning of the chain to obtain

s1 = 124 s2 = 139 otherwise you will get a bigger difference s1 = 421 s2 = 931

certainly an interesting problem

    
answered by 24.11.2017 / 18:53
source
0

You have two problems. First, for the case of the exception, it happens because you are trying to convert the text 9998777666655555554433322111 to long , but the maximum number that reaches to store a long is 9223372036854775807 . What you could do to solve this problem is change the return of the solution to be a text, something like this:

String solucion = new String[2];
//...
solucion[0] = s1;
solucion[1] = s2;
return solucion;

Note: This part is not really important if you are certain that the results can always be converted into a long

On the other hand, compareTo compares alphabetically, that is, if at some point you compare 9 versus 12345 , 9 will seem higher. However, you could look at the length of the chains (if there is one string shorter than the other, it has a lower value), in addition to using the compareTo . It would be something like this:

int largoS1 = s1.length();
int largoS2 = s2.length();
if (largoS2<largoS1 || largoS1==largoS2 && s1.compareTo(s2)>=1){
    s2 = s2 + cs;
}else{
    s1 = s1 + cs;
}

Here you have a working example code

    
answered by 24.11.2017 в 21:26
0

The detail refers to the length of the number that is larger than the int can support

  

c = selectCandidate (setNumbers);

int Whole 4 bytes 2 * 10 ^ 9

You are overcoming this capacity.

Check the data entry double

    
answered by 27.11.2017 в 23:25
-1

The number is very large so you can save it in a Long, I recommend you use BigInteger for those cases.

BigInteger[] solucion = new BigInteger[2];



 solucion[0]=new BigInteger(s1);
 solucion[1]=new BigInteger(s2);
    
answered by 24.11.2017 в 14:53