Question

Je l'algorithme de mise en œuvre de tri à bulles et je veux que ce soit en mesure d'accepter les paramètres de Integer et String. Je jetai toutes les entrées sous forme de chaînes et d'utiliser la méthode compareTo pour comparer les nombres entiers casted sous forme de chaînes aux cordes. Je reçois une réponse incorrecte lorsque vous utilisez compareTo pour comparer les entiers casted. Qu'est-ce que je fais mal?

Était-ce utile?

La solution

trie Integer.compareTo nombres numériquement. C'est ce que vous voulez.

String.compareTo trie les chaînes lexicographique; qui est, dans l'ordre alphabétique.

Je me souviens dans Windows 3.1 que le dossier de photos de mon appareil photo numérique a été commandé comme ceci: PHOTO1, Photo10, PHOTO100, PHOTO2, photo20, photo3, ... et ainsi de suite. Windows XP les trie plus comme on peut s'y attendre. PHOTO1, photo2, photo3, etc ... En effet, il a des règles spéciales de tri pour les chaînes qui représentent des nombres

En ordre lexicographique, chaque caractère dans une chaîne A est comparée au caractère correspondant dans une autre chaîne B. Pour chaque caractère correspondant dans les deux chaînes:

  • Si le caractère actuel de A est lexicographique moins (vient avant dans l'alphabet) le caractère de B, alors A est avant B.
  • Si le caractère de B est inférieure à caractère de A, B vient avant A.
  • Si les deux personnages sont les mêmes, nous ne savons pas encore. La prochaine est cochée.
  • S'il n'y a plus de caractères dans l'une des chaînes, le plus court vient avant la plus longue.
  • S'il n'y a pas plus de caractère à gauche dans les deux chaînes, ils sont la même chaîne.

Le quatrième point est ici pourquoi vous obtenez des réponses incorrectes, en supposant l'analyse Eddie de votre problème est correct.

Considérez les chaînes "10" et "2". L'ordonnancement lexicographique examinerait les premiers caractères de chacun, « 1 » et « 2 » respectivement. Le caractère « 1 » vient avant « 2 » dans le jeu de caractères que Java utilise, il trie « 10 » avant « 2 », de la même manière que « nu » est trié avant « lièvre » parce que « b » vient avant " h.

Je suggère que vous lancez vos chaînes entiers avant le tri. Utilisez Integer.parseString pour le faire.

Autres conseils

Êtes-vous sûr de vouloir mélanger Entiers et des chaînes dans la même liste? le cas échéant, sont Entiers moins ou plus que les chaînes? ce qui est ce des critères de tri?

vous pouvez également faire une méthode de tri des bulles qui trie des listes distinctes de nombres entiers et des listes de chaîne (et les listes d'une autre classe). de le faire, vous pouvez utiliser Generics. par exemple:

public static <T> void bubbleSort(List<T> elements, Comparator<T> comparator) {
    // your implementation
}

vous utilisez le paramètre comparator pour comparer les elements, c'est pourquoi ils peuvent être ou des chaînes (Entiers pas les deux en même temps). le compilateur ne vous laissera pas [sans avertissement] passer une liste d'objets d'une classe et un comparateur d'une classe différente, de sorte que la comparaison sera toujours travailler.

Prenez une instance de Comparable.

Les chaînes ne peuvent pas vraiment être jetés aux entiers, et il n'y a pas de méthode comparryo.

Ce que vous décrivez est pas vraiment possible ... alors peut-être vous avez besoin d'afficher le code. Voici mon interprétation de WHT que vous faites:

public int compareTo(final Object o)
{
    final String str;

    str = (String)o; // this will crash if you pass it an Integer.

    // rest of the code.
}

La documentation compareTo est ici , vous devriez vraiment suivre le contrat.

Tout d'abord, vous voulez Comparator comparable parce que prend Comparator deux objets alors que comparable compare l'objet courant à un passé et vous ne pouvez pas changer la méthode compareTo () sur chaîne ou entier si:

public class CompareIntegersAsStrings implements Comparator {
  public int compare(Object o1, Object o2) {
    return o1.toString().compareTo(o2.toString());
  }
}

En supposant que ce que vous voulez vraiment dire est que vous convertissez à cordes Entiers, puis comparer, cela ne fonctionnera pas. Par exemple, disons que vous avez l'entier 1234 et le 1 entier et le 2 entier. Si vous convertissez ces Strings et de les comparer, vous obtiendrez l'ordre:

1
1234
2

ce qui est correct pour le tri ASCII et incorrect pour le tri numérique. C'est, je suppose que votre code fait quelque chose comme ceci:

public int myCompare(Integer a1, Integer a2) {
    myCompare(String.valueOf(a1), String.valueOf(a2));
}

public int myCompare(String a1, String a2) {
    ....
}

Pourquoi est-ce que je suppose que cela? Parce que vous parlez d'obtenir un résultat incorrect et ne parle pas de faire des exceptions. Si vous obtenez effectivement des exceptions, les autres affiches sont correctes que la coulée ne fonctionnera pas.

Il est à cause du code API java ci-dessous en classe String où longueur minimale de caractères entre les deux chaînes ne sont comparées.

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2); //**HERE**
    char v1[] = value;
    char v2[] = anotherString.value;

    int k = 0;
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) {
            return c1 - c2;
        }
        k++;
    }
    return len1 - len2;
}

Si nous utilisons cette api pour comparer

String first = "ABCD"; 
String second = "ABZ"; 
System.out.println("" + "ABCD".compareTo("ABZ")); //-23

renvoie une valeur négative dire ABCD est inférieure à ABZ signifie C est inférieur à Z et D ignorée dans la première chaîne.

Nous avons donc besoin peut-être quelque chose comme ci-dessous

class StringNumericComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        int len1 = o1.length();
        int len2 = o2.length();
        if(len1 != len2) {
            return len1 - len2; //Else iterate all diff lengh chars and SUM it.
        }
        int lim = Math.min(len1, len2);
        char v1[] = o1.toCharArray();
        char v2[] = o2.toCharArray();

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return 0;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top