# String Lauflängen Encoder und Decoder



## Awaxor (9. Nov 2014)

Hallo, ich soll folgende Methoden erstellen: eine soll einen String der zuvor eingelesen wurde encoden das heist wenn ein Buchstabe mehr als 2 mal aufeinander folgend vorkommt dann soll er diese durch den Buchstaben und die Anzahl dessen ersetzen (zB "aabbbbbccc" wird zu "aab5c3"). Ich darf keine arrays benutzen und ich komm einfach nicht weiter. In der Decoder Methode soll das Ganze andersrum laufen. Würde mich über Hilfe freuen. Danke im voraus.


----------



## JavaMeister (9. Nov 2014)

Wie sieht dien Ansatz aus?


----------



## njans (9. Nov 2014)

Geh den String durch. Dabei guckst du für jeden Buchstaben, ob die darauffolgenden Buchstaben ebenfalls gleich diesem sind. Die Anzahl und den Buchstaben schreibst du in einen neuen String. fertig.


----------



## Awaxor (9. Nov 2014)

Hallo JavaMeister,

danke für die schnelle Reaktion.
Mein Ansatz sieht wie folgt aus:

_


		Java:In die Zwischenablage kopieren


public class Bsp04{
    public static void main(String[] args) {
    System.out.println ("Bitte geben Sie einen String ein: ");
    String s = SavitchIn.readLine();
    System.out.println ("r enthaelt: " + encode(s));
    }
    public static String encode(String s){
    int length = s.length();
    int j = 1;
    char c = s.charAt(0);
    String help = "";
    help = help + c;
    String help2 = "";
    String r = "";
            
    for(int i = 1; i < length; i++) {
        c = s.charAt(i);
        help2 = "" + c;
        if(help.equals(help2)) {
            j = j + 1;
            if(j >= 3) {
                r = r + help + j;        
            }
        }
        else {
            if( j == 2){
                r = r + help + help;
            }
            j = 1;
        }
        help = help2;
    }    
    if( j == 2){
        r = r + help + help;
    }
    else{
        if ( j >= 3){
            
        }
        else{
            r = r + help;
        }
        
    }
    
    return r;
    }
}[/I]


Als vorgegebene Eingabe habe ich: "abbcccddddddddddddddddeee"
Das Ergebnis soll lauten: "abbc3d16e3"
Mein bisheriges Ergebnis sieht so aus: "bbc3d3d4d5d6d7d8d9d10d11d12d13d14d15d16e3"
Ich denke der Fehler liegt bei der Stelle:


		Java:In die Zwischenablage kopieren


if(help.equals(help2)) {
    j = j + 1;
    if(j >= 3) {
       r = r + help + j;        
    }
}


Da das "d" ja 16mal vorkommt, wird der String jedes mal um das "d" und die Anzahl erweitert._


----------



## Androbin (9. Nov 2014)

Schon mal was von den Java-Tags gehört?


----------



## JavaMeister (9. Nov 2014)

Ja,


```
if(j >= 3) {
					r = r + help + j;
				}
```

Ich rate einfach, dass das hier zu oft aufgerufen wird. Das muss nur passieren, wenn sich ber Buchstabe ändert und nicht wenn er mehr als 2 mal vorkommt.


----------



## njans (9. Nov 2014)

Kleiner Tipp: Versuch es mal mit einer weiteren Schleife. 
Was ich da momentan sehe ist, dass du für unzählige Fälle irgendwelche Ifs einbaust. Mit einer Schleife kannst du das ganze deutlich einfacher und kürzer lösen.


----------



## Awaxor (9. Nov 2014)

ja hab ich mir auch schon überlegt aber ich komm nicht drauf wie ich die zweite einbauen soll und was ich reinschreiben soll


----------



## JavaMeister (9. Nov 2014)

> ja hab ich mir auch schon überlegt aber ich komm nicht drauf wie ich die zweite einbauen soll und was ich reinschreiben soll



Versuche Dir erstmal klar zu machen, was dein aktueller Code macht. Denn hinzufügend zu meinem Posting muss ich sagen,d ass die ganzen folgenden if/else irgentwie nicht so stimmen.

Eine zweite Schleife ist imho nicht notwendig. Du guckst und zählst schon die doppelten aber die Zahl ist a) zu oft und b) falsch berechnet.


----------



## Awaxor (9. Nov 2014)

Ich muss das bis heute 24 Uhr abgeben, kann mir einer sagen wie genau ich die schleifen aufbauen muss?


----------



## njans (9. Nov 2014)

Hier hast du zwei Lösungen. Die erste mit 2 for-schleifen. Die 2te ist näher an dem, was du machst. 



```
public static String myEncode(String input)
	{
		String output = "";

		for (int i = 0; i < input.length(); i++)
		{
			int chainLength = 1;
			char currentChar = input.charAt(i);
			
			for (int j = i+1; j < input.length(); j++)
			{
				if (input.charAt(j) == currentChar)
				{
					chainLength++;
					i++;
				}
				else
				{
					break;
				}
			}
			
			output += currentChar;
			
			if (chainLength > 1)
				output += chainLength;
		}
		
		return output;
	}
```


```
public static String myEncode2(String input)
	{
		int chainLength = 1;
		char lastChar = input.charAt(0);
		String output = String.valueOf(lastChar);
		
		for (int i = 1; i < input.length(); i++)
		{
			final char currentChar = input.charAt(i);
			
			if (currentChar != lastChar)
			{
				if (chainLength > 1)
					output += chainLength;
				
				output += currentChar;
				
				chainLength = 1;
			}
			else
			{
				chainLength++;
			}
			
			lastChar = currentChar;
		}
		
		if (chainLength > 1)
			output += chainLength;
		
		return output;
	}
```


----------



## njans (10. Nov 2014)

Da tatsächlich ursprünglich gefordert war, dass das runlength coding erst ab Länge 2 auftritt:


```
public static String myEncode2(String input)
	{
		int chainLength = 1;
		char lastChar = input.charAt(0);
		String output = String.valueOf(lastChar);
		
		for (int i = 1; i < input.length(); i++)
		{
			final char currentChar = input.charAt(i);
			
			if (currentChar != lastChar)
			{
				if (chainLength == 2)
					output += lastChar;
				
				if (chainLength > 2)
					output += chainLength;
				
				output += currentChar;
				
				chainLength = 1;
			}
			else
			{
				chainLength++;
			}
			
			lastChar = currentChar;
		}
		if (chainLength == 2)
			output += lastChar;
		
		else if (chainLength > 2)
			output += chainLength;
		
		return output;
	}
```


```
public static String myEncode(String input)
	{
		String output = "";

		for (int i = 0; i < input.length(); i++)
		{
			int chainLength = 1;
			char currentChar = input.charAt(i);
			
			for (int j = i+1; j < input.length(); j++)
			{
				if (input.charAt(j) == currentChar)
				{
					chainLength++;
					i++;
				}
				else
				{
					break;
				}
			}
			
			output += currentChar;
			
			if (chainLength == 2)
				output += currentChar;
			
			else if (chainLength > 2)
				output += chainLength;
		}
		
		return output;
	}
```


----------



## urgs (10. Nov 2014)

Ich habe die Diskussion interessehalber mitverfolgt und schreibe im Moment den Decoder! Bekomm ihn jedoch nicht zum laufen, kann mir da jemanden einen Tipp geben?
Danke


----------



## Flown (10. Nov 2014)

Man kann dir nicht helfen, wenn du deinen Code nicht postest!


----------



## JavaMeister (10. Nov 2014)

Und schreibe bitte nicht nur Code sondern was nicht funktioniert.


----------



## moz923 (10. Nov 2014)

Hallo,
bin leider auch beim decoder hängen geblieben.
Ich bekomme keinen Error aber auch kein Ergebnis.
Ich wäre sehr dankbar für einen Tipp.


```
public class Decoder{ 

  public static void main(String[] args){
  
  
  String s, r ;

  
  s = SavitchIn.readLine();
  r = decode (s);
  System.out.println(r);
  
}  
public static String decode (String s){

int count, position;
  String finalString;
  position = 0;
  count=0;
  finalString = "";
  s= s + "-";
  boolean run= true;
  
  while (run == true){
    char p1 = s.charAt(position);
  //  char p2 = s.charAt(position+1);
  

    
  if (Character.isLetter(p1)){
     finalString = finalString + s.charAt(position);
     position++;
  }   
  
  else if ( Character.isDigit(p1)){
    String sub;
    int n = 0;
    int finalNumber= 0;
    int countNumbers = position;
    int positionNumbers = position;
      while (Character.isDigit(s.charAt(positionNumbers)) && Character.isDigit(s.charAt(positionNumbers+1))){
        countNumbers++;
        positionNumbers++;
      }
    sub = s.substring(position, countNumbers);
    n = sub.length() - 1;
    for ( int strint = 0; strint < sub.length(); strint++){ 
      finalNumber  = finalNumber + Character.getNumericValue(sub.charAt(strint))* 10^n;
      n--; 
    } 
    for( int i = 0 ; i <= finalNumber; i++){
      finalString= finalString + s.charAt(position-1);   
    }
    position++;
  }
  else if ( s.charAt(position) == Character.MATH_SYMBOL){
    run = false;
  }
  
  }
  return finalString;

  }
  }
```


----------



## JavaMeister (10. Nov 2014)

Das ist viel zu kompliziert. 

Zwei Schleifen reichen. 

Die erste geht Zeichen für Zeichen durch. 

Wenn es auf eine Zahl trifft,
Dann wird sooft das nächste Zeichen ausgegeben. 

Fertig.


----------



## Flown (10. Nov 2014)

Ich kann mich JavaMeister nur anschließen. 

Meine Implementierung, damit auch eine funktionierende Lösung (vl. auch sogar sauber ) vorhanden ist.

Wenn dann, dann so:


Spoiler: code





```
public class Test {
  
  public static void main(String... args) {
    String in = "aabbbbbcccddddddddddddddd";
    String encode = encode(in);
    System.out.println(encode);
    String decode = decode(encode);
    System.out.println(decode);
    System.out.println(in.equals(decode));
  }
  
  public static String encode(String input) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < input.length(); i++) {
      char cur = input.charAt(i);
      int occurence = 1;
      for (int j = i + 1; j < input.length(); j++) {
        if (cur == input.charAt(j)) {
          i++;
          occurence++;
        } else {
          break;
        }
      }
      if (occurence > 2) {
        builder.append(cur);
        builder.append(occurence);
      } else {
        for (int j = 0; j < occurence; j++) {
          builder.append(cur);
        }
      }
    }
    return builder.toString();
  }
  
  public static String decode(String input) {
    StringBuilder builder = new StringBuilder();
    char lastLetter = '\0';
    for (int i = 0; i < input.length(); i++) {
      char cur = input.charAt(i);
      if (Character.isDigit(cur)) {
        int number = Character.getNumericValue(cur);
        for (int j = i + 1; j < input.length(); j++) {
          cur = input.charAt(j);
          if (!Character.isDigit(cur)) {
            break;
          }
          number = number * 10 + Character.getNumericValue(cur);
          i++;
        }
        for (int j = 1; j < number; j++) {
          builder.append(lastLetter);
        }
      } else {
        lastLetter = cur;
        builder.append(cur);
      }
    }
    return builder.toString();
  }
}
```




@moz923

Ich hab mir deinen Code ehrlich gesagt nicht durchgesehen, aber ich kann dir sagen, dass 
	
	
	
	





```
finalNumber  = finalNumber + Character.getNumericValue(sub.charAt(strint))* 10^n;[COLOR=#339933][/COLOR]
```
 nicht richtig sein kann. 

Guck dir doch mal "^" Operator in Java an.


----------



## urgs (10. Nov 2014)

hab jetzt das Programm fast fertig! Was jz leider das Problem ist, ist dass ich eine out of Bounds exception bekomme! 
zB. a11 wird zu aaaaaaaaaaa
könnt mir jemand einen Tip geben? Ich weiß dass es an (Character.isDigit(s.charAt(i + 1)) hapert.

for (int i = 0; i < s.length(); i++) {

            if (Character.isDigit(s.charAt(i))) {

                int n = (int) (s.charAt(i) - '0');

                if (Character.isDigit(s.charAt(i + 1))) {

                    int l = (int) (s.charAt(i + 1) - '0');                    
                    int x = n * 10 + l;

                    for (int h = 0; h < x; h++) {

                        q += s.charAt(i - 1);
                    }
                }              
                for (int j = 1; j < n; j++) {

                    q += s.charAt(i - 1);

                }

            } else {

                q += s.charAt(i);
            }

        }


----------



## JavaMeister (10. Nov 2014)

Schaue vorher, ob der Buchstabe existiert. Normal dürfte der nur dann da sein , wenn aktuell eine Zahl gelesen wird.
Wenn du beim letzen Buchstaben bist, dann hast du keinen nöchsten.


----------



## gamduju (10. Nov 2014)

Mein Ansatz für den Decoder  sieht wie folgt aus ich bekomme aber auch immer eine out of bounds exception:

public static String decode (String s) {
      int number=0, i = 1;
      String s2 =("");
      while(i<s.length()){
         char currentchar = s.charAt(i);
         i++;

         if (Character.isDigit(s.charAt(i))) {
               number = (int) (s.charAt(i)-'0');
               i++;
               while (Character.isDigit(s.charAt(i))){
                  number = 10* number + (int) (s.charAt(i)-'0');
                  i++;
               }
         }
         s2 = s2 + currentchar + number * currentchar;



      }

      return s2;
   }

bin am verzweifeln könnt ihr mir vielleicht auf die Sprünge helfen?


----------



## JavaMeister (10. Nov 2014)

Wieviele Leute posten hier und haben gleichzeitig den total falschen Studiengang oder Unterricht erwischt?

Leute.. Erstmal würde ich ja LESEN, was bisher hier steht. Dann eine zweite nicht funktionierende Lösung zu posten, die scheinbar genau die gleiche von oben ist, bringts hier auch nicht.

Bisschen mehr Struktur bitte.

Außerdem steht hier eine voll funktionierende Lösung. Unfassbar, dass die auch ignoriert wird. Kein Wunde, dass wir einen Fachkräftemangel haben.


----------

