[Java]Find duplicate characters in a string without hashmap and set - java

I have written a Java program to find duplicate characters in a string without Hashmap and set.
Below is the program,
package practice;
public class Duplicate {
public static void main(String[] args) {
String src= "abcad";
char[] srcChar= src.toLowerCase().toCharArray();
int len=srcChar.length;
int j=0;
boolean flag=false;
char ch;
// System.out.println("Length of the String is "+len1);
// System.out.println("Length of the character array is "+len);
int k=0;
for(int i=0;i<len;i++)
{
// System.out.println("i-----> "+i + " and character is "+srcChar[i]);
for(j=0;j<len;j++)
{
// System.out.println("j-----> "+j + " and character is "+srcChar[j]);
if(srcChar[i]==srcChar[j])
{
k++;
}
}
if(k>1)
{
if(srcChar[i]>1)
{
System.out.println("This character "+srcChar[i]+" has repeated "+k+ " time");
}
else
{
System.out.println("There are no characters repeated in the given string");
}
}
k=0;
}
}
}
Output here is:
This character a has repeated 2 time
This character a has repeated 2 time
Here, I want the output like
This character a has repeated 2 time
i.e. not repeating the output twice. Since the character "a" is repeated twice, the output is also repeated twice.
kindly help me to get the output once instead of twice.
Thank you,

class PrintDuplicateCharacter
{
public static void main(String[] args)
{
String str = "HelloJava";
char[] ch = str.toCharArray();
int i=0,j=0;
for(i=0;i<ch.length;i++)
{
int count = 0 ;
for( j = i+1;j<ch.length;j++)
{// 4 6 , 8 , 10
if(ch[i] == ch[j] )
{
count++;
}
}
if(count != 0)
{
System.out.print(str.charAt(i) + " Occured " + count + " time");
}
}
}
}

private static void duplicateChar(String str){
char[] arr1 = str.toUpperCase().toCharArray();
int length = str.length();
int count = 1;
String s = "";
char c1 = '\u0000';
for(int i=0;i<length;i++){
count = 1;
for(int j=i+1;j<length;j++){
if(arr1[i] == arr1[j]){
count++;
c1 = arr1[i];
}
if(j == (length-1) && c1 != '\u0000' && !s.contains(String.valueOf(c1))){
s = s+" "+String.valueOf(c1)+" No of times: "+count+"\n";
}
}
}
System.out.println("\nDuplicate char are:\n"+s);
}

You can make a 2 dimensional array, 2 wide, the source strings height. In this array you store a character when it gets replaced and add one to the amount of times it has been replaced.
Something like(I don't know if these counters are correct):
replacements[j][0] = charAt(j);
replacements[j][1] += 1;
You would have to check if the character you are replacing already exists in this array and you can only print elements of the array if they aren't null.
You print this after the original loop.

All you need to fix is to start the second loop from i instead of 0.
for (int i = 0; i < len; i++) {
for (j = i; j < len; j++) {
...
}
...
}

Imports:
import java.util.ArrayList;
import java.util.List;
Code:
public static void main(String args[]) {
String input = "abcad"; // Input value
char[] chars = input.toLowerCase().toCharArray(); // Creates ArrayList
// of all characters
// in the String
List<Character> charR = new ArrayList<>(); // Creates a List used to
// saving the Characters it
// has saved
List<Integer> valR = new ArrayList<>(); // Creates a List that will
// store how many times a
// character is repeated
for (int i = 0; i < chars.length; i++) { // Loop through items in the
// ArrayList
char c = chars[i]; // Create Character value containing the value of
// the item at the "i" index of the ArrayList
if (charR.contains(c)) { // If the List contains item...
for (int i2 = 0; i2 < charR.size(); i2++) { // Loop through its
// items
if (charR.get(i2).equals(c)) { // If you find a match...
valR.set(i2, valR.get(i2) + 1); // Increase repeated
// value by 1
i2 = charR.size(); // Stop loop
} else { // Else...
i2++; // Increase index by 1
}
}
} else { // Else...
charR.add(c); // Add the Character to the List
valR.add(1); // Add the value 1 to the List (Meaning that the
// Character repeated once)
}
}
for (int i = 0; i < charR.size(); i++) { // Loop through all the items
// in the List
System.out.println("'" + charR.get(i) + "' : " + valR.get(i)); // Display
// what
// the
// character
// is
// and
// how
// many
// times
// it
// was
// repeated
}
}
Output:
'a' : 2
'b' : 1
'c' : 1
'd' : 1

char[] array=value.toCharArray();
int count=0;
char ch;
for(int i=0;i<array.length-1;i++)
{
ch=array[i];
count=1;
if(ch!='#'){
for(int j=i+1;j<array.length;j++)
{
if(ch==array[j]){
count++;
array[j]='#';
}
}
if(count>1)
{
System.out.println("char is " + ch + "count" + count);
}
}
}

You can also solve this problem with this code like :
public static void main(String[] args) {
String src = "abcad";
char[] srcChar = src.toLowerCase().toCharArray();
int len = srcChar.length;
int j = 0;
boolean flag = false;
char ch;
// System.out.println("Length of the String is "+len1);
// System.out.println("Length of the character array is "+len);
int k = 0;
for (int i = 0; i < len; i++) {
// System.out.println("i-----> "+i + " and character is "+srcChar[i]);
for (j = 0 + i; j < len; j++) {
// System.out.println("j-----> "+j + " and character is "+srcChar[j]);
if (srcChar[i] == srcChar[j]) {
k++;
}
}
if (k > 1) {
if (srcChar[i] > 1) {
System.out.println("This character " + srcChar[i] + " has repeated " + k + " time");
} else {
System.out.println("There are no characters repeated in the given string");
}
}
k = 0;
}
}
just we need to start the inner loop with j=0+i ;
for (j = 0 + i; j < len; j++)
This will you can observe above code;

Related

Palindrome in java

Here what I tried
sample input is "aabaa"
eg: in if condition val[0] = a[4]
if it is equal i stored it in counter variable if it is half of the length it original string it is palindrome
if it is not it is not a palindrome
I tried with my basic knowledge in java if there is any errors let me know
boolean solution(String inputString) {
int val = inputString.length();
int count = 0;
for (int i = 0; i<inputString.length(); i++) {
if(inputString.charAt(i) == inputString.charAt(val-i)) {
count = count++;
if (count>0) {
return true;
}
}
}
return true;
}
How about
public boolean isPalindrome(String text) {
String clean = text.replaceAll("\\s+", "").toLowerCase();
int length = clean.length();
int forward = 0;
int backward = length - 1;
while (backward > forward) {
char forwardChar = clean.charAt(forward++);
char backwardChar = clean.charAt(backward--);
if (forwardChar != backwardChar)
return false;
}
return true;
}
From here
In your version you compare first element with last, second with second last etc.
last element in this case is inputString.length()-1(so need to use 'inputString.charAt(val-i-1)' . If you iterate till end, then the count should be equal to length of the string.
for(int i = 0; i<inputString.length(); i++){
if(inputString.charAt(i) == inputString.charAt(val-i-1)){
count ++;
}
}
return (count==val); //true when count=val
Or alternatlively iterate till the mid point of the array, then count value is val/2.
for(int i = 0; i<inputString.length()/2; i++){
if(inputString.charAt(i) == inputString.charAt(val-i-1)){
count ++;
}
}
return (count==val/2); //true when count=val/2
There's no constraints in the question so let me throw in a more cheesy solution.
boolean isPalindrome(String in)
final String inl = in.toLowerCase();
return new StringBuilder(inl).reverse().toString().equals(inl);
}
A palindrome is a word, sentence, verse, or even a number that reads the same forward and backward. In this java solution, we’ll see how to figure out whether the number or the string is palindrome in nature or not.
Method - 1
class Main {
public static void main(String[] args) {
String str = "Nitin", revStr = "";
int strLen = str.length();
for (int i = (strLen - 1); i >=0; --i) {
revStr = revStr + str.charAt(i);
}
if (str.toLowerCase().equals(revStr.toLowerCase())) {
System.out.println(str + " is a Palindrome String.");
}
else {
System.out.println(str + " is not a Palindrome String.");
}
Method - 2
class Main {
public static void main(String[] args) {
int n = 3553, revNum = 0, rem;
// store the number to the original number
int orgNum = n;
/* get the reverse of original number
store it in variable */
while (n != 0) {
remainder = n % 10;
revNum = revNum * 10 + rem;
n /= 10;
}
// check if reversed number and original number are equal
if (orgNum == revNum) {
System.out.println(orgNum + " is Palindrome.");
}
else {
System.out.println(orgNum + " is not Palindrome.");
}

I want the string pattern aabbcc to be displayed as 2a2b2c

I have somehow got the output with the help of some browsing. But I couldn't understand the logic behind the code. Is there any simple way to achieve this?
public class LetterCount {
public static void main(String[] args)
{
String str = "aabbcccddd";
int[] counts = new int[(int) Character.MAX_VALUE];
// If you are certain you will only have ASCII characters, I would use `new int[256]` instead
for (int i = 0; i < str.length(); i++) {
char charAt = str.charAt(i);
counts[(int) charAt]++;
}
for (int i = 0; i < counts.length; i++) {
if (counts[i] > 0)
//System.out.println("Number of " + (char) i + ": " + counts[i]);
System.out.print(""+ counts[i] + (char) i + "");
}
}
}
There are 3 conditions which need to be taken care of:
if (s.charAt(x) != s.charAt(x + 1) && count == 1) ⇒ print the counter and character;
if (s.charAt(x) == s.charAt(x + 1)) ⇒ increase the counter;
if (s.charAt(x) != s.charAt(x + 1) && count >= 2) ⇒ reset to counter 1.
{
int count= 1;
int x;
for (x = 0; x < s.length() - 1; x++) {
if (s.charAt(x) != s.charAt(x + 1) && count == 1) {
System.out.print(s.charAt(x));
System.out.print(count);
}
else if (s.charAt(x)== s.charAt(x + 1)) {
count++;
}
else if (s.charAt(x) != s.charAt(x + 1) && count >= 2) {
System.out.print(s.charAt(x));
System.out.print(count);
count = 1;
}
}
System.out.print(s.charAt(x));
System.out.println(count);
}
The code is really simple.It uses the ASCII value of a character to index into the array that stores the frequency of each character.
The output is simply got by iterating over that array and which character has frequency greater than 1, print it accordingly as you want in the output that is frequency followed by character.
If the input string has same characters consecutive then the solution can be using space of O(1)
For example in your string aabbcc, the same characters are consecutive , so we can take advantage of this fact and count the character frequency and print it at the same time.
for (int i = 0; i < str.length(); i++)
{
int freq = 1;
while((i+1)<str.length()&&str.charAt(i) == str.charAt(i+1))
{++freq;++i}
System.out.print(freq+str.charAt(i));
}
You are trying to keep count of the number of times each character is found. An array is referenced by an index. For example, the ASCII code for the lowercase letter a is the integer 97. Thus the count of the number of times the letter a is seen is in counts[97]. After every element in the counts array has been set, you print out how many have been found.
This should help you understand the basic idea behind how to approach the string compression problem
import java.util.*;
public class LetterCount {
public static void main(String[] args) {
//your input string
String str = "aabbcccddd";
//split your input into characters
String chars[] = str.split("");
//maintain a map to store unique character and its frequency
Map<String, Integer> compressMap = new LinkedHashMap<String, Integer>();
//read every letter in input string
for(String s: chars) {
//java.lang.String.split(String) method includes empty string in your
//split array, so you need to ignore that
if("".equals(s))
continue;
//obtain the previous occurances of the character
Integer count = compressMap.get(s);
//if the character was previously encountered, increment its count
if(count != null)
compressMap.put(s, ++count);
else//otherwise store it as first occurance
compressMap.put(s, 1);
}
//Create a StringBuffer object, to append your input
//StringBuffer is thread safe, so I prefer using it
//you could use StringBuilder if you don't expect your code to run
//in a multithreaded environment
StringBuffer output = new StringBuffer("");
//iterate over every entry in map
for (Map.Entry<String, Integer> entry : compressMap.entrySet()) {
//append the results to output
output.append(entry.getValue()).append(entry.getKey());
}
//print the output on console
System.out.println(output);
}
}
class Solution {
public String toFormat(String input) {
char inChar[] = input.toCharArray();
String output = "";
int i;
for(i=0;i<input.length();i++) {
int count = 1;
while(i+1<input.length() && inChar[i] == inChar[i+1]) {
count+=1;
i+=1;
}
output+=inChar[i]+String.valueOf(count);
}
return output;
}
public static void main(String[] args) {
Solution sol = new Solution();
String input = "aaabbbbcc";
System.out.println("Formatted String is: " + sol.toFormat(input));
}
}
def encode(Test_string):
count = 0
Result = ""
for i in range(len(Test_string)):
if (i+1) < len(Test_string) and (Test_string[i] == Test_string[i+1]):
count += 1
else:
Result += str((count+1))+Test_string[i]
count = 0
return Result
print(encode("ABBBBCCCCCCCCAB"))
If you want to get the correct count considering the string is not in alphabetical order. Sort the string
public class SquareStrings {
public static void main(String[] args) {
SquareStrings squareStrings = new SquareStrings();
String str = "abbccddddbd";
System.out.println(squareStrings.manipulate(str));
}
private String manipulate(String str1) {
//convert to charArray
char[] charArray = str1.toCharArray();
Arrays.sort(charArray);
String str = new String(charArray);
StringBuilder stbuBuilder = new StringBuilder("");
int length = str.length();
String temp = "";
if (length > 1) {
for (int i = 0; i < length; i++) {
int freq = 1;
while (((i + 1) < length) && (str.charAt(i) == str.charAt(i + 1))) {
++freq;
temp = str.charAt(i) + "" + freq;
++i;
}
stbuBuilder.append(temp);
}
} else {
return str + "" + 1;
}
return stbuBuilder.toString();
}
}
Kotlin:
fun compressString(input: String): String {
if (input.isEmpty()){
return ""
}
var result = ""
var count = 1
var char1 = input[0]
for (i in 1 until input.length) {
val char2 = input[i]
if (char1 == char2) {
count++
} else {
if (count != 1) {
result += "$count$char1"
count = 1
} else {
result += "$char1"
}
char1 = char2
}
}
result += if (count != 1) {
"$count$char1"
} else {
"$char1"
}
return result
}

Finding anagram using array list

I'm trying to find if two string are anagrams of each other:
void anagram(String a, String b) {
List<Character> bcopy = new ArrayList<Character>();
for (int i = 0; i < b.length(); i++)
bcopy.add(b.charAt(i));
if (b.length() == 0 || a.length() == 0) {
System.out.println("Exit");
} else {
for (int i = 0; i < a.length(); i++) {
char temp = a.charAt(i);
if (bcopy.contains(temp)) {
System.out.println("match found" + temp);
bcopy.remove(temp);
}
for (char j : bcopy) {
System.out.println("Values" + j);
}
}
}
}
I keep getting an out of bounds error at the remove() line. Can someone please tell me how I reach the array bounds when I'm searching by the object availability? What am I missing here?
The problem is you're using the int-argument version of remove() since the char temp is being treated as an int. Here's a workaround:
bcopy.remove(Character.valueOf(temp));
By the way a better way to test for anagrams would be something like:
char[] c1 = a.toCharArray();
char[] c2 = b.toCharArray();
Arrays.sort(c1);
Arrays.sort(c2);
return Arrays.equals(c1, c2); // true -> anagram, false -> not anagram
there is another algorithm which might be more suitable to the task. it computes the letter frequencies for strings of equal lengths.
for simplicity i assume that the set of all characters involved can be represented in one of the common 8 bit codepages.
void anagram(String a, String b) {
int freqa[256], freqb[256];
if (b.length() == 0 || a.length() == 0) {
System.out.println("Exit");
return;
}
for (int i = 0; i < b.length(); i++) {
freqa[(int) a.charAt(i)]++;
freqb[(int) b.charAt(i)]++;
}
for (i = 0; i < 256; i++) {
if (freqa[i] <> freqb[i]) {
System.out.println("Exit");
return;
}
}
System.out.println("match found: '" + a + "', '" + b + "'");
}
There is a problem with your code. You are removing the items from a list however the loop is running 'n' times is the string length is 'n'.
So if item is removed from the list and the loop count reaches a number which Index is removed from list it will give the exception. You can keep a count instead of removing the items. I modified your code little bit which is working fine now.
Please check
import java.util.ArrayList;
import java.util.List;
class Anagram{
void anagram(String a, String b) {
List<Character> bcopy = new ArrayList<Character>();
int count=0;
for (int i = 0; i < b.length(); i++)
bcopy.add(b.charAt(i));
if (b.length() == 0 || a.length() != b.length()) {
System.out.println("Two strings are not anagram");
} else {
for (int i = 0; i < a.length(); i++) {
char temp = a.charAt(i);
if (bcopy.contains(temp)) {
//System.out.println("match found" + temp);
//bcopy.remove(temp);-- Here list size was reduced but the loop was constant, because list size is less than a.length() now it was giving error
//System.out.println(c);
count++;
}
}
if(count==a.length()) {
System.out.println("Two strings are anagram");
}
else {
System.out.println("Two strings are not anagram");
}
}
}
}
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Anagram a=new Anagram();
a.anagram("abs", "ass");
}
}

count specific characters in a string (Java)

I have a homework assignment to count specific chars in string.
For example: string = "America"
The output should be = a appear 2 times, m appear 1 time, e appear 1 time, r appear 1 time, i appear 1 time and c appear 1 time
public class switchbobo {
/**
* #param args
*/ // TODO Auto-generated method stub
public static void main(String[] args){
String s = "BUNANA";
String lower = s.toLowerCase();
char[] c = lower.toCharArray(); // converting to a char array
int freq =0, freq2 = 0,freq3 = 0,freq4=0,freq5 = 0;
for(int i = 0; i< c.length;i++) {
if(c[i]=='a') // looking for 'a' only
freq++;
if(c[i]=='b')
freq2++;
if (c[i]=='c') {
freq3++;
}
if (c[i]=='d') {
freq4++;
}
}
System.out.println("Total chars "+c.length);
if (freq > 0) {
System.out.println("Number of 'a' are "+freq);
}
}
}
code above is what I have done, but I think it is not make sense to have 26 variables (one for each letter). Do you guys have alternative result?
Obviously your intuition of having a variable for each letter is correct.
The problem is that you don't have any automated way to do the same work on different variables, you don't have any trivial syntax which helps you doing the same work (counting a single char frequency) for 26 different variables.
So what could you do? I'll hint you toward two solutions:
you can use an array (but you will have to find a way to map character a-z to indices 0-25, which is somehow trivial is you reason about ASCII encoding)
you can use a HashMap<Character, Integer> which is an associative container that, in this situation, allows you to have numbers mapped to specific characters so it perfectly fits your needs
You can use HashMap of Character key and Integer value.
HashMap<Character,Integer>
iterate through the string
-if the character exists in the map get the Integer value and increment it.
-if not then insert it to map and set the integer value for 0
This is a pseudo code and you have to try coding it
I am using a HashMap for the solution.
import java.util.*;
public class Sample2 {
/**
* #param args
*/
public static void main(String[] args)
{
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
String test = "BUNANA";
char[] chars = test.toCharArray();
for(int i=0; i<chars.length;i++)
{
if(!map.containsKey(chars[i]))
{
map.put(chars[i], 1);
}
map.put(chars[i], map.get(chars[i])+1);
}
System.out.println(map.toString());
}
}
Produced Output -
{U=2, A=3, B=2, N=3}
In continuation to Jack's answer the following code could be your solution. It uses the an array to store the frequency of characters.
public class SwitchBobo
{
public static void main(String[] args)
{
String s = "BUNANA";
String lower = s.toLowerCase();
char[] c = lower.toCharArray();
int[] freq = new int[26];
for(int i = 0; i< c.length;i++)
{
if(c[i] <= 122)
{
if(c[i] >= 97)
{
freq[(c[i]-97)]++;
}
}
}
System.out.println("Total chars " + c.length);
for(int i = 0; i < 26; i++)
{
if(freq[i] != 0)
System.out.println(((char)(i+97)) + "\t" + freq[i]);
}
}
}
It will give the following output:
Total chars 6
a 2
b 1
n 2
u 1
int a[]=new int[26];//default with count as 0
for each chars at string
if (String having uppercase)
a[chars-'A' ]++
if lowercase
then a[chars-'a']++
public class TestCharCount {
public static void main(String args[]) {
String s = "america";
int len = s.length();
char[] c = s.toCharArray();
int ct = 0;
for (int i = 0; i < len; i++) {
ct = 1;
for (int j = i + 1; j < len; j++) {
if (c[i] == ' ')
break;
if (c[i] == c[j]) {
ct++;
c[j] = ' ';
}
}
if (c[i] != ' ')
System.out.println("number of occurance(s) of " + c[i] + ":"
+ ct);
}
}
}
maybe you can use this
public static int CountInstanceOfChar(String text, char character ) {
char[] listOfChars = text.toCharArray();
int total = 0 ;
for(int charIndex = 0 ; charIndex < listOfChars.length ; charIndex++)
if(listOfChars[charIndex] == character)
total++;
return total;
}
for example:
String text = "america";
char charToFind = 'a';
System.out.println(charToFind +" appear " + CountInstanceOfChar(text,charToFind) +" times");
Count char 'l' in the string.
String test = "Hello";
int count=0;
for(int i=0;i<test.length();i++){
if(test.charAt(i)== 'l'){
count++;
}
}
or
int count= StringUtils.countMatches("Hello", "l");

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