String Lauflängen Encoder und Decoder

Awaxor

Mitglied
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.
 

njans

Top Contributor
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

Mitglied
Hallo JavaMeister,

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

Java:
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:
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.
 
Zuletzt bearbeitet von einem Moderator:

JavaMeister

Gesperrter Benutzer
Ja,

Java:
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

Top Contributor
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

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

JavaMeister

Gesperrter Benutzer
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.
 

njans

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


Java:
	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;
	}

Java:
	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

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

Java:
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;
	}

Java:
	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;
	}
 
Zuletzt bearbeitet:

urgs

Neues Mitglied
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
 

moz923

Neues Mitglied
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.

Java:
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

Gesperrter Benutzer
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

Administrator
Mitarbeiter
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:
Java:
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
Java:
finalNumber  = finalNumber + Character.getNumericValue(sub.charAt(strint))* 10^n;[COLOR=#339933][/COLOR]
nicht richtig sein kann.

Guck dir doch mal "^" Operator in Java an.
 
Zuletzt bearbeitet:

urgs

Neues Mitglied
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

Gesperrter Benutzer
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

Neues Mitglied
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

Gesperrter Benutzer
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.
 
Zuletzt bearbeitet:

Oben