String Pattern Question - Core Java (repeatSeparator) - java

Write a Java function such that Given two strings, word and a separator, return a big string made of count occurences of the word, separated by the separator string.
repeatSeparator("Word", "X", 3) → "WordXWordXWord"
repeatSeparator("This", "And", 2) → "ThisAndThis"
repeatSeparator("This", "And", 1) → "This"
My code is as below but is not working
public String repeatSeparator(String word, String sep, int count) {
if(count == 1) {
return word;
}
if(count > 1) {
for (int i = 0; i < count-1; i++){
word = word + sep + word;
}
}
return word;
}
Example Output ::
Expected Run Result
repeatSeparator("Word", "X", 3) → "WordXWordXWord" "WordXWordXWordXWord" X

word = word + sep + word;
Think carefully about what this does the second time around. Hint: word has changed since the first time around.
Solution: Use a different variable to hold the results, so that you append the same word each time. (Free hint: use a StringBuffer or StringBuilder instead.)

The below function should do what you need:
public String repeatSeparator(String word, String sep, int count) {
StringBuffer buffer = new StringBuffer();
while (count > 0) {
buffer.append(word);
count--;
if (count > 0) {
buffer.append(sep);
}
}
return buffer.toString();
}

public string doStuff(
final String word,
final String seperator,
final int count)
{
StringBuffer buffer = new StringBuffer();
for (int index = 0; index < count; ++index)
{
if (buffer.length() > 0)
{
buffer.append(seperator);
}
buffer.append(word);
}
return buffer.toString();
}

public String repeatSeparator(String word, String sep, int count) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count; i++) {
sb.append(word);
if (i < count - 1)
sb.append(sep);
}
return sb.toString();
}
In real life, would use Apache Common Lang StringUtils.repeat

Don't for get to consider the edge cases too. If the count is zero then the program should return an empty String.

public String repeatSeparator(String word, String sep, int count) {
String ans ="";
for(int i=0;i<count;i++)
{
if(i<count-1)
{
ans+=word + sep;
} else {
ans+=word;
}
}
return ans;
}

public String repeatSeparator(String word, String sep, int count) {
String s = "";
if (count > 1)
{
while (count > 0)
{
if (count > 1)
{
s = s + word + sep;
count--;
}
if (count == 1)
{
s = s + word;
count--;
}
}
}
if (count == 1) s = word;
return s;
}

public static String repeatSeparator1(String word,String sep,int count){
StringBuilder sb = new StringBuilder();
for(int i=0;i<count;i++){
sb.append(word+sep);
}
return sb.substring(0, sb.lastIndexOf(sep));
}

used this:
public String repeatSeparator(String word, String sep, int count) {
String result = "";
if(count == 0)
return "";
for(int i = 0 ; i < count-1 ; i++){
result = result +(word+sep);
}
return result+word;
}

public String createSeparatorString(String word, String separator, int count) {
StringBuffer stringBuffer = new StringBuffer();
while (count > 0) {
stringBuffer.append(word);
count--;
if (count > 0) {
stringBuffer.append(separator);
}
}
return stringBuffer.toString();
}

Here's another similar approach(I append the word at the end of every string if the count is greater than 0):
public String repeatSeparator(String word, String sep, int count) {
String out="";
if(count>0){
for(int i=1; i<=count-1; i++){
out += word+sep;
}
return out+word;
}
else return out;
}

public String repeatSeparator(String word, String sep, int count) {
String g="";
for(int i=0;i<count;i++){
g=g+word;
if(i<count-1){
g=g+sep;
}
}
return g;
}

public static void main(String[] args) {
String str1="Word";
String str2="X";
int x=2;
System.out.println(repeatString(str1, str2, x));
}
public static String repeatString(String s1, String s2, int y) {
String dummy="";
for(int i=1; i<=y; i++) {
dummy+=s1;
if(i!=y) {
dummy+=s2;
}
}
return dummy;
}

Related

How I return specific string from recursive function in java?

Input for method :
word = AbcDef
input = 3
w = AbcDef
The Following code showing the ouput :
fAbcDe
efAbcD
DefAbc
I want to return only DefAbc.
How can I do the coding for return keyword.
public static String match2(String word,int input,String w)
{
StringBuilder st = new StringBuilder();
StringBuilder st1 = new StringBuilder();
String str = "";
int count = 0;
st.append(word.charAt(i));
for(int j = 0;j < i;j++)
{
st.append(word.charAt(j));
}
if(input!=0)
{
str = st.toString();
System.out.println(str);
int input2 = input-1;
match2(str,input2,w);
}
return null;
}
Please try this one. Hope it might solve your problem using recursion-> tillValue should be->3 if you want to rotate for 3 characters
static String recurse(String word, int count, int tillValue) {
if (count == tillValue) {
return word;
}
String recurse = recurse(word, count + 1,tillValue);
word = swap(recurse);
return word;
}
private static String swap(String word) {
if (word.length() > 0) {
String c = word.substring(word.length() - 1);
String dc = c + word.substring(0, word.length() - 1);
System.out.println(dc);
return dc;
}
return "";
}

Number of rotations required to make string

This is my code to count the number of rotations.
But IDK, What is the problem with it.
Can anyone explain and help me out.
Test Case: Input: david vidda
Output: 2
I tried to have brute force approach but, that wasn't working even.
Can anyone point out my mistake??
import java.util.*;
class solution{
public static int arrayLeftRotation(StringBuilder str1, StringBuilder str2)
{
int i;
int count =0;
for (i = 0; i < str1.length(); i++){
if(str1.equals(str2))
{
count++;
str1 = leftRotatebyOne(str1);
System.out.println(str1);
}
else return count;
}
return count;
}
static StringBuilder leftRotatebyOne(StringBuilder str)
{
int i;
char temp = str.charAt(0);
for (i = 0; i < str.length()-1; i++)
str.setCharAt(str.indexOf(str.charAt(i)+""),str.charAt(i+1));
str.setCharAt(i,temp);
return str;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String strr1= in.nextLine();
StringBuilder str1 = new StringBuilder(strr1);
String strr2 = in.nextLine();
StringBuilder str2 = new StringBuilder(strr2);
System.out.print(arrayLeftRotation(str1, str2));
}
}
Your method leftRotateByOne appears more complicated than necessary.
Try this:
public class Solution
{
public static int arrayLeftRotation(String str1,
String str2)
{
int nr_rotate;
int counter;
nr_rotate = 0;
for (counter = 0; counter < str1.length(); counter++)
{
if (str1.equals(str2))
return (nr_rotate);
else
{
str1 = leftRotateByOne(str1);
nr_rotate++;
System.out.println(str1);
}
}
// No possible solution
return (-1);
} // arrayLeftRotation
public static String leftRotateByOne(String str)
{
return (str.substring(1) + str.charAt(0));
}
public static void main(String[] args)
{
String str1 = "david";
String str2 = "vidda";
System.out.print(arrayLeftRotation(str1, str2));
}
} // class Solution
Another possible solution for arrayLeftRotation,
public static int arrayLeftRotation(String str1, String str2) {
StringBuilder builder = new StringBuilder(str1);
for (int i = 0; i < str1.length(); i++) {
builder.append(str1.charAt(i)).delete(0, 1);
if (str2.equals(builder.toString())) {
return i + 1;
}
}
return -1;
}
Note: this will return -1 if no matches found.
The trick is to append the input string to itself, then call String#indexOf. It will give you the index at which the doubled string contains the expected string, which is what you're looking for.
Example:
public static int numberOfRotations(String input, String expected) {
final String doubledInput = input + input;
return doubledInput.indexOf(expected);
}
If you really want to implement it yourself, you need to simplify your code to minimize the possibility of making mistakes.
public static String rotate(String input) {
return input.substring(1) + input.charAt(0);
}
public static int numberOfRotations(String input, String expected) {
// handle edge cases (null, empty, etc.) here
String rotatedInput = input;
int count = 0;
while (!rotatedInput.equals(expected) && count < input.length()) {
rotatedInput = rotate(rotatedInput);
count++;
}
return count == input.length() ? -1 : count;
}
I am just trying to point out where your error lies and fix it.
Your error lies here in your leftRotatebyOne:
for (i = 0; i < str.length()-1; i++)
str.setCharAt(str.indexOf(str.charAt(i)+""),str.charAt(i+1)); // your error while shifting to the left;
What you are trying to do is shifting one position to the left, and you should just do it as:
for (i = 0; i < str.length()-1; i++)
str.setCharAt(i,str.charAt(i+1));
And then your method will work.
But I have to say Alex M has provided a cleaner solution to your problem. Perhaps you should have a try.
Your solution then can be (after the fix):
public class RotationCount {
public static int arrayLeftRotation(StringBuilder str1, StringBuilder str2) {
int i;
int count = 0;
for (i = 0; i < str1.length(); i++) {
if (!str1.toString().equals(str2.toString())) {
count++;
str1 = leftRotatebyOne(str1);
} else return count;
}
return count;
}
static StringBuilder leftRotatebyOne(StringBuilder str) {
int i;
char temp = str.charAt(0);
for (i = 0; i < str.length() - 1; i++) {
str.setCharAt(i, str.charAt(i + 1));
}
str.setCharAt(i, temp);
return str;
}
public static void main(String[] args) {
StringBuilder str1 = new StringBuilder("david");
StringBuilder str2 = new StringBuilder("vidda");
System.out.print(arrayLeftRotation(str1, str2));
}
}

How to identify the number of common character between two strings?

Given 2 strings, str1 and str2, as input, return the count of the chars which are in the same position in str1 and str2.
Sample Input #1
count("New York","New Delhi")
Sample Output #1
4
Because the two strings share the same four leading characters: "New "
Sample Input #2
count("rhinoceroses","hippopotamus")
Sample Output #2
2
Because 'o' occupies the fourth position and 's' the eleventh position in both strings.
MyApproach
#Edit
public int count(String str1, String str2)
{
int p=0;
int k=0;
int count=0;
int l1=str1.length();
int l2=str2.length();
if(l1>=l2)
{
while(k<l2)
{
char ch1=str1.charAt(p);
char ch2=str2.charAt(k);
if(ch1==ch2)
{
p++;
k++;
count++;
}
else
{
p++;
k++;
}
}
}
else
{
char ch1=str1.charAt(p);
char ch2=str2.charAt(k);
while(k<l1)
{
if(ch1==ch2)
{
p++;
k++;
count++;
}
else
{
p++;
k++;
}
}
}
return count;
}
Parameters Actual Output Expected Output
'Trisect''Classes' 0 1
I am getting correct output now.
Thanku
This can be done more preciously using a single loop. Find the below code with the solution :-
class GetCount {
public static void main(String args[]) {
String myString = "rhinoceroses";
String myString1 = "hippopotamus";
count(myString, myString1);
}
/**
* #param myString
* #param myString1
*/
private static void count(String myString, String myString1) {
int i = 0;
int count = 0;
int length = myString.length() < myString1.length() ? myString.length() : myString1.length();
while(i < length) {
if(myString.charAt(i) == myString1.charAt(i)) {
count++;
}
i++;
}
System.out.println("Count is :: " + count);
}
}
Here is a compact solution, very easy to understand.
Solution
public static int count(String s1, String s2){
int count = 0;
for (int i = 0 ; i < (s1.length() > s2.length() ? s2 : s1).length() ; i++){
count += s1.charAt(i) == s2.charAt(i) ? 1 : 0;
}
return count;
}
Input
public static void main(String[] args) {
System.out.println(
"New York, New Delhi : "
+ count("New York", "New Delhi"));
System.out.println(
"Rhinoceroses, Hippopotamus : "
+ count ("Rhinoceroses", "Hippopotamus"));
}
Output
New York, New Delhi : 4
Rhinoceroses, Hippopotamus : 2
The solutions provided before are useless, as they work only if the characters are in the same sequence.
Here is my solution:
private int commonCharacterCount(String s1, String s2) {
int counter = 0;
List<Character> list = new LinkedList<>();
for (char aChar : s1.toCharArray()) {
list.add(aChar);
}
for (char c : s2.toCharArray()) {
if (list.contains(c)) {
list.remove(Character.valueOf(c));
counter++;
}
}
return counter;
}
You are welcome :)
You can also do something like this. (Try it) -
public int count(String s1, String s2) {
int result=0;
char[] ch1=s1.toCharArray();
char[] ch2=s2.toCharArray();
if(ch1.length>ch2.length){
for(int i=0;i<ch2.length;i++){
if(ch1[i]==ch2[i]){
result++;
}
}
}
else{
for(int i=0;i<ch1.length;i++){
if(ch2[i]==ch1[i]){
result++;
}
}
}
return result;
}
Typescript solution. Guaranteed constraints:
1 ≤ s1.length ≤ 15, 1 ≤ s2.length ≤ 15
function commonCharacterCount(s1: string, s2: string): number {
let count = 0;
let s_1 = s1.split("");
let s_2 = s2.split("");
for (let i = 0; i < s_1.length; i++) {
for (let j = 0; j < s_2.length; j++) {
if (s_1[i] == s_2[j]) {
count++;
s_2.splice(j, 1);
break;
}
}
}
return(count);
}
Since you need to count of the chars which are in the same position we can do it in a single loop checking at each iteration (string position) if the chars are equal or not. And the number of iteration should be the minimum length of str1 and str2 (maybe we could extract Math.min(str1.length(), str2.length()) in a variable). I compressed the if - else branches from your solution to a single loop using the minimum string length in loop condition.
public int countCommonChars(String str1, String str2) {
int commonCharsNumber = 0;
for(int i=0; i< Math.min(str1.length(), str2.length()); i++) {
if (str1.charAt(i) == str2.charAt(i)) {
commonCharsNumber++;
}
}
return commonCharsNumber;
}
int commonCharacterCount(String s1, String s2) {
Map<String, Integer> mapOfString1 = getOcuurances(s1);
Map<String, Integer> mapOfString2 = getOcuurances(s2);
int counter = 0;
for (Map.Entry<String, Integer> entry : mapOfString2.entrySet()) {
if (mapOfString1.get(entry.getKey()) != null) {
if (mapOfString1.get(entry.getKey()) > entry.getValue()) {
counter += entry.getValue();
} else {
counter += mapOfString1.get(entry.getKey());
}
}
}
return counter;
}
public Map<String, Integer> getOcuurances(String s) {
Map<String, Integer> hashMap = new HashMap<>();
String[] strings = s.split("");
for (int i = 0; i < strings.length; i++) {
if (hashMap.containsKey(strings[i])) {
hashMap.put(strings[i], hashMap.get(strings[i]) + 1);
} else {
hashMap.put(strings[i], 1);
}
}
return hashMap;
}
int count(String s1, String s2) {
Map<Character, Integer> charCountMap1 = getCharacterCount(s1);
Map<Character, Integer> charCountMap2 = getCharacterCount(s2);
return charCountMap1.entrySet().stream().map(charCountEntry ->
Math.min(charCountEntry.getValue(), charCountMap2.getOrDefault(charCountEntry.getKey(), 0))
).collect(Collectors.summingInt(value -> value));
}
private Map<Character, Integer> getCharacterCount(String str) {
Map<Character, Integer> charCountMap = new HashMap<>();
for (int i = 0; i < str.toCharArray().length; i++) {
Integer count = charCountMap.getOrDefault(str.charAt(i), 0);
charCountMap.put(str.charAt(i), ++count);
}
return charCountMap;
}
I would like to go with below:-
private static int solution(String s1, String s2) {
int count = 0;
List<Character> listChars = s1.chars().mapToObj(chr -> (char) chr)
.collect(Collectors.toCollection(LinkedList::new));
for (char c : s2.toCharArray()) {
if (listChars.contains(c)) {
listChars.remove(Character.valueOf(c));
count++;
}
}
return count;
}
Though there is already an accepted answer but I don't feel that answer is concise enough, hence I am giving mine (haven't compiled, treat it as psuedo-code please)
public static int count(String s1, String s2) {
if (s1 == null || s2==null ||s1.isEmpty() || s2.isEmpty()) {
return 0;
}
int minLength = Math.min(s1.length(), s2.length());
int count = 0;
for (int i < 0; i < minLength; ++i) {
if (s1.charAt(i) == s2.charAt(i)) {
++count;
}
}
return count;
}
public int count(String str1, String str2) {
int result = 0;
if (str1.length() == 0 || str2.length() == 0)
return result;
if (str1.length() > str2.length()) {
for (int i = 0; i < str2.length(); i++) {
if (str2.charAt(i) == str1.charAt(i))
result++;
}
}
else {
for (int i = 0; i < str1.length(); i++) {
if (str1.charAt(i) == str2.charAt(i))
result++;
}
}
return result;
}

Counting number of occurrences of word in java

I want to count the number of occurrences of particular word in a source string.
Let's say src="thisisamangoterrthisismangorightthis?"
word="this"
So what I am doing is, first search for index of word in src. It's at index 0. Now I am extracting the part from this index location to end of src.
i.e., now src="isamangoterrthisismangorightthis?" and search for word again.
But I am getting array out of bound exception.
public static int countOccur(String s1, String s2)
{
int ans=0;
int len1=s1.length();
int len2=s2.length();
System.out.println("Lengths:"+len1+" " +len2);
while(s1.contains(s2))
{
ans++;
int tmpInd=s1.indexOf(s2);
System.out.println("Now Index is:"+tmpInd);
if((tmpInd+len2)<len1){
s1=s1.substring(tmpInd+len2, len1);
System.out.println("Now s1 is:"+s1);
}
else
break;
}
return ans;
}
Try this to count the word in a string,
private static int countingWord(String value, String findWord)
{
int counter = 0;
while (value.contains(findWord))
{
int index = value.indexOf(findWord);
value = value.substring(index + findWord.length(), value.length());
counter++;
}
return counter;
}
When you use a method that throws ArrayIndexOutOfBoundsException, it's always a good idea to check the bounds. See String#substring:
IndexOutOfBoundsException - if the beginIndex is negative, or endIndex
is larger than the length of this String object, or beginIndex is
larger than endIndex.
You should cover all cases:
if(tmpInd + len2 >= s1.length() || len1 >= s1.length() || ... ) {
//Not good
}
Or, better, you should consider your logic to avoid this situation in the first place.
Try and use indexOf(), it will take care of bounds etc for you:
public static int countOccurrences(final String haystack, final String needle)
{
int index = 0;
int ret = 0;
while (true) {
index = haystack.indexOf(needle, index);
if (index == -1)
return ret;
ret++;
}
// Not reached
throw new IllegalStateException("How on earth did I get there??");
}
Rather than doing a substring on your String use this method
public int indexOf(int ch, int fromIndex)
then just check if the result is -1
Your might use replace to solve the problem
String s = "thisisamangoterrthisismangorightthis?";
String newS = s.replaceAll("this","");
int count = (s.length() - newS.length()) / 4;
import java.io.*;
import java.util.*;
public class WordCount
{
public static class Word implements Comparable<Word>
{
String word;
int count;
#Override
public int hashCode()
{
return word.hashCode();
}
#Override
public boolean equals(Object obj)
{
return word.equals(((Word)obj).word);
}
#Override
public int compareTo(Word b)
{
return b.count - count;
}
}
public static void findWordcounts(File input)throws Exception
{
long time = System.currentTimeMillis();
Map<String, Word> countMap = new HashMap<String, Word>();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(input)));
String line;
while ((line = reader.readLine()) != null) {
String[] words = line.split("[^A-ZÅÄÖa-zåäö]+");
for (String word : words) {
if ("".equals(word)) {
continue;
}
Word wordObj = countMap.get(word);
if (wordObj == null) {
wordObj = new Word();
wordObj.word = word;
wordObj.count = 0;
countMap.put(word, wordObj);
}
wordObj.count++;
}
}
reader.close();
SortedSet<Word> sortedWords = new TreeSet<Word>(countMap.values());
int i = 0;
for (Word word : sortedWords) {
if (i > 10) {
break;
}
System.out.println("Word \t "+ word.word+"\t Count \t"+word.count);
i++;
}
time = System.currentTimeMillis() - time;
System.out.println("Completed in " + time + " ms");
}
public static void main(String[] args)throws Exception
{
findWordcounts(new File("./don.txt"));
}
}

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