Hello I am having trouble implementing this function
Function:
Decompress the String s. Character in the string is preceded by a number. The number tells you how many times to repeat the letter. return a new string.
"3d1v0m" becomes "dddv"
I realize my code is incorrect thus far. I am unsure on how to fix it.
My code thus far is :
int start = 0;
for(int j = 0; j < s.length(); j++){
if (s.isDigit(charAt(s.indexOf(j)) == true){
Integer.parseInt(s.substring(0, s.index(j))
Assuming the input is in correct format, the following can be a simple code using for loop. Of course this is not a stylish code and you may write more concise and functional style code using Commons Lang or Guava.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i += 2) {
final int n = Character.getNumericValue(s.charAt(i));
for (int j = 0; j < n; j++) {
builder.append(s.charAt(i + 1));
}
}
System.out.println(builder.toString());
Here is a solution you may like to use that uses Regex:
String query = "3d1v0m";
StringBuilder result = new StringBuilder();
String[] digitsA = query.split("\\D+");
String[] letterA = query.split("[0-9]+");
for (int arrIndex = 0; arrIndex < digitsA.length; arrIndex++)
{
for (int count = 0; count < Integer.parseInt(digitsA[arrIndex]); count++)
{
result.append(letterA[arrIndex + 1]);
}
}
System.out.println(result);
Output
dddv
This solution is scalable to support more than 1 digit numbers and more than 1 letter patterns.
i.e.
Input
3vs1a10m
Output
vsvsvsammmmmmmmmm
Though Nami's answer is terse and good. I'm still adding my solution for variety, built as a static method, which does not use a nested For loop, instead, it uses a While loop. And, it requires that the input string has even number of characters and every odd positioned character in the compressed string is a number.
public static String decompress_string(String compressed_string)
{
String decompressed_string = "";
for(int i=0; i<compressed_string.length(); i = i+2) //Skip by 2 characters in the compressed string
{
if(compressed_string.substring(i, i+1).matches("\\d")) //Check for a number at odd positions
{
int reps = Integer.parseInt(compressed_string.substring(i, i+1)); //Take the first number
String character = compressed_string.substring(i+1, i+2); //Take the next character in sequence
int count = 1;
while(count<=reps)//check if at least one repetition is required
{
decompressed_string = decompressed_string + character; //append the character to end of string
count++;
};
}
else
{
//In case the first character of the code pair is not a number
//Or when the string has uneven number of characters
return("Incorrect compressed string!!");
}
}
return decompressed_string;
}
Related
I would like to find the sum of integer in string. For example:
String myString= "The price is 345and the tax1 is 12sales";
String output = "The price is 12and the tax1 is 3sales";
I found few approaches none is displaying the final output the way I need.
int sum = 0;
for (int I =0; i < myString.lengh(); i++)
{
char c = myString.charAt(i);
if(Character.isDigit(c))
{
int value = Integer.parseInt(String.valueOf(c));
}
}
I am getting the total sum but I would like to be able to append the string with individual sums.
output = "The price is 12and the tax1 is 3sales"
I'm using a StringBuilder for building the result string. You have to keep adding the digits as long as you encounter digits. When you encounter a character, you have to append the sum at hand (if you have) and then append the character.
Note: This won't work if the sum can be 0 (and needs to be tweaked to support that).
int sum = 0;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < myString.length(); i++)
{
char c = myString.charAt(i);
if(Character.isDigit(c))
{
sum += Integer.parseInt(String.valueOf(c));
} else {
if (sum != 0) {
builder.append(sum);
}
builder.append(c);
sum = 0; //reset
}
}
add an if statement checking the next character for a digit, if it's a digit add it, otherwise you are done and can print it.
However, your input is quite unusual, are you sure you can not improve the input itself?
I'm trying to make a code that deletes the repeated characters. For example - if we have a string "aabacdc", we want to make it as "abd". If the character exists twice in the string, then we delete both characters as we did in the above example. The 'a' occurs 3 times in our string, so we just deleted the 2 a and left 1 remaining.
What I'm trying to do in this code is use two nested for loops - first for loop to compare the first character with the other characters. If the character has a duplicate in the string, then just delete both the characters. How can I fix this code?
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str2 = input.nextLine();
StringBuilder str = new StringBuilder(str2);
for (int k = 0; k < str.length() - 1; k++) {
for (int i = 1; i < str.length() - 1; i++) {
if (str.charAt(k) == str.charAt(i)) {
str.deleteCharAt(k);
str.deleteCharAt(i);
}
}
}
System.out.println(str);
}
My interpretation of what you're trying to do based on your expected output is that you want to remove characters from the string 1 pair at a time. So if there is an odd number of a character in the string, 1 should remain, and if there's an even number 0 should remain.
Any time you're removing elements from a structure while you're iterating by index, you need to loop over the structure backwards, so that the index values don't shift as you delete elements. This means you should only delete elements which the outer loop is currently at, or has already seen (i.e. only delete elements at indexes >= i).
Scanner input = new Scanner(System.in);
String str = input.nextLine();
StringBuilder sb = new StringBuilder(str);
for (int i = sb.length() - 2; i >= 0; i--) {
for (int j = i + 1; j < sb.length(); j++) {
if (sb.charAt(i) == sb.charAt(j)) {
sb.deleteCharAt(j);
sb.deleteCharAt(i);
break;
}
}
}
System.out.println(sb);
Ideone Demo
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am doing one simple java code where if
input is : "aabbba"
then
output should be: "a2b3a1"
I have done the below coding but missing somewhere. So let me know my mistake.
public class Test {
public static void main(String[] args) {
String str = "aabbba";
int count = 1;
for (int i = 0; i < str.length(); i = i + count) {
count = 1;
for (int j = i + 1; j < str.length(); j++) {
if (str.charAt(i) == str.charAt(j)) {
count = count + 1;
} else {
System.out.println(str.charAt(i) + "" + count);
break;
}
}//end of inner for
}//end of outer for
}//end of main
}//end of class
Actually you have too much code, You only need one loop, and you should be comparing the letter to the previous one, not attempting to compare each letter to every letter after it.
If you are confused about what your program is doing, the best place to start is to use your debugger to step through the code.
for(int i = 0, count = 1; i < str.length(); i++, count++) {
char ch = str.charAt(i);
char next = i + 1 < str.length() ? str.charAt(i + 1) : (char) -1;
if (ch != next) {
System.out.print("" + ch + count);
count = 0;
}
}
Using your effort and code, you simply did put the print to the wrong place
String str = "aabbba";
int count = 1;
for(int i = 0; i <str.length();i=i+count){
count =1;
for(int j = i+1; j<str.length();j++){
if(str.charAt(i) == str.charAt(j)){
count = count+1;
}
else{
break;
}
}
// Print here otherwise you will miss the last group of letters
// Also if you just want one line use .print instead of println
System.out.print(str.charAt(i)+""+count);
}
Using Java-8 and my StreamEx library it's a one-liner:
String input = "aabbba";
String result = IntStreamEx.ofChars(input).mapToObj(ch -> (char)ch)
.runLengths().join("").joining();
Step-by step:
IntStreamEx.ofChars(input): create IntStreamEx (enhanced IntStream) where each element is the corresponding character of input line.
.mapToObj(ch -> (char)ch): transform to StreamEx<Character> (enhanced Stream<Character>) where each element is the Character object.
.runLengths(): convert to EntryStream<Character, Long> (enhanced Stream<Map.Entry<Character, Long>>) where keys are Character objects and values are counts of equal adjacent characters.
.join(""): convert to StreamEx<String>, joining keys (characters) and values (counts) via given empty separator.
.joining(): final reduction to the resulting string without additional separators.
You're just missing the print of the last group of letters. you only print inside the loop once you found a different letter, you should take into account the last group of letters that has no "different letter" after it
I would suggest using a StringBuilder:
public String myOutput(String str) {
if (str == null || str.length() == 0)
return str;
StringBuilder sb = new StringBuilder();
int count = 1;
char currentChar;
for (int i = 0; i < str.length() - 1; i++) {
currentChar = str.charAt(i);
if (currentChar == str.charAt(i+1)) {
count++;
} else {
sb.append(currentChar);
sb.append(String.valueOf(count));
count = 1;
}
}
sb.append(str.charAt(str.length()-1));
sb.append(String.valueOf(count));
return sb.toString();
}
You only need 1 loop
System.out.println() will cause your output to have line break. You better use System.out.print(). Now your currrent code is resulting :
a2
b3
I have a string that contains numbers like: 02101403101303101303140
how can I iterate the string to check whether the number in string is >= 2 and remember that number's index in array or list for further processing?
the further processing should be replacing substrings.
for example: the iterator found number 2 and remembers the index of this character.
Now it takes the next character from 2 and remembers this character index also.
Now it is possible to replace the substring.
Let's say there is 21. Now I want this to become 11
Or lets say there is 60, this should be replaced with 000000.
First number is indicator of "how many" and the second number is "what".
Or is there a better way to remember and replace certain substrings in that way?
Thank you in advance.
There you go. but remember to atleast try next time
String str = "02101403101303101303140";
StringBuilder sb = new StringBuilder();
for(int i=0; i < str.length(); i+=2)
for(int j =0; j < Integer.parseInt(String.valueOf(str.charAt(i))); j++)
sb.append(str.charAt(i+1));
System.out.print(sb.toString());
Not sure if I'm understanding well your question, you could try something like this:
String mystring = "02101403101303101303140";
String target = "21";
String replacement = "11"
String newString = mystring.replace(target, replacement);
String str = "02101403101303101303140";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if(Integer.parseInt(String.valueOf(str.charAt(i))) >= 2) {
int temp = Integer.parseInt(String.valueOf(str.charAt(i))) - 1;
for (int j = 0; j < temp ; j++) {
sb.append(str.charAt(i+1));
}
}
else {
sb.append(str.charAt(i));
}
}
System.out.println(sb.toString());
This would produce: 01101000011101000111010001110000 which is binary for "http" (without quotes).
Thank you all! What I really needed was a push to right direction and thank zubergu for that. Also fr34k gave the best answer!
I'm currently working on a problem in code hunt level 6.02 which asks me to capitalize every other letter in a String. I have tried doing it with toCharArray + StringBuilder in for loops. It works, but it's not good enough. I still can't get the perfect score for the problem. I'm running out of ideas. Any help will be greatly appreciated.
Note: This is my first post on stack overflow. So if I miss anything or ask question in a wrong way. Pls feel free to point it out for me. Thx.
s is the input string
Attempt 1:
char [] words = s.toCharArray();
for (int i = 0; i < words.length; i +=2){
words[i] = Character.toUpperCase(words[i]);
}
return new String(words);
Attempt 2:
StringBuilder result = new StringBuilder(s);
for (int i = 0; i < result.length(); i +=2){
result.replace(i, i + 1, result.substring(i,i + 1).toUpperCase());
}
return result.toString();
Input: "iaiaa"
Expected output: "IaIaA"
In both of your attempts, you're going through the characters 2 1/2 times.
Taking your second attempt;
StringBuilder result = new StringBuilder(s);
for (int i = 0; i < result.length(); i +=2){
result.replace(i, i + 1, result.substring(i,i + 1).toUpperCase());
}
return result.toString();
The first line copies all the characters, and your last line copies all the characters. Your for loop goes through half the characters, for a total of 2 1/2 sets of characters.
I don't know if this is faster, but here's my attempt.
String r = "";
for (int i = 0; i < s.length; i++) {
if (i % 2 == 0) {
r += s.substring(i, i + 1).toUpperCase();
} else {
r += s.substring(i, i + 1);
}
}
return r;
I realize that this looks like a lot of intermediate Strings are created, but string concatenation has improved since Java 1.7.
I don't know how efficient this really is, but this does the trick for capitalizing the first letter and every other letter after.
String sentence = "i want to manipulate this string";
char[] array = new char[] {};
array = sentence.toCharArray(); //put the sentence into a character array
for (int i = 0; i < array.length; i += 2) {
if (array[i] == ' ') { //if the character is blank, move to the next index
i++;
}
array[i] = Character.toUpperCase(array[i]); //capitalize
}
sentence = new String(array); //revert array back to String
System.out.println(sentence); //display