Run-length decompression - java

CS student here. I want to write a program that will decompress a string that has been encoded according to a modified form of run-length encoding (which I've already written code for). For instance, if a string contains 'bba10' it would decompress to 'bbaaaaaaaaaa'. How do I get the program to recognize that part of the string ('10') is an integer?
Thanks for reading!

A simple regex will do.
final Matcher m = Pattern.compile("(\\D)(\\d+)").matcher(input);
final StringBuffer b = new StringBuffer();
while (m.find())
m.appendReplacement(b, replicate(m.group(1), Integer.parseInt(m.group(2))));
m.appendTail(b);
where replicate is
String replicate(String s, int count) {
final StringBuilder b = new StringBuilder(count);
for (int i = 0; i < count; i++) b.append(s);
return b.toString();
}

Not sure whether this is one efficient way, but just for reference
for (int i=0;i<your_string.length();i++)
if (your_string.charAt(i)<='9' && your_string.charAt(i)>='0')
integer_begin_location = i;

I think you can divide chars in numeric and not numeric symbols.
When you find a numeric one (>0 and <9) you look to the next and choose to enlarge you number (current *10 + new) or to expand your string

Assuming that the uncompressed data does never contain digits: Iterate over the string, character by character until you get a digit. Then continue until you have a non-digit (or end of string). The digits inbetween can be parsed to an integer as others already stated:
int count = Integer.parseInt(str.substring(start, end));

Here is a working implementation in python. This also works fine for 2 or 3 or multiple digit numbers
inputString="a1b3s22d4a2b22"
inputString=inputString+"\0" //just appending a null char
charcount=""
previouschar=""
outputString=""
for char in inputString:
if char.isnumeric():
charcount=charcount+char
else:
outputString=outputString
if previouschar:
outputString=outputString+(previouschar*int(charcount))
charcount=""
previouschar=char
print(outputString) // outputString= abbbssssssssssssssssssssssddddaabbbbbbbbbbbbbbbbbbbbbb

Presuming that you're not asking about the parsing, you can convert a string like "10" into an integer like this:
int i = Integer.parseInt("10");

Related

Replacing a character in a string from another string with the same char index

I'm trying to search and reveal unknown characters in a string. Both strings are of length 12.
Example:
String s1 = "1x11222xx333";
String s2 = "111122223333"
The program should check for all unknowns in s1 represented by x|X and get the relevant chars in s2 and replace the x|X by the relevant char.
So far my code has replaced only the first x|X with the relevant char from s2 but printed duplicates for the rest of the unknowns with the char for the first x|X.
Here is my code:
String VoucherNumber = "1111x22xx333";
String VoucherRecord = "111122223333";
String testVoucher = null;
char x = 'x'|'X';
System.out.println(VoucherNumber); // including unknowns
//find x|X in the string VoucherNumber
for(int i = 0; i < VoucherNumber.length(); i++){
if (VoucherNumber.charAt(i) == x){
testVoucher = VoucherNumber.replace(VoucherNumber.charAt(i), VoucherRecord.charAt(i));
}
}
System.out.println(testVoucher); //after replacing unknowns
}
}
I am always a fan of using StringBuilders, so here's a solution using that:
private static String replaceUnknownChars(String strWithUnknownChars, String fullStr) {
StringBuilder sb = new StringBuilder(strWithUnknownChars);
while ((int index = Math.max(sb.toString().indexOf('x'), sb.toString().indexOf('X'))) != -1) {
sb.setCharAt(index, fullStr.charAt(index));
}
return sb.toString();
}
It's quite straightforward. You create a new string builder. While a x or X can still be found in the string builder (indexOf('X') != -1), get the index and setCharAt.
Your are using String.replace(char, char) the wrong way, the doc says
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
So you if you have more than one character, this will replace every one with the same value.
You need to "change" only the character at a specific spot, for this, the easiest is to use the char array that you can get with String.toCharArray, from this, this is you can use the same logic.
Of course, you can use String.indexOf to find the index of a specific character
Note : char c = 'x'|'X'; will not give you the expected result. This will do a binary operation giving a value that is not the one you want.
The OR will return 1 if one of the bit is 1.
0111 1000 (x)
0101 1000 (X)
OR
0111 1000 (x)
But the result will be an integer (every numeric operation return at minimum an integer, you can find more information about that)
You have two solution here, you either use two variable (or an array) or if you can, you use String.toLowerCase an use only char c = 'x'

Looking to restrict the length of a string in Java

I'd like to count the amount of characters within a string, and cut off any excess characters of the string. I thought of just using a while loop and a char, but I need to pass in a string. I also tried to use the remainder function, but I"m pretty sure it wouldn't work.
So, essentially, a counter for a string and then to limit that string to x amount of characters.
If I were to set the string to a single character, say
String x = "*";
Then implemented a counter in a for loop...
for(int i = 0; i < 6; i++){
???
}
Would that work? I feel like it wouldn't, and that it would just be more effective for me to declare
char x = 'a';
...
I'm trying to make this as vague as possible so that I can take ideas and implement them so it's not like I'm stealing anybody's code for homework, I just need a little help.
String myString = "myString";
int maxLength = 3;
if (myString.length() > maxLength)
myString = myString.substring(0, maxLength);
Result will be "myS"
"I was searching around on the web for a manual code to count the amount of characters within a string, and then to a further extent cut off any excess characters of the string."
Count amount of characters within a string:
int length = stringName.length();
Cutting off extra characters of the string
int maxAmount; //wherever you want to stop
if(length > maxAmount)
{
stringName = stringName.substring(0,stopPoint);
}

From string to ASCII to binary back to ASCII to string in Java

I have sort of a funky question (that I hope hasn't been asked and answered yet). To start, I'll tell you the order of what I'm trying to do and how I'm doing it and then tell you where I'm having a problem:
Convert a string of characters into ASCII numbers
Convert those ASCII numbers into binary and store them in a string
Convert those binary numbers back into ASCII numbers
Convert the ASCII numbers back into normal characters
Here are the methods I've written so far:
public static String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public static String binaryToString(String binaryString){
int charCode = Integer.parseInt(binaryString, 2);
String returnString = new Character((char)charCode).toString();
return returnString;
}
I'm getting a NumberFormatException when I run the code and I think it's because the program is trying to convert the binary digits as one entire binary number rather than as separate letters. Based on what you see here, is there a better way to do this overall and/or how can I tell the computer to recognize the ASCII characters when it's iterating through the binary code? Hope that's clear and if not I'll be checking for comments.
So I used OP's code with some modifications and it works really well for me.
I'll post it here for future people. I don't think OP needs it anymore because he probably figured it out in the past 2 years.
public class Convert
{
public String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public String binaryToString(String binaryString){
String returnString = "";
int charCode;
for(int i = 0; i < binaryString.length(); i+=7)
{
charCode = Integer.parseInt(binaryString.substring(i, i+7), 2);
String returnChar = new Character((char)charCode).toString();
returnString += returnChar;
}
return returnString;
}
}
I'd like to thank OP for writing most of it out for me. Fixing errors is much easier than writing new code.
You've got at least two problems here:
You're just concatenating the binary strings, with no separators. So if you had "1100" and then "0011" you'd get "11000011" which is the same result as if you had "1" followed by "1000011".
You're calling String.replace and ignoring the return result. This sort of doesn't matter as you're replacing spaces, and there won't be any spaces anyway... but there should be!
Of course you don't have to use separators - but if you don't, you need to make sure that you include all 16 bits of each UTF-16 code point. (Or validate that your string only uses a limited range of characters and go down to an appropriate number of bits, e.g. 8 bits for ISO-8859-1 or 7 bits for ASCII.)
(I have to wonder what the point of all of this is. Homework? I can't see this being useful in real life.)

How can I extract the numbers from a string only using charAt(), length() and/or toCharArray() in Java

I have to do this for an assignment in my java class. I have been searching for a while now, but only find solutions with regex etc.
For my assignment however I may only use charAt(), length() and/or toCharArray(). I need to get from a string like gu578si300 for example just the numbers so it will become: 578300.
i know numbers are 48 - 57 in ASCII but i can't figure out how to do this in java. You guys any ideas?
i was thinking about a for loop that checks whether the (int) char is between 48-57 en if so puts the value into a seperate array. Howeevr i dont know how to programm that last thing.
I now have this;
public static String filterGetallenreeks(String reeks){
String temp = "";
for (char c : reeks.toCharArray()) {
if ((int) c > 47 && (int) c < 58)
temp += c;
}
return temp;
however it is not working, it just outputs the same as goes in.
is it something in my mainm which looks like this. If i'm right the return temp; will return the temp string into the reeks string in the main right? why is my input still the same a sthe output?
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Voer een zin, woord of cijferreeks in:");
String reeks = sc.nextLine();
if (isGetallenreeks(reeks)){
System.out.println("is getallenreeks");
filterGetallenreeks(reeks);
System.out.println(reeks);
}
Since this is homework I will not be providing the complete solution, however, this is how you should go about it:
Do a for loop that iterates for the total amount of characters within the string (.length). Check if the character is a digit using the charAt and isDigit methods.
You could do a loop that checks a character in the string, and if it's a number, append it to another string:
//I haven't tested this, so you know.
String test = "gu578si300 ";
String numbers = "";
for(int i=0; i<test.length(); i++){
if("0123456789".indexOf(test.charAt(i)) // if the character at position i is a number,
numbers = numbers + test.charAt(i); // Add it to the end of "numbers".
}
int final = Integer.parseInt(numbers); // If you need to do something with those numbers,
// Parse it.
Let me know if that works for you.
It seems like a reasonable approach, but I'd make a couple of changes from what you suggested:
If you need to result as a string then use a StringBuilder instead of an array.
Use character literals like '0' and '9' instead of ASCII codes to make your code more readable.
Update
The specific problem with your code is this line:
temp = temp + (int)c;
This converts the character to its ASCII value and then converts that to a decimal string containing the ASCII value. That's not what you want. Use this instead:
temp += c;

Homework: Java IO Streaming and String manipulation

In Java,
I need to read lines of text from a file and then reverse each line, writing the reversed version into another file. I know how to read from one file and write to another. What I don't know how to do is manipulate the text so that "This is line 1" would be written into the second file as "1 enil si sihT"
since these are homeworks you are probably interested in your own implementation of reverse method.
The naive version visits the string backwards (from the last index to the index 0) while copying it in a StringBuilder:
public String reverse(String s) {
StringBuilder sb = new StringBuilder();
for (int i = s.length() - 1; i >= 0; i--) {
sb.append(s.charAt(i));
}
return sb.toString();
}
for example the String "hello":
H e l l o
0 1 2 3 4 // indexes for charAt()
the method start by the index 4 ('o') then the index 3 ('l') ... until 0 ('H').
StringBuilder buffer = new StringBuilder(theString);
return buffer.reverse().toString();
If this is homework, it would be better for you to understand how are data stored into the string it self.
A string may be represented as an array of characters
String line = // read line ....;
char [] data = line.toCharArray();
To reverse an array you have to swap the positions of the elements. The first in the last, the last in the first and so on.
int l = data.length;
char temp;
temp = data[0]; // put the first element in "temp" to avoid losing it.
data[0] = data[l - 1]; // put the last value in the first;
data[l - 1] = temp; // and the first in the last.
Continue with the rest of the elements ( hint use a loop ) in the array and then create a new String with the result:
String modifiedString = new String( data ); // where data is the reversed array.
If is not ( and you really just need to have the work done ) use:
StringBuilder.reverse()
Good luck.
String reversed = new StringBuilder(textLine).reverse().toString();
The provided answers all suggest using an already existing method, which is sound advice and usually more effective than writing your own.
Depending on the assignment, however, your teacher might expect you to write a method of your own. If that is the case, try using a for loop to walk through the string character by character, only instead of counting from zero and up, start counting from the last character index and down to zero, consecutively building the reversed string.
While we're feeding horrible, finished answers to the poor student, we might as well whet his appetite for the bizarre. If strings were guaranteed to be reasonably short and CPU time was no object, this is what I'd code:
public static String reverse(String str) {
if (str.length() == 0) return "";
else return reverse(str.substring(1)) + str.charAt(0);
}
(OK, I admit it: my current favorite language is Clojure, a Lisp!)
BONUS HOMEWORK: Figure out if, how and why this works!
java.lang.StringBuffer has a reverse method.

Categories