rle compression algorithm java - java

I have to do a RLE algorithm in java with the escape character (Q)
Example 1 if i have an input like:
77777 => 57
BBBBBBBBB => 10B
FBFB8923 => 004FBFB8923
2365553422 => 005236555342200
this is the code that i made:
public String coderRLE(string text) {
String res = new String();
char[] charArray = text.toCharArray();
char caractere = 0;
int num = 0;
int i = 0;
for (char c : charArray) {
if (c != caractere && i != 0) {
if (num >= 2) {
res += num;
res += caractere;
} else {
res += caractere;
}
num = 1;
} else {
num++;
}
caractere = c;
i++;
}
if (num >= 2) {
res += num;
res += caractere;
} else {
res += caractere;
}
return res;
}
public String decoderRLE(String text) {
String res = new String();
char[] charArray = text.toCharArray();
for (int i = 0;i<charArray.length-1;i++) {
char s = charArray[i];
if (!Character.isDigit(s)) {
res += s;
} else {
int num = Integer.parseInt(String.valueOf(s));
for (int j = 0; j < num - 1; j++) {
res += charArray[i+1];
}
}
}
return res;
}
the problem is with number like thisaaabbcccc666iii => aaabbcccc6633333ii

Try,
public static String encode(String source) {
StringBuffer dest = new StringBuffer();
for (int i = 0; i < source.length(); i++) {
int runLength = 1;
while (i+1 < source.length() && source.charAt(i) == source.charAt(i+1)) {
runLength++;
i++;
}
dest.append(runLength);
dest.append(source.charAt(i));
}
return dest.toString();
}
if the input is aaabbcccc666iii it compress it as 3a2b4c363i
String example = "aaabbcccc666iii";
System.out.println(encode(example));
Output
3a2b4c363i

Related

Array index out of bounds exception. Please help if you can [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 5 years ago.
Extremely close to having this task finished but can't see which part of this is holding me back. If anybody could put me on the right track I'd be very thankful. the following is the error code that eclipse gives me each time I try to run this.
**Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
at lab01.EncodeDecode.backMap(EncodeDecode.java:162)
at lab01.EncodeDecode.Decode(EncodeDecode.java:68)
at lab01.EncodeDecode.(EncodeDecode.java:26)
at lab01.EncodeDecodeTester.main(EncodeDecodeTester.java:14)**
package lab01;
import java.util.*;
/**
*
* #author David Bierbrauer,
*
*/
public class EncodeDecode
{
//method declaration
static String[] originalList,encodedList,decodedList;
static int total;
public EncodeDecode(String[] oL)
{
//instance variable declaration
total = oL.length;
originalList = new String[total];
encodedList = new String[total];
decodedList = new String[total];
originalList = oL;
encodedList= Encode(originalList);
decodedList = Decode(encodedList);
}
public static String[] Encode (String[] originalList)
{
//declare control variables
String currentWord = "", codedWord = "";
char currentChar = ' ';
int i = 0, j = 0, stringLength = 0;
for (i=0; i < total ; i++)
{
currentWord = originalList[i];
stringLength = currentWord.length();
for (j = 0; j < stringLength; j++)
{
currentChar = currentWord.charAt(j);
codedWord = codedWord +forwardMap(currentChar);
}
encodedList[i] = codedWord;
codedWord = "";
}
return encodedList;
}
public static String[] Decode (String[] encodedList)
{
String currentWord = "", encodedWord = "";
char currentChar = ' ';
int i =0, j=0, stringLength = 0;
for(i = 0; i < total; i++)
{
currentWord = encodedList[i];
stringLength = currentWord.length();
for(j = 0; j < stringLength; j++)
{
currentChar = currentWord.charAt(j);
encodedWord = encodedWord + backMap(currentChar);
}
decodedList[i] = encodedWord;
encodedWord = "";
}
return decodedList;
}
public static char forwardMap(char currentChar)
{
char newChar = ' ';
int i = 0;
String encodeMapUpper = "CDEFGHIJKLMNOPQRSTUVWXYZAB";
String encodeMapLower = "cdefghijklmnopqrstuvwxyzab";
String encodeMapNumber = "2345678901";
char [] encodeArrayUpper = encodeMapUpper.toCharArray();
char [] encodeArrayLower = encodeMapLower.toCharArray();
char [] encodeArrayNumber = encodeMapNumber.toCharArray();
if(encodeMapUpper.indexOf(currentChar) != -1)
{
for( i = 0; i < encodeArrayUpper.length; i++)
{
if(currentChar == encodeArrayUpper[i])
{
newChar = encodeArrayUpper[(i+2) % 26];
}
}
}
else if(encodeMapLower.indexOf(currentChar) != -1)
{
for( i = 0; i < encodeArrayLower.length; i++)
{
if(currentChar == encodeArrayLower[i])
{
newChar = encodeArrayLower[(i+2) % 26];
}
}
}
else if(encodeMapNumber.indexOf(currentChar) != -1)
{
for( i = 0; i < encodeArrayNumber.length; i++)
{
if(currentChar == encodeArrayNumber[i])
{
newChar = encodeArrayNumber[(i+2) % 10];
}
}
}
else
{
//element is a special character
newChar = currentChar;
}
return newChar;
}
public static char backMap(char currentChar)
{
char newChar = ' ';
int i = 0;
String decodeMapUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String decodeMapLower = "abcdefghijklmnopqrstuvwxyz";
String decodeMapNumber = "0123456789";
char[] decodeArrayUpper = decodeMapUpper.toCharArray();
char[] decodeArrayLower = decodeMapLower.toCharArray();
char[] decodeArrayNumber = decodeMapNumber.toCharArray();
if (decodeMapUpper.indexOf(currentChar) != -1)
{
for (i=0; i < decodeArrayUpper.length; i++)
{
if (currentChar == decodeArrayUpper[i])
{
newChar = decodeArrayUpper[(i - 2) % 26];
}
}
}
else if(decodeMapLower.indexOf(currentChar) != -1)
{
for (i=0; i < decodeArrayLower.length; i++)
{
if (currentChar == decodeArrayLower[i])
{
newChar = decodeArrayLower[(i - 2) % 26];
}
}
}
else if(decodeMapNumber.indexOf(currentChar) != -1)
{
for (i=0; i < decodeArrayNumber.length; i++)
{
if (currentChar == decodeArrayNumber[i])
{
newChar = decodeArrayNumber[(i - 2) % 10];
}
}
}
else
{
newChar = currentChar;
}
return newChar;
}
//get methods
public String[] getEncodedList() { return encodedList;}
public String[] getDecodedList() { return decodedList;}
}
This is the tester class bellow just in case.
package lab01;
public class EncodeDecodeTester
{
public static void main(String[] args)
{
EncodeDecode testEncoder;
int x = 0;
String[] output = new String[5];
String[] oL = new String[] {"catdog","24","keys","Duck","PIZZA!"};
//create encoder
testEncoder = new EncodeDecode(oL);
System.out.println("Encoded list:");
for( x = 0; x < output.length; x++)
{
output = testEncoder.getEncodedList();
System.out.println(output[x]);
}
System.out.println();
System.out.println("Decoded List:");
for(x = 0; x < output.length; x++)
{
output = testEncoder.getDecodedList();
System.out.println(output[x] + " ");
}
System.out.println();
System.out.println("End");
}
}
Please help I am completely lost for words on what I did wrong here.
The Java % operator doesn't always produce a number between 0 and the second operand. Replace (i - 2) % 26 (which can produce -2) with (i + 24) % 26 and similarly in other places.

Extract the particular portion from a String

I have the below String variable
String s = "abc,xyz,lmn,ijk";
I want to extract only the portion of the String (i.e - 'lmn')
And, Should not use in-built functions like, SubString(), Split(), IndexOf(). But I can use charArray()
And this question was asked in my interview.
I tried the below code,
But not sure how to proceed. Can any one please provide your thoughts?
String s = "abc,xyz,lmn,ijk";
int counter = 0;
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if (ch[i] == ',') {
counter++;
}
}
Here's one way:
public static void main(String[] args) {
String s = "abc,xyz,lmn,ijk";
char[] ch = s.toCharArray();
int counter = 0;
int place = 2;
for (int i = 0; i < ch.length-2; i++) {
if(ch[i] == ',') {
counter++;
}
if(counter == place && ch[i] != ',') {
System.out.print(ch[i]);
}
}
}
It prints everything after the second comma, but before the third one.
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "abc,xyz,lmn,ijk";
StringBuffer sb=new StringBuffer();
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if(','==(ch[i]))
{
if (sb.toString().equals("lmn")) {
System.out.println(sb.toString());
}
else
{
int length=sb.length();
sb.delete(0, length);
}
}
else
{
sb.append(ch[i]);
}
}
}
I would do it this way.
String s = "abc,xyz,lmn,ijk";
String x = "c,x"; // String to found
String r = "";
boolean coincidence = false;
int a=0; // Initial index if of the first character in x is found
int b=0; // Last index If it was possible to search for the last character of x
int c=0; // Index "iterator" on String x
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if(c == x.length())
break;
else{
if(ch[i] == x.charAt(c) && !coincidence){
a = i; b = i; c++;
coincidence = true;
}
else if(ch[i] == x.charAt(c) && coincidence){
b++; c++;
}else{
coincidence = false;
a = 0; b = 0; c = 0;
}
}
}
System.out.println("String: " + s);
System.out.println("String to find: " + x);
System.out.println("Was found? " + ((coincidence)? "Yes" : "No"));
if(coincidence){
System.out.println("Intervals indexes in String: ["+a + "," + b +"]");
// String extration
for (int i = a; i <= b; i++)
r += s.charAt(i);
System.out.println("String extracted: " + r);
}

Java Decode RLE string

Example if i have an input like:
H9e3e2l5o
the output have to be:
Heeeeeeeeeeeellooooo
This is the code that I wrote so far:
public class RLE {
public static String decode(String st) {
char[] stArr = st.toCharArray();
char lastseen = 0;
StringBuilder sb = new StringBuilder();
for (char s : stArr) {
if (!Character.isDigit(s)) {
lastseen = s;
sb.append(s);
} else {
int n = Integer.parseInt(String.valueOf(s));
for (int i = 0; i < n - 1; i++) {
sb.append(lastseen);
}
}
}
return sb.toString();
}
Results in:
'H9e3e2l5o' -> HHHHHHHHHeeeeelllllo
I'm assuming generic variant, here is corrected version:
public static String decode(final String st) {
final StringBuilder sb = new StringBuilder();
final char[] chars = st.toCharArray();
int i = 0;
while (i < chars.length) {
int repeat = 0;
while ((i < chars.length) && Character.isDigit(chars[i])) {
repeat = repeat * 10 + chars[i++] - '0';
}
final StringBuilder s = new StringBuilder();
while ((i < chars.length) && !Character.isDigit(chars[i])) {
s.append(chars[i++]);
}
if (repeat > 0) {
for (int j = 0; j < repeat; j++) {
sb.append(s.toString());
}
} else {
sb.append(s.toString());
}
}
return sb.toString();
}
#Test
public void test() {
Assert.assertEquals("abb", decode("1a2b"));
Assert.assertEquals("aaaaaaaaaa", decode("10a"));
Assert.assertEquals("baaaaaaaaaa", decode("b10a"));
Assert.assertEquals("abab", decode("2ab"));
Assert.assertEquals("Heeeeeeeeeeeellooooo", decode("H9e3e2l5o"));
}

Using java, input string="aabbcdeaaaabbb" and the output must be aaaa

Using java, input string="aabbcdeaaaabbb" and the output must be aaaa, as sequence here is having repeated 4 times a. Can anyone help me to get this "aaaa" as output using java implementation.
Algorithm to find the Longest substring having same character repeated.
for eg:
I/P: aabbcdefaaaacccccc O/P: cccccc
Please check my program below and suggest any optimization for faster processing:
public class LongestSubString {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
System.out
.println("Enter a word to find longest substring with same characters repeated");
String word = reader.readLine();
System.out.println("Entered word is: " + word);
System.out.println("Longest repeated characters substring is: "
+ subStringFinder(word));
}
/*
*longest substring finder with same character repeated
*/
public static String subStringFinder(String word) {
char[] tokens = word.toCharArray();
int len = tokens.length;
int wordLen = word.length();
System.out.println("len of input word: " + wordLen);
List<String> myList = new ArrayList<>();
StringBuilder strConcat = new StringBuilder("");
for (int j = 0; j <= len - 1; j++) {
if (j + 1 > len - 1) {
if ((strConcat.length() >= 1)
&& (strConcat.charAt(strConcat.length() - 1) == (tokens[j]))) {
strConcat.append("" + tokens[j]);
myList.add(strConcat.toString());
}
}
else {
if (tokens[j] == tokens[j + 1]) {
if ((strConcat.length() >= 1)
&& (strConcat.charAt(strConcat.length() - 1) == (tokens[j]))) {
strConcat.append("" + tokens[j]);
myList.add(strConcat.toString());
} else {
strConcat = new StringBuilder("");
strConcat.append("" + tokens[j]);
}
} else {
if ((strConcat.length() >= 1)
&& (strConcat.charAt(strConcat.length() - 1) == (tokens[j]))) {
strConcat.append("" + tokens[j]);
myList.add(strConcat.toString());
} else {
strConcat = new StringBuilder("");
strConcat.append("" + tokens[j]);
}
}
}
}
int max = 0, index = 0;
for (int i = 0; i < myList.size(); i++) {
String strEle = myList.get(i);
int strLen = strEle.length();
if (max < strLen) {
max = strLen;
index = i;
}
}
return myList.get(index);
}
}
I believe your code is overly complicated. You don’t need a StringBuilder nor an ArrayList. I tried to understand your intention, but then skipped it and wrote my own version instead. Hope it helps anyway.
public static String subStringFinder(String word) {
if (word == null || word.isEmpty()) {
return word;
}
char currentChar = word.charAt(0);
int longestStart = 0;
int longestLength = 0;
int currentStart = 0;
int currentLength = 1;
for (int ix = 1; ix < word.length(); ix++) {
if (word.charAt(ix) == currentChar) {
currentLength++;
} else {
if (currentLength > longestLength) {
longestStart = currentStart;
longestLength = currentLength;
}
currentChar = word.charAt(ix);
currentStart = ix;
currentLength = 1;
}
}
if (currentLength > longestLength) {
longestStart = currentStart;
longestLength = currentLength;
}
return word.substring(longestStart, longestStart + longestLength);
}
String in = "aabbcdeaaaabbb";
String t;
ArrayList<String> out = new ArrayList<String>();
String l="";
int c=0;
String n;
for(int i=0;i<in.length;i++) {
n=in.substring(i, i+1); //get the current character
if(n.equals(l)){
l=n; c++;
}
else {
t=n;
for(int j=1;j<c;j++) {
n+=t;
}
c=0;
out.add(n);
c=0;
}
}

How to Search and Get Strings between Special Characters [] in a Dynamic Text

Can you please let me know how Can I list ONLY strings which are between [] characters? For example I have a string like
5014 [228] 6:37a 6:522* 7:06a8 7:22a [229] 9:32b8 ...
and I need to add each of strings between [] into an array.
Second try, I hope this works.
I didnt have the time to test it with other strings of that type.
String str = "5014 [228] 6:37a 6:522* 7:06a8 7:22a [229] 9:32b8";
String[][] result = new String[2][2]; //You can change the size of the array by yourself,
//for that case 2 2 should be enough
//you could make n 2
String[] data1;
String[] data2;
String output1 = ""; //for the number between the bracets
String output2 = "";//for the numbers outside of the bracets
char[] help1 = new char[str.length()];
char[] help2 = new char[str.length()];
Arrays.fill(help1, '0');
Arrays.fill(help2, '0');
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '[') {
while (c != ']') {
i++;
help1[i] = str.charAt(i);
c = str.charAt(i);
}
}
if(c == ']'){
while (c != '[') {
i++;
if(i > str.length()-1){
break;
}
help2[i] = str.charAt(i);
c = str.charAt(i);
}
i--;
}
}
for (int i = 0; i < help1.length; i++) {
if (help1[i] != '0') {
output1 += help1[i];
}
}
for (int i = 0; i < help1.length; i++) {
if (help2[i] != '0') {
output2 += help2[i];
}
}
data1 = output1.split("\\]");
data2 = output2.split("\\[");
StringBuilder sb;
for (int i = 0; i < data2.length; i++) {
if(i == data2.length){
sb = new StringBuilder(data2[i]);
sb.deleteCharAt(0);
data2[i] = sb.toString();
}else{
sb = new StringBuilder(data2[i]);
sb.deleteCharAt(0);
sb.deleteCharAt(data2[i].length()-2);
data2[i] = sb.toString();
}
}
for (int i = 0; i < data1.length; i++) {
result[i][0] = data1[i];
result[i][1] = data2[i];
}
}

Categories