# Character-Array sortieren￾￾



## aVoX (29. Mrz 2009)

Mahlzeit!

Ich möchte ein Character-Array sortieren und ausgeben. Jedoch soll das Ergebnis nicht wie folgt aussehen:


> Array unsortiert:
> [A, b, q, s, Q, a, s]
> Array sortiert (V1):
> [A, Q, a, b, q, s, s]


Sondern so (also zuerst der Großbuchstabe, dann - falls vorhanden - der dazugehörige Kleinbuchstabe)


> Array unsortiert:
> [A, b, q, s, Q, a, s]
> Array sortiert (V1):
> [A, a, Q, q, b, s, s]


Ich werk schon die ganze zeit daran herum. Mein Code bis jetzt:
[highlight="JAVA"]char[] chr = {'A', 'b', 'q', 's', 'Q', 'a', 's'};
    	char  help;

    	System.out.println("Array unsortiert:");
    	System.out.println(Arrays.toString(chr));

    	//Bubblesort zum sortieren der Buchstaben:
    	for (int i = chr.length-1; i > 0; i--) {
    		for (int j = 1; j <= i; j++) {
    			//* Hier rein gehören meine Überlegungen
    			if (chr[j-1] > chr[j]) {
    				help = chr[j-1];
    				chr[j-1] = chr[j];
    				chr[j] = help;
    			}
    		}
    	}
    	System.out.println("Array sortiert (V1):");
    	System.out.println(Arrays.toString(chr));[/highlight]
*Soweit bin ich schon mit meinen Überlegungen: Wenn das zeichen [j] größer als 65 (großes A) ist und kleiner als 90 (kleines a) ist, muss man 32 dazuzählen, um den Vergleich richtig zu machen. Mei der Methode wird aber jeder Großbuchstabe zu einem kleinen. <- Nicht gut...

MfG, avoX


----------



## hdi (29. Mrz 2009)

*ungetestet:*

[HIGHLIGHT="Java"]        
        // wenn er grösser ist als der nächste
        if ( chr[j-1] > chr[j]){
                     // dann schieb ihn vor
                     help = chr[j-1];
                     chr[j-1] = chr[j];
                     chr[j] = help;
                     }
        }
        // wenn er kleiner ist als der nächste
        else if(chr[j-1] < chr[j]){
                    // aber zwischen einem Päärchen von Klein-/Grossbuchstabe liegt, zB A-x-a
                    if(chr[j-2] == chr[j] -32){
                           // dann schieb ihn trotzdem vor
                           help = chr[j-1];
                           chr[j-1] = chr[j];
                           chr[j] = help;
                     }
         }[/HIGHLIGHT]

...du musst nur aufpassen noch eine kleine Abfrage einzubauen für den Fall j-1 == 0,
weil du sonst bei j-2 == -1 eine Exception kriegst.


----------



## Käptn Blaubär (29. Mrz 2009)

Es ist es deutlich komfortable dazu Arrays.sort zu nehmen und nur einen eigenen Comparator zu implementieren da man sich das manuelle interieren sparen kann.

Im Comparator sähe das dann etwa so aus
[highlight=Java]
public class MyComarator implements Comparator<Character>
{

    public int compare(Character o1, Character o2)
    {
        int value1=Character.toLowerCase(o1);
        int value2=Character.toLowerCase(o2);
        if(value1==value2)
        {
            if(Character.isUpperCase(o1))
            {
                value1=0;
            }
            else
            {
                value2=0;
            }
        }
        return value1-value2;
    }
}[/highlight]


----------



## aVoX (29. Mrz 2009)

Danke, aber wohin gehört diese Klammer?


			
				hdi hat gesagt.:
			
		

> [highlight=JAVA]// wenn er grösser ist als der nächste
> if ( chr[j-1] > chr[j]){
> // dann schieb ihn vor
> help = chr[j-1];
> ...


----------



## hdi (29. Mrz 2009)

Genau dorthin, wo sie in meinem Code liegt.
Der erste Teil ist eine Kopie von deinem Code, ich habe lediglich einen
neuen (esle) if-Zweig angehängt.
Das kannst du so kopieren. Aber wie gesagt, hab nich gross überlegt ob das so passt.

Die Lösung von Blaubär ist *eindeutig* schöner, aber es schadet eig. nie sich das Hirn
zu verdrehen mit solchen Übungen


----------



## Wildcard (29. Mrz 2009)

Collator (Java Platform SE 6)


----------



## SlaterB (29. Mrz 2009)

@Käptn Blaubär
durch das value = 0 wird das aber recht kompliziert, da muss man ja erstmal nachdenken, wohin das führt 

kleiner Schönheitfehler noch: wenn beide Chars die gleichen sind, also 'x' und 'x' oder 'X' und 'X',
wird dennoch entweder ein positiver oder negativer Wert zurückgegeben, nicht gerade symmetrisch


eine Alternative:

```
public int compare(Character o1, Character o2)
    {
        if (o1.equals(o2)) {
            return 0;
        }
        int c =Character.toLowerCase(o1) - Character.toLowerCase(o2);
        if(c != 0)
        {
            return c;
        } 
        if(Character.isUpperCase(o1))
        {
              return 1;
        }
        return -1; // oder andersrum
    }
```


----------



## aVoX (29. Mrz 2009)

Liegt wohl an der } Klammer. Wenn ich die aber wegmache bekomm ich einen IndexOutOfBounds-Fehler, weil das Element -1 nicht im Array definiert ist

@Blaubärs Lösung:
Die Lösung nehm ich deshalb nicht, weil ich sie absolut nicht kapiere! Und ehrlichgesagt habe ich lieber einen Code, der nicht sehr schön ist, den ich verstehe und der funzt, als einen Code, der schön ist, funzt, und den ich absolut nicht verstehe.


----------



## Illuvatar (29. Mrz 2009)

Um trotzdem nochmal zum Comparator zurück zu kommen:
Hier eine Version, die meiner Meinung nach den Kontrakt (inklusive Antisymmetrie) vollständig erfüllt:

[HIGHLIGHT="Java"]import java.util.*;

public class Test {
  public static void main(String[] args) {
    Character[] chars = {
      'A', 'b', 'q', 's', 'Q', 'a', 's'
    };
    Arrays.sort(chars, new Comparator<Character>(){
      public int compare(Character c1, Character c2) {
        int value1 = Character.toLowerCase(c1) * 2;
        if (Character.isLowerCase(c1)) value1++;
        int value2 = Character.toLowerCase(c2) * 2;
        if (Character.isLowerCase(c2)) value2++;
        return value1 - value2;
      }
    });
    System.out.println(Arrays.toString(chars));
  }
}
[/HIGHLIGHT]


----------

