Compress string longer than 2 - loops - java

Method to compress a string using java and loops. For example, if dc = "aabbbccaaaaba, then c = "aab3cca4ba" Here is what I have so far. Please help/guide. Thanks.
int cnt = 1;
String ans = "";
for (int i = 0; i < dc.length(); i++) {
if ((i < dc.length()) && (dc.charAt(i) == dc.charAt(i++)) && (dc.charAt(i) == dc.charAt(i+=2))){
cnt++;
ans = ans + dc.charAt(i) + cnt;
}
else
ans = ans + dc.charAt(i);
setC(ans);

Unless you're restricted to using for loops, I believe this would do the trick:
String sb = "";
for (int i = 0; i < dc.length(); i++) {
char c = dc.charAt(i);
int count = 1;
while (i + 1 < dc.length() && (dc.charAt(i + 1)) == c) {
count++;
i++;
}
if (count > 1) {
sb += count;
}
sb += c;
}
System.out.println(sb);
edit:
Changed the example to use regular String instead of StringBuilder. However, I really advise against concatenating strings this way, especially if the string you're trying to compress is long.

It might be easier to get what you want by using Sting.toCharArray().
Then manipulate the array accordingly.

String dc = "aabbbccaaaaba";
String and = "";
int index = 0;
int cnt = 2;
While(dc.charAt(index) != null){
int index1 = index + 1;
char j = dc.charAt(index)
While(j.equals(dc.charAt(index1)){
cnt++;
}
//more code
index++;
}
It's a little incomplete but if you follow the logic I think it's what you're looking for. I won't do your assignment for you.

Easiest Solution: - Only one for loop, Time Complexity - O(n)
public static void main(String[] args) {
String str = "aabbbccaaaaba";
char[] arr = str.toCharArray();
int length = arr.length;
StringBuilder sb = new StringBuilder();
int count=1;
for(int i=0; i<length; i++){
if(i==length-1){
sb.append(arr[i]+""+count);
break;
}
if(arr[i]==arr[i+1]){
count++;
}
else{
sb.append(arr[i]+""+count);
count=1;
}
}
System.out.println(sb.toString());
}

Related

how to merge two strings into one by using chartAt() and arrays technique

as mentioned in the title, I got an error in each line inside for loop which says (variable expected) and this is my code
String s = "ABC";
String t = "DEFGH";
String merge = "";
// merge should looks like "ADBECFGH"
int i = 0;
for (; i < s.length(); i=i+2) {
merge.charAt(i) = s.charAt(i/2);
merge.charAt(i+1) = t.charAt(i/2);
}
for (; i < t.length()+s.length() ; i++) {
merge.charAt(i) = t.charAt(i-s.length());
}
am trying to use same technique with arrays which I think its very effective.
If you like take one letter from first string and then from other try this:
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge += String.valueOf(s.charAt(i));
}
if (i < t.length()) {
merge += String.valueOf(t.charAt(i));
}
}
This is condition that let you iterate till longer String finish
i < s.length() || i < t.length()
Another one, since you are manipulating Strings inside a loop, it is better to use StringBuilder instead of String.
String s = "ABC";
String t = "DEFGH";
StringBuilder merge = new StringBuilder();
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge.append(s.charAt(i));
}
if (i < t.length()) {
merge.append(t.charAt(i));
}
}
System.out.println(merge.toString());
The method charAt(int index) returns the character at the specified index(IT IS A GETTER NOT A SETTER). You cannot use it as
merge.charAt(i) = s.charAt(i/2)
one of the easiest ways to perform such operation is to use string operation such as concatination as shown in the below example
s="abc";
t="def";
System.out.print(s.concat(t));
You could simply use the .concact() method without using the for loop:
so your code would look like:
merge = s.concat(t);
try this : concatenate two string without inbuilt method and without + operator.
public static void main(String[] args) {
String s = "ABC";
String s1 = "DEF";
String merge = "";
char[]ch = new char[120];
for(int i=0;i<s.length();i++) {
ch[i] = s.charAt(i);
}
for(int i = 0;i<s1.length();i++) {
ch[s.length()+i] = s1.charAt(i);
}
System.out.println(ch);
}
CharacterIterator a = new StringCharacterIterator("haaaaallo");
CharacterIterator b = new StringCharacterIterator("12345");
StringBuilder output = new StringBuilder();
if(a.getEndIndex() < b.getEndIndex()) { //true -> swap a and b
CharacterIterator holder = a;
a = b;
b = holder;
}
while (a.current() != CharacterIterator.DONE) {
output.append(a.current());
while (b.current() != CharacterIterator.DONE) {
output.append(b.current());
break;
}
a.next();
b.next();
}
System.out.println(output.toString()); //h1a2a3a4a5allo
To show "the manual way". The used Strings can be any size.
I would go with #Bartek's answer its simple and easy to remember..
the complicated way to achieve this would be
String a = "abcdefgh";
String b = "ijklmnopqrst";
int i = 0;
StringBuilder merge = new StringBuilder();
for (; i < a.length() && i < b.length(); i++) {
merge.append(a.charAt(i)).append(b.charAt(i));
}
if (i < a.length())
merge.append(a.substring(i));
if (i < b.length())
merge.append(b.substring(i));
Only to avoid having if conditions inside the for loop.. (optimal only in case of large strings, strings of vastly different lengths)

String compression algorithm in Java

I am looking to implement a method to perform basic string compression in the form of:
aabcccccaaa -> a2b1c5a3
I have this program:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(compress(str));
}
public static String compress(String str) {
char[] chars = str.toCharArray();
int count = 0;
String result = "";
for (int i = 0; i < chars.length; i++) {
char curr = chars[i];
result += curr;
for (int j = i; j < chars.length; j++) {
if (chars[j] == curr) {
count++;
}
else {
i += count;
break;
}
}
result += count;
count = 0;
}
return result;
}
}
But in my tests I am always missing the last character count.
I assume this is because the program gets out of the inner for loop before it should, but why is this the case?
Thanks a lot
You don't need two for loops for this and can do it in one go like so
String str = "aaabbbbccccca";
char[] chars = str.toCharArray();
char currentChar = str.length() > 0 ? chars[0] : ' ';
char prevChar = ' ';
int count = 1;
StringBuilder finalString = new StringBuilder();
if(str.length() > 0)
for(int i = 1; i < chars.length; i++)
{
if(currentChar == chars[i])
{
count++;
}else{
finalString.append(currentChar + "" + count);
prevChar = currentChar;
currentChar = chars[i];
count = 1;
}
}
if(str.length() > 0 && prevChar != currentChar)
finalString.append(currentChar + "" + count);
System.out.println(finalString.toString());
Output is: a3b4c5a1 for aaabbbbccccca
Keep a track of character that you are reading and compare it with next character of the string. If it is different, reset the count.
public static void stringCompression (String compression) {
String finalCompressedString = "";
char current = '1';
int count = 0;
compression = compression + '1';
for (int i = 0; i < compression.length(); i++) {
if (compression.charAt(i) == current) {
count = count + 1;
} else {
if (current != '1')
finalCompressedString = finalCompressedString + (current + Integer.toString(count));
count = 1;
current = compression.charAt(i);
}
}
System.out.println(finalCompressedString);
}
My answer for String Compression in java.
In this what i have done is and what you should have done is that , Keep a record of the characters that that are coming for a specific number of times, do so by comparing the current character with the next character , and when the current and the next character become unequal reset the value of count and repeat the whole process again for the next different character.
Hope it helps!
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int count = 0;
for (int i=0; i<str.length(); ++i) {
int j=i+1;
count=1;
while (j!=str.length() && str.charAt(i) == str.charAt(j)) {
count += 1;
j += 1;
i += 1;
}
System.out.print(str.charAt(i));
if (count > 1) {
System.out.print(count);
}
}
}
}

String Compression loop logic

My for loop for my string compression is a bit off. I have been working on this assignment the past 5 days and I can't figure out for the life of me what is wrong. Can someone help me out?
For example, I passed over the string "TTTTrrrEe" and instead of getting T4r3Ee, I'm getting T4r3EeTT. I don't know why it jumps back to the beginning of the string like that, but I am getting closer.We can only use charAt,equals,length, and substring from the string class.
Can someone help guide me in the right direction by helping to correct my logic? I still want to try and code this myself, seeing as how it is an assignment.
public static String compress(String s){
int count = 0;
String temp = s.substring(0,1);
for(int i = 0; i < s.length(); i++){
if(i !=s.length()-1){
if(temp.equals(s.substring(i,i+1))){
count++;
}else{
if(count < 1){
System.out.print(s.substring(i,i+2));
System.out.print(temp.substring(0,1) );
}else{
System.out.print("" + temp.substring(0,1) + count);
i--;
temp = s.substring(count,count+1);
System.out.println(" temp is now " + temp);
count = 0;
//i--;
}
}
}
}
System.out.println(temp);
return temp;
}
Since this is a learning exercise, I wouldn't try fixing your code, just point out a few things to work on to get it right:
The if (i !=s.length()-1) condition inside the loop becomes unnecessary if you change your for loop condition to i < s.length()-1
Comparing individual characters is easier (and faster) than comparing substrings. You get a character at position i by calling char ch1 = s.charAt(i), and compare two characters using == operator, rather than calling equals() on them.
When count is zero (your count < 1 condition is equivalent to count == 0) you print both the current character and the character after it, in addition to the first character of temp followed by the count. This does not look correct.
Rather than growing temp as you go through the loop, you set it on each iteration. This does not look correct.
A better way of growing temp as you go through the loop is using StringBuilder and append(), instead of using a plain String, and performing concatenations.
Try using some logic like this;
int count = 0;
for(int i =0; i < string.length()-1; i++){
if(string.charAt(i) == string.charAt(i + 1)){
count++;
// DO SOME OPERATION
}
}
temp = s.substring(count,count+1); does not relate to a position (i), but a size.
In fact I would try to rewrite it afresh, with externally sensible names:
char repeatedChar = `\u0000`; // Not present.
int repetitions = 0;
Because of the no-namer count you got into trouble.
Working code:
public class HelloWorld {
public static void compress(String s){
StringBuilder buff = new StringBuilder();
char tmp = '\0';
int index = 1;
for(int i = 0; i < s.length(); i++){
char curr = s.charAt(i);
if(buff.length() == 0){
tmp = curr;
buff.append(tmp);
continue;
}
if(curr == tmp){
index++;
}
else{
if(index > 1){
buff.append(index);
index = 1;
tmp = curr;
}
buff.append(curr);
}
}
System.out.println(buff.toString());
}
public static void main(String args[]){
compress("TTTTrrrEe");
}
}
Output: T4r3Ee
For compress("TTsssssssssssTTrrrEe");
Output: T2s11T2r3Ee
String temp = s.substring(0,1);
temp.equals(s.substring(i,i+1))
In case of these 2 sentences you should have used a char instead of String, as such:
char temp = s.charAt(0)
temp == s.charAt(i)
I would start with 3 variables:
char lastCharacter = inputString.charAt(0);
int count = 1;
String result = "";
then proceed to process the input string in a loop:
if (length <= 1) return inputString;
for i = 1 ; i < length;i++
if (inputString.charAt(i) == lastCharacter && i != length-1)
count++
else
if count == 1
result += lastCharacter
else
result = result + lastCharacter + count;
count = 1;
end if
lastCharacter = inputString.charAt(i);
end if
end for
return result;
TRY THIS
public class Compress {
/**
* #param args
* #author Rakesh KR
*/
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(source.charAt(i));
dest.append(runLength);
}
return dest.toString();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String example = "aaaaaaBBBBccc";
System.out.println("Encode::"+encode(example));
}
}

Fancy looping in Java

I have a problem wherein I have two strings, the length of one of which I will know only upon execution of my function. I want to write my function such that it would take these two stings and based upon which one is longer, compute a final string as under -
finalString = longerStringChars1AND2
+ shorterStringChar1
+ longerStringChars3and4
+ shorterStringChar2
+ longerStringChars5AND6
...and so on till the time the SHORTER STRING ENDS.
Once the shorter string ends, I want to append the remaining characters of the longer string to the final string, and exit. I have written some code, but there is too much looping for my liking. Any suggestions?
Here is the code I wrote - very basic -
public static byte [] generateStringToConvert(String a, String b){
(String b's length is always known to be 14.)
StringBuffer stringToConvert = new StringBuffer();
int longer = (a.length()>14) ? a.length() : 14;
int shorter = (longer > 14) ? 14 : a.length();
int iteratorForLonger = 0;
int iteratorForShorter = 0;
while(iteratorForLonger < longer) {
int count = 2;
while(count>0){
stringToConvert.append(b.charAt(iteratorForLonger));
iteratorForLonger++;
count--;
}
if(iteratorForShorter < shorter && iteratorForLonger >= longer){
iteratorForLonger = 0;
}
if(iteratorForShorter<shorter){
stringToConvert.append(a.charAt(iteratorForShorter));
iteratorForShorter++;
}
else{
break;
}
}
if(stringToConvert.length()<32 | iteratorForLonger<b.length()){
String remainingString = b.substring(iteratorForLonger);
stringToConvert.append(remainingString);
}
System.out.println(stringToConvert);
return stringToConvert.toString().getBytes();
}
You can use StringBuilder to achieve this. Please find below source code.
public static void main(String[] args) throws InterruptedException {
int MAX_ALLOWED_LENGTH = 14;
String str1 = "yyyyyyyyyyyyyyyy";
String str2 = "xxxxxx";
StringBuilder builder = new StringBuilder(MAX_ALLOWED_LENGTH);
builder.append(str1);
char[] shortChar = str2.toCharArray();
int index = 2;
for (int charCount = 0; charCount < shortChar.length;) {
if (index < builder.length()) {
// insert 1 character from short string to long string
builder.insert(index, shortChar, charCount, 1);
}
// 2+1 as insertion index is increased after after insertion
index = index + 3;
charCount = charCount + 1;
}
String trimmedString = builder.substring(0, MAX_ALLOWED_LENGTH);
System.out.println(trimmedString);
}
Output
yyxyyxyyxyyxyy
String one = "longwordorsomething";
String two = "short";
String shortString = "";
String longString = "";
if(one.length() > two.length()) {
shortString = two;
longString = one;
} else {
shortString = one;
longString = two;
}
StringBuilder newString = new StringBuilder();
int j = 0;
for(int i = 0; i < shortString.length(); i++) {
if((j + 2) < longString.length()) {
newString.append(longString.substring(j, j + 2));
j += 2;
}
newString.append(shortString.substring(i, i + 1));
}
// Append last part
newString.append(longString.substring(j));
System.out.println(newString);

Java compressing Strings

I need to create a method that receives a String and also returns a String.
Ex input: AAABBBBCC
Ex output: 3A4B2C
Well, this is quite embarrassing and I couldn't manage to do it on the interview that I had today ( I was applying for a Junior position ), now, trying at home I made something that works statically, I mean, not using a loop which is kind of useless but I don't know if I'm not getting enough hours of sleep or something but I can't figure it out how my for loop should look like. This is the code:
public static String Comprimir(String texto){
StringBuilder objString = new StringBuilder();
int count;
char match;
count = texto.substring(texto.indexOf(texto.charAt(1)), texto.lastIndexOf(texto.charAt(1))).length()+1;
match = texto.charAt(1);
objString.append(count);
objString.append(match);
return objString.toString();
}
Thanks for your help, I'm trying to improve my logic skills.
Loop through the string remembering what you last saw. Every time you see the same letter count. When you see a new letter put what you have counted onto the output and set the new letter as what you have last seen.
String input = "AAABBBBCC";
int count = 1;
char last = input.charAt(0);
StringBuilder output = new StringBuilder();
for(int i = 1; i < input.length(); i++){
if(input.charAt(i) == last){
count++;
}else{
if(count > 1){
output.append(""+count+last);
}else{
output.append(last);
}
count = 1;
last = input.charAt(i);
}
}
if(count > 1){
output.append(""+count+last);
}else{
output.append(last);
}
System.out.println(output.toString());
You can do that using the following steps:
Create a HashMap
For every character, Get the value from the hashmap
-If the value is null, enter 1
-else, replace the value with (value+1)
Iterate over the HashMap and keep concatenating (Value+Key)
use StringBuilder (you did that)
define two variables - previousChar and counter
loop from 0 to str.length() - 1
each time get str.charat(i) and compare it to what's stored in the previousChar variable
if the previous char is the same, increment a counter
if the previous char is not the same, and counter is 1, increment counter
if the previous char is not the same, and counter is >1, append counter + currentChar, reset counter
after the comparison, assign the current char previousChar
cover corner cases like "first char"
Something like that.
The easiest approach:- Time Complexity - O(n)
public static void main(String[] args) {
String str = "AAABBBBCC"; //input String
int length = str.length(); //length of a String
//Created an object of a StringBuilder class
StringBuilder sb = new StringBuilder();
int count=1; //counter for counting number of occurances
for(int i=0; i<length; i++){
//if i reaches at the end then append all and break the loop
if(i==length-1){
sb.append(str.charAt(i)+""+count);
break;
}
//if two successive chars are equal then increase the counter
if(str.charAt(i)==str.charAt(i+1)){
count++;
}
else{
//else append character with its count
sb.append(str.charAt(i)+""+count);
count=1; //reseting the counter to 1
}
}
//String representation of a StringBuilder object
System.out.println(sb.toString());
}
In the count=... line, lastIndexOf will not care about consecutive values, and will just give the last occurence.
For instance, in the string "ABBA", the substring would be the whole string.
Also, taking the length of the substring is equivalent to subtracting the two indexes.
I really think that you need a loop.
Here is an example :
public static String compress(String text) {
String result = "";
int index = 0;
while (index < text.length()) {
char c = text.charAt(index);
int count = count(text, index);
if (count == 1)
result += "" + c;
else
result += "" + count + c;
index += count;
}
return result;
}
public static int count(String text, int index) {
char c = text.charAt(index);
int i = 1;
while (index + i < text.length() && text.charAt(index + i) == c)
i++;
return i;
}
public static void main(String[] args) {
String test = "AAABBCCC";
System.out.println(compress(test));
}
Please try this one. This may help to print the count of characters which we pass on string format through console.
import java.util.*;
public class CountCharacterArray {
private static Scanner inp;
public static void main(String args[]) {
inp = new Scanner(System.in);
String str=inp.nextLine();
List<Character> arrlist = new ArrayList<Character>();
for(int i=0; i<str.length();i++){
arrlist.add(str.charAt(i));
}
for(int i=0; i<str.length();i++){
int freq = Collections.frequency(arrlist, str.charAt(i));
System.out.println("Frequency of "+ str.charAt(i)+ " is: "+freq);
}
}
}
Java's not my main language, hardly ever use it, but I wanted to give it a shot :]
Not even sure if your assignment requires a loop, but here's a regexp approach:
public static String compress_string(String inp) {
String compressed = "";
Pattern pattern = Pattern.compile("([\\w])\\1*");
Matcher matcher = pattern.matcher(inp);
while(matcher.find()) {
String group = matcher.group();
if (group.length() > 1) compressed += group.length() + "";
compressed += group.charAt(0);
}
return compressed;
}
This is just one more way of doing it.
public static String compressor(String raw) {
StringBuilder builder = new StringBuilder();
int counter = 0;
int length = raw.length();
int j = 0;
while (counter < length) {
j = 0;
while (counter + j < length && raw.charAt(counter + j) == raw.charAt(counter)) {
j++;
}
if (j > 1) {
builder.append(j);
}
builder.append(raw.charAt(counter));
counter += j;
}
return builder.toString();
}
The following can be used if you are looking for a basic solution. Iterate through the string with one element and after finding all the element occurrences, remove that character. So that it will not interfere in the next search.
public static void main(String[] args) {
String string = "aaabbbbbaccc";
int counter;
String result="";
int i=0;
while (i<string.length()){
counter=1;
for (int j=i+1;j<string.length();j++){
System.out.println("string length ="+string.length());
if (string.charAt(i) == string.charAt(j)){
counter++;
}
}
result = result+string.charAt(i)+counter;
string = string.replaceAll(String.valueOf(string.charAt(i)), "");
}
System.out.println("result is = "+result);
}
And the output will be :=
result is = a4b5c3
private String Comprimir(String input){
String output="";
Map<Character,Integer> map=new HashMap<Character,Integer>();
for(int i=0;i<input.length();i++){
Character character=input.charAt(i);
if(map.containsKey(character)){
map.put(character, map.get(character)+1);
}else
map.put(character, 1);
}
for (Entry<Character, Integer> entry : map.entrySet()) {
output+=entry.getValue()+""+entry.getKey().charValue();
}
return output;
}
One other simple way using Multiset of guava-
import java.util.Arrays;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multiset.Entry;
public class WordSpit {
public static void main(String[] args) {
String output="";
Multiset<String> wordsMultiset = HashMultiset.create();
String[] words="AAABBBBCC".split("");
wordsMultiset.addAll(Arrays.asList(words));
for (Entry<String> string : wordsMultiset.entrySet()) {
if(!string.getElement().isEmpty())
output+=string.getCount()+""+string.getElement();
}
System.out.println(output);
}
}
consider the below Solution in which the String s1 identifies the unique characters that are available in a given String s (for loop 1), in the second for loop build a string s2 that contains unique character and no of times it is repeated by comparing string s1 with s.
public static void main(String[] args)
{
// TODO Auto-generated method stub
String s = "aaaabbccccdddeee";//given string
String s1 = ""; // string to identify how many unique letters are available in a string
String s2=""; //decompressed string will be appended to this string
int count=0;
for(int i=0;i<s.length();i++) {
if(s1.indexOf(s.charAt(i))<0) {
s1 = s1+s.charAt(i);
}
}
for(int i=0;i<s1.length();i++) {
for(int j=0;j<s.length();j++) {
if(s1.charAt(i)==s.charAt(j)) {
count++;
}
}
s2=s2+s1.charAt(i)+count;
count=0;
}
System.out.println(s2);
}
It may help you.
public class StringCompresser
{
public static void main(String[] args)
{
System.out.println(compress("AAABBBBCC"));
System.out.println(compress("AAABC"));
System.out.println(compress("A"));
System.out.println(compress("ABBDCC"));
System.out.println(compress("AZXYC"));
}
static String compress(String str)
{
StringBuilder stringBuilder = new StringBuilder();
char[] charArray = str.toCharArray();
int count = 1;
char lastChar = 0;
char nextChar = 0;
lastChar = charArray[0];
for (int i = 1; i < charArray.length; i++)
{
nextChar = charArray[i];
if (lastChar == nextChar)
{
count++;
}
else
{
stringBuilder.append(count).append(lastChar);
count = 1;
lastChar = nextChar;
}
}
stringBuilder.append(count).append(lastChar);
String compressed = stringBuilder.toString();
return compressed;
}
}
Output:
3A4B2C
3A1B1C
1A
1A2B1D2C
1A1Z1X1Y1C
The answers which used Map will not work for cases like aabbbccddabc as in that case the output should be a2b3c2d2a1b1c1.
In that case this implementation can be used :
private String compressString(String input) {
String output = "";
char[] arr = input.toCharArray();
Map<Character, Integer> myMap = new LinkedHashMap<>();
for (int i = 0; i < arr.length; i++) {
if (i > 0 && arr[i] != arr[i - 1]) {
output = output + arr[i - 1] + myMap.get(arr[i - 1]);
myMap.put(arr[i - 1], 0);
}
if (myMap.containsKey(arr[i])) {
myMap.put(arr[i], myMap.get(arr[i]) + 1);
} else {
myMap.put(arr[i], 1);
}
}
for (Character c : myMap.keySet()) {
if (myMap.get(c) != 0) {
output = output + c + myMap.get(c);
}
}
return output;
}
O(n) approach
No need for hashing. The idea is to find the first Non-matching character.
The count of each character would be the difference in the indices of both characters.
for a detailed answer: https://stackoverflow.com/a/55898810/7972621
The only catch is that we need to add a dummy letter so that the comparison for
the last character is possible.
private static String compress(String s){
StringBuilder result = new StringBuilder();
int j = 0;
s = s + '#';
for(int i=1; i < s.length(); i++){
if(s.charAt(i) != s.charAt(j)){
result.append(i-j);
result.append(s.charAt(j));
j = i;
}
}
return result.toString();
}
The code below will ask the user for user to input a specific character to count the occurrence .
import java.util.Scanner;
class CountingOccurences {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
String str;
char ch;
int count=0;
System.out.println("Enter the string:");
str=inp.nextLine();
System.out.println("Enter th Char to see the occurence\n");
ch=inp.next().charAt(0);
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)==ch)
{
count++;
}
}
System.out.println("The Character is Occuring");
System.out.println(count+"Times");
}
}
public static char[] compressionTester( char[] s){
if(s == null){
throw new IllegalArgumentException();
}
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0 ; i < s.length ; i++) {
if(!map.containsKey(s[i])){
map.put(s[i], 1);
}
else{
int value = map.get(s[i]);
value++;
map.put(s[i],value);
}
}
String newer="";
for( Character n : map.keySet()){
newer = newer + n + map.get(n);
}
char[] n = newer.toCharArray();
if(s.length > n.length){
return n;
}
else{
return s;
}
}
package com.tell.datetime;
import java.util.Stack;
public class StringCompression {
public static void main(String[] args) {
String input = "abbcccdddd";
System.out.println(compressString(input));
}
public static String compressString(String input) {
if (input == null || input.length() == 0)
return input;
String finalCompressedString = "";
String lastElement="";
char[] charArray = input.toCharArray();
Stack stack = new Stack();
int elementCount = 0;
for (int i = 0; i < charArray.length; i++) {
char currentElement = charArray[i];
if (i == 0) {
stack.push((currentElement+""));
continue;
} else {
if ((currentElement+"").equalsIgnoreCase((String)stack.peek())) {
stack.push(currentElement + "");
if(i==charArray.length-1)
{
while (!stack.isEmpty()) {
lastElement = (String)stack.pop();
elementCount++;
}
finalCompressedString += lastElement + "" + elementCount;
}else
continue;
}
else {
while (!stack.isEmpty()) {
lastElement = (String)stack.pop();
elementCount++;
}
finalCompressedString += lastElement + "" + elementCount;
elementCount=0;
stack.push(currentElement+"");
}
}
}
if (finalCompressedString.length() >= input.length())
return input;
else
return finalCompressedString;
}
}
public class StringCompression {
public static void main(String[] args){
String s = "aabcccccaaazdaaa";
char check = s.charAt(0);
int count = 0;
for(int i=0; i<s.length(); i++){
if(s.charAt(i) == check) {
count++;
if(i==s.length()-1){
System.out.print(s.charAt(i));
System.out.print(count);
}
} else {
System.out.print(s.charAt(i-1));
System.out.print(count);
check = s.charAt(i);
count = 1;
if(i==s.length()-1){
System.out.print(s.charAt(i));
System.out.print(count);
}
}
}
}
// O(N) loop through entire character array
// match current char with next one, if they matches count++
// if don't then just append current char and counter value and then reset counter.
// special case is the last characters, for that just check if count value is > 0, if it's then append the counter value and the last char
private String compress(String str) {
char[] c = str.toCharArray();
String newStr = "";
int count = 1;
for (int i = 0; i < c.length - 1; i++) {
int j = i + 1;
if (c[i] == c[j]) {
count++;
} else {
newStr = newStr + c[i] + count;
count = 1;
}
}
// this is for the last strings...
if (count > 0) {
newStr = newStr + c[c.length - 1] + count;
}
return newStr;
}
public class StringCompression {
public static void main(String... args){
String s="aabbcccaa";
//a2b2c3a2
for(int i=0;i<s.length()-1;i++){
int count=1;
while(i<s.length()-1 && s.charAt(i)==s.charAt(i+1)){
count++;
i++;
}
System.out.print(s.charAt(i));
System.out.print(count);
}
System.out.println(" ");
}
}
This is a leet code problem 443. Most of the answers here uses StringBuilder or a HashMap, the actual problem statement is to solve using the input char array and in place array modification.
public int compress(char[] chars) {
int startIndex = 0;
int lastArrayIndex = 0;
if (chars.length == 1) {
return 1;
}
if (chars.length == 0) {
return 0;
}
for (int j = startIndex + 1; j < chars.length; j++) {
if (chars[startIndex] != chars[j]) {
chars[lastArrayIndex] = chars[startIndex];
lastArrayIndex++;
if ((j - startIndex) > 1) {
for (char c : String.valueOf(j - startIndex).toCharArray()) {
chars[lastArrayIndex] = c;
lastArrayIndex++;
}
}
startIndex = j;
}
if (j == chars.length - 1) {
if (j - startIndex >= 1) {
j = chars.length;
chars[lastArrayIndex] = chars[startIndex];
lastArrayIndex++;
for (char c : String.valueOf(j - startIndex).toCharArray()) {
chars[lastArrayIndex] = c;
lastArrayIndex++;
}
} else {
chars[lastArrayIndex] = chars[startIndex];
lastArrayIndex++;
}
}
}
return lastArrayIndex;
}
}

Categories

Resources