Related
What is an elegant way to find all the permutations of a string. E.g. permutation for ba, would be ba and ab, but what about longer string such as abcdefgh? Is there any Java implementation example?
public static void permutation(String str) {
permutation("", str);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0) System.out.println(prefix);
else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
(via Introduction to Programming in Java)
Use recursion.
Try each of the letters in turn as the first letter and then find all the permutations of the remaining letters using a recursive call.
The base case is when the input is an empty string the only permutation is the empty string.
Here is my solution that is based on the idea of the book "Cracking the Coding Interview" (P54):
/**
* List permutations of a string.
*
* #param s the input string
* #return the list of permutations
*/
public static ArrayList<String> permutation(String s) {
// The result
ArrayList<String> res = new ArrayList<String>();
// If input string's length is 1, return {s}
if (s.length() == 1) {
res.add(s);
} else if (s.length() > 1) {
int lastIndex = s.length() - 1;
// Find out the last character
String last = s.substring(lastIndex);
// Rest of the string
String rest = s.substring(0, lastIndex);
// Perform permutation on the rest string and
// merge with the last character
res = merge(permutation(rest), last);
}
return res;
}
/**
* #param list a result of permutation, e.g. {"ab", "ba"}
* #param c the last character
* #return a merged new list, e.g. {"cab", "acb" ... }
*/
public static ArrayList<String> merge(ArrayList<String> list, String c) {
ArrayList<String> res = new ArrayList<>();
// Loop through all the string in the list
for (String s : list) {
// For each string, insert the last character to all possible positions
// and add them to the new list
for (int i = 0; i <= s.length(); ++i) {
String ps = new StringBuffer(s).insert(i, c).toString();
res.add(ps);
}
}
return res;
}
Running output of string "abcd":
Step 1: Merge [a] and b:
[ba, ab]
Step 2: Merge [ba, ab] and c:
[cba, bca, bac, cab, acb, abc]
Step 3: Merge [cba, bca, bac, cab, acb, abc] and d:
[dcba, cdba, cbda, cbad, dbca, bdca, bcda, bcad, dbac, bdac, badc, bacd, dcab, cdab, cadb, cabd, dacb, adcb, acdb, acbd, dabc, adbc, abdc, abcd]
Of all the solutions given here and in other forums, I liked Mark Byers the most. That description actually made me think and code it myself.
Too bad I cannot voteup his solution as I am newbie.
Anyways here is my implementation of his description
public class PermTest {
public static void main(String[] args) throws Exception {
String str = "abcdef";
StringBuffer strBuf = new StringBuffer(str);
doPerm(strBuf,0);
}
private static void doPerm(StringBuffer str, int index){
if(index == str.length())
System.out.println(str);
else { //recursively solve this by placing all other chars at current first pos
doPerm(str, index+1);
for (int i = index+1; i < str.length(); i++) {//start swapping all other chars with current first char
swap(str,index, i);
doPerm(str, index+1);
swap(str,i, index);//restore back my string buffer
}
}
}
private static void swap(StringBuffer str, int pos1, int pos2){
char t1 = str.charAt(pos1);
str.setCharAt(pos1, str.charAt(pos2));
str.setCharAt(pos2, t1);
}
}
I prefer this solution ahead of the first one in this thread because this solution uses StringBuffer. I wouldn't say my solution doesn't create any temporary string (it actually does in system.out.println where the toString() of StringBuffer is called). But I just feel this is better than the first solution where too many string literals are created. May be some performance guy out there can evalute this in terms of 'memory' (for 'time' it already lags due to that extra 'swap')
A very basic solution in Java is to use recursion + Set ( to avoid repetitions ) if you want to store and return the solution strings :
public static Set<String> generatePerm(String input)
{
Set<String> set = new HashSet<String>();
if (input == "")
return set;
Character a = input.charAt(0);
if (input.length() > 1)
{
input = input.substring(1);
Set<String> permSet = generatePerm(input);
for (String x : permSet)
{
for (int i = 0; i <= x.length(); i++)
{
set.add(x.substring(0, i) + a + x.substring(i));
}
}
}
else
{
set.add(a + "");
}
return set;
}
All the previous contributors have done a great job explaining and providing the code. I thought I should share this approach too because it might help someone too. The solution is based on (heaps' algorithm )
Couple of things:
Notice the last item which is depicted in the excel is just for helping you better visualize the logic. So, the actual values in the last column would be 2,1,0 (if we were to run the code because we are dealing with arrays and arrays start with 0).
The swapping algorithm happens based on even or odd values of current position. It's very self explanatory if you look at where the swap method is getting called.You can see what's going on.
Here is what happens:
public static void main(String[] args) {
String ourword = "abc";
String[] ourArray = ourword.split("");
permute(ourArray, ourArray.length);
}
private static void swap(String[] ourarray, int right, int left) {
String temp = ourarray[right];
ourarray[right] = ourarray[left];
ourarray[left] = temp;
}
public static void permute(String[] ourArray, int currentPosition) {
if (currentPosition == 1) {
System.out.println(Arrays.toString(ourArray));
} else {
for (int i = 0; i < currentPosition; i++) {
// subtract one from the last position (here is where you are
// selecting the the next last item
permute(ourArray, currentPosition - 1);
// if it's odd position
if (currentPosition % 2 == 1) {
swap(ourArray, 0, currentPosition - 1);
} else {
swap(ourArray, i, currentPosition - 1);
}
}
}
}
Let's use input abc as an example.
Start off with just the last element (c) in a set (["c"]), then add the second last element (b) to its front, end and every possible positions in the middle, making it ["bc", "cb"] and then in the same manner it will add the next element from the back (a) to each string in the set making it:
"a" + "bc" = ["abc", "bac", "bca"] and "a" + "cb" = ["acb" ,"cab", "cba"]
Thus entire permutation:
["abc", "bac", "bca","acb" ,"cab", "cba"]
Code:
public class Test
{
static Set<String> permutations;
static Set<String> result = new HashSet<String>();
public static Set<String> permutation(String string) {
permutations = new HashSet<String>();
int n = string.length();
for (int i = n - 1; i >= 0; i--)
{
shuffle(string.charAt(i));
}
return permutations;
}
private static void shuffle(char c) {
if (permutations.size() == 0) {
permutations.add(String.valueOf(c));
} else {
Iterator<String> it = permutations.iterator();
for (int i = 0; i < permutations.size(); i++) {
String temp1;
for (; it.hasNext();) {
temp1 = it.next();
for (int k = 0; k < temp1.length() + 1; k += 1) {
StringBuilder sb = new StringBuilder(temp1);
sb.insert(k, c);
result.add(sb.toString());
}
}
}
permutations = result;
//'result' has to be refreshed so that in next run it doesn't contain stale values.
result = new HashSet<String>();
}
}
public static void main(String[] args) {
Set<String> result = permutation("abc");
System.out.println("\nThere are total of " + result.size() + " permutations:");
Iterator<String> it = result.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
This one is without recursion
public static void permute(String s) {
if(null==s || s.isEmpty()) {
return;
}
// List containing words formed in each iteration
List<String> strings = new LinkedList<String>();
strings.add(String.valueOf(s.charAt(0))); // add the first element to the list
// Temp list that holds the set of strings for
// appending the current character to all position in each word in the original list
List<String> tempList = new LinkedList<String>();
for(int i=1; i< s.length(); i++) {
for(int j=0; j<strings.size(); j++) {
tempList.addAll(merge(s.charAt(i), strings.get(j)));
}
strings.removeAll(strings);
strings.addAll(tempList);
tempList.removeAll(tempList);
}
for(int i=0; i<strings.size(); i++) {
System.out.println(strings.get(i));
}
}
/**
* helper method that appends the given character at each position in the given string
* and returns a set of such modified strings
* - set removes duplicates if any(in case a character is repeated)
*/
private static Set<String> merge(Character c, String s) {
if(s==null || s.isEmpty()) {
return null;
}
int len = s.length();
StringBuilder sb = new StringBuilder();
Set<String> list = new HashSet<String>();
for(int i=0; i<= len; i++) {
sb = new StringBuilder();
sb.append(s.substring(0, i) + c + s.substring(i, len));
list.add(sb.toString());
}
return list;
}
Well here is an elegant, non-recursive, O(n!) solution:
public static StringBuilder[] permutations(String s) {
if (s.length() == 0)
return null;
int length = fact(s.length());
StringBuilder[] sb = new StringBuilder[length];
for (int i = 0; i < length; i++) {
sb[i] = new StringBuilder();
}
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
int times = length / (i + 1);
for (int j = 0; j < times; j++) {
for (int k = 0; k < length / times; k++) {
sb[j * length / times + k].insert(k, ch);
}
}
}
return sb;
}
One of the simple solution could be just keep swapping the characters recursively using two pointers.
public static void main(String[] args)
{
String str="abcdefgh";
perm(str);
}
public static void perm(String str)
{ char[] char_arr=str.toCharArray();
helper(char_arr,0);
}
public static void helper(char[] char_arr, int i)
{
if(i==char_arr.length-1)
{
// print the shuffled string
String str="";
for(int j=0; j<char_arr.length; j++)
{
str=str+char_arr[j];
}
System.out.println(str);
}
else
{
for(int j=i; j<char_arr.length; j++)
{
char tmp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = tmp;
helper(char_arr,i+1);
char tmp1 = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = tmp1;
}
}
}
python implementation
def getPermutation(s, prefix=''):
if len(s) == 0:
print prefix
for i in range(len(s)):
getPermutation(s[0:i]+s[i+1:len(s)],prefix+s[i] )
getPermutation('abcd','')
This is what I did through basic understanding of Permutations and Recursive function calling. Takes a bit of time but it's done independently.
public class LexicographicPermutations {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="abc";
List<String>combinations=new ArrayList<String>();
combinations=permutations(s);
Collections.sort(combinations);
System.out.println(combinations);
}
private static List<String> permutations(String s) {
// TODO Auto-generated method stub
List<String>combinations=new ArrayList<String>();
if(s.length()==1){
combinations.add(s);
}
else{
for(int i=0;i<s.length();i++){
List<String>temp=permutations(s.substring(0, i)+s.substring(i+1));
for (String string : temp) {
combinations.add(s.charAt(i)+string);
}
}
}
return combinations;
}}
which generates Output as [abc, acb, bac, bca, cab, cba].
Basic logic behind it is
For each character, consider it as 1st character & find the combinations of remaining characters. e.g. [abc](Combination of abc)->.
a->[bc](a x Combination of (bc))->{abc,acb}
b->[ac](b x Combination of (ac))->{bac,bca}
c->[ab](c x Combination of (ab))->{cab,cba}
And then recursively calling each [bc],[ac] & [ab] independently.
Use recursion.
when the input is an empty string the only permutation is an empty string.Try for each of the letters in the string by making it as the first letter and then find all the permutations of the remaining letters using a recursive call.
import java.util.ArrayList;
import java.util.List;
class Permutation {
private static List<String> permutation(String prefix, String str) {
List<String> permutations = new ArrayList<>();
int n = str.length();
if (n == 0) {
permutations.add(prefix);
} else {
for (int i = 0; i < n; i++) {
permutations.addAll(permutation(prefix + str.charAt(i), str.substring(i + 1, n) + str.substring(0, i)));
}
}
return permutations;
}
public static void main(String[] args) {
List<String> perms = permutation("", "abcd");
String[] array = new String[perms.size()];
for (int i = 0; i < perms.size(); i++) {
array[i] = perms.get(i);
}
int x = array.length;
for (final String anArray : array) {
System.out.println(anArray);
}
}
}
this worked for me..
import java.util.Arrays;
public class StringPermutations{
public static void main(String args[]) {
String inputString = "ABC";
permute(inputString.toCharArray(), 0, inputString.length()-1);
}
public static void permute(char[] ary, int startIndex, int endIndex) {
if(startIndex == endIndex){
System.out.println(String.valueOf(ary));
}else{
for(int i=startIndex;i<=endIndex;i++) {
swap(ary, startIndex, i );
permute(ary, startIndex+1, endIndex);
swap(ary, startIndex, i );
}
}
}
public static void swap(char[] ary, int x, int y) {
char temp = ary[x];
ary[x] = ary[y];
ary[y] = temp;
}
}
Java implementation without recursion
public Set<String> permutate(String s){
Queue<String> permutations = new LinkedList<String>();
Set<String> v = new HashSet<String>();
permutations.add(s);
while(permutations.size()!=0){
String str = permutations.poll();
if(!v.contains(str)){
v.add(str);
for(int i = 0;i<str.length();i++){
String c = String.valueOf(str.charAt(i));
permutations.add(str.substring(i+1) + c + str.substring(0,i));
}
}
}
return v;
}
Let me try to tackle this problem with Kotlin:
fun <T> List<T>.permutations(): List<List<T>> {
//escape case
if (this.isEmpty()) return emptyList()
if (this.size == 1) return listOf(this)
if (this.size == 2) return listOf(listOf(this.first(), this.last()), listOf(this.last(), this.first()))
//recursive case
return this.flatMap { lastItem ->
this.minus(lastItem).permutations().map { it.plus(lastItem) }
}
}
Core concept: Break down long list into smaller list + recursion
Long answer with example list [1, 2, 3, 4]:
Even for a list of 4 it already kinda get's confusing trying to list all the possible permutations in your head, and what we need to do is exactly to avoid that. It is easy for us to understand how to make all permutations of list of size 0, 1, and 2, so all we need to do is break them down to any of those sizes and combine them back up correctly. Imagine a jackpot machine: this algorithm will start spinning from the right to the left, and write down
return empty/list of 1 when list size is 0 or 1
handle when list size is 2 (e.g. [3, 4]), and generate the 2 permutations ([3, 4] & [4, 3])
For each item, mark that as the last in the last, and find all the permutations for the rest of the item in the list. (e.g. put [4] on the table, and throw [1, 2, 3] into permutation again)
Now with all permutation it's children, put itself back to the end of the list (e.g.: [1, 2, 3][,4], [1, 3, 2][,4], [2, 3, 1][, 4], ...)
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class hello {
public static void main(String[] args) throws IOException {
hello h = new hello();
h.printcomp();
}
int fact=1;
public void factrec(int a,int k){
if(a>=k)
{fact=fact*k;
k++;
factrec(a,k);
}
else
{System.out.println("The string will have "+fact+" permutations");
}
}
public void printcomp(){
String str;
int k;
Scanner in = new Scanner(System.in);
System.out.println("enter the string whose permutations has to b found");
str=in.next();
k=str.length();
factrec(k,1);
String[] arr =new String[fact];
char[] array = str.toCharArray();
while(p<fact)
printcomprec(k,array,arr);
// if incase u need array containing all the permutation use this
//for(int d=0;d<fact;d++)
//System.out.println(arr[d]);
}
int y=1;
int p = 0;
int g=1;
int z = 0;
public void printcomprec(int k,char array[],String arr[]){
for (int l = 0; l < k; l++) {
for (int b=0;b<k-1;b++){
for (int i=1; i<k-g; i++) {
char temp;
String stri = "";
temp = array[i];
array[i] = array[i + g];
array[i + g] = temp;
for (int j = 0; j < k; j++)
stri += array[j];
arr[z] = stri;
System.out.println(arr[z] + " " + p++);
z++;
}
}
char temp;
temp=array[0];
array[0]=array[y];
array[y]=temp;
if (y >= k-1)
y=y-(k-1);
else
y++;
}
if (g >= k-1)
g=1;
else
g++;
}
}
/** Returns an array list containing all
* permutations of the characters in s. */
public static ArrayList<String> permute(String s) {
ArrayList<String> perms = new ArrayList<>();
int slen = s.length();
if (slen > 0) {
// Add the first character from s to the perms array list.
perms.add(Character.toString(s.charAt(0)));
// Repeat for all additional characters in s.
for (int i = 1; i < slen; ++i) {
// Get the next character from s.
char c = s.charAt(i);
// For each of the strings currently in perms do the following:
int size = perms.size();
for (int j = 0; j < size; ++j) {
// 1. remove the string
String p = perms.remove(0);
int plen = p.length();
// 2. Add plen + 1 new strings to perms. Each new string
// consists of the removed string with the character c
// inserted into it at a unique location.
for (int k = 0; k <= plen; ++k) {
perms.add(p.substring(0, k) + c + p.substring(k));
}
}
}
}
return perms;
}
Here is a straightforward minimalist recursive solution in Java:
public static ArrayList<String> permutations(String s) {
ArrayList<String> out = new ArrayList<String>();
if (s.length() == 1) {
out.add(s);
return out;
}
char first = s.charAt(0);
String rest = s.substring(1);
for (String permutation : permutations(rest)) {
out.addAll(insertAtAllPositions(first, permutation));
}
return out;
}
public static ArrayList<String> insertAtAllPositions(char ch, String s) {
ArrayList<String> out = new ArrayList<String>();
for (int i = 0; i <= s.length(); ++i) {
String inserted = s.substring(0, i) + ch + s.substring(i);
out.add(inserted);
}
return out;
}
We can use factorial to find how many strings started with particular letter.
Example: take the input abcd. (3!) == 6 strings will start with every letter of abcd.
static public int facts(int x){
int sum = 1;
for (int i = 1; i < x; i++) {
sum *= (i+1);
}
return sum;
}
public static void permutation(String str) {
char[] str2 = str.toCharArray();
int n = str2.length;
int permutation = 0;
if (n == 1) {
System.out.println(str2[0]);
} else if (n == 2) {
System.out.println(str2[0] + "" + str2[1]);
System.out.println(str2[1] + "" + str2[0]);
} else {
for (int i = 0; i < n; i++) {
if (true) {
char[] str3 = str.toCharArray();
char temp = str3[i];
str3[i] = str3[0];
str3[0] = temp;
str2 = str3;
}
for (int j = 1, count = 0; count < facts(n-1); j++, count++) {
if (j != n-1) {
char temp1 = str2[j+1];
str2[j+1] = str2[j];
str2[j] = temp1;
} else {
char temp1 = str2[n-1];
str2[n-1] = str2[1];
str2[1] = temp1;
j = 1;
} // end of else block
permutation++;
System.out.print("permutation " + permutation + " is -> ");
for (int k = 0; k < n; k++) {
System.out.print(str2[k]);
} // end of loop k
System.out.println();
} // end of loop j
} // end of loop i
}
}
//insert each character into an arraylist
static ArrayList al = new ArrayList();
private static void findPermutation (String str){
for (int k = 0; k < str.length(); k++) {
addOneChar(str.charAt(k));
}
}
//insert one char into ArrayList
private static void addOneChar(char ch){
String lastPerStr;
String tempStr;
ArrayList locAl = new ArrayList();
for (int i = 0; i < al.size(); i ++ ){
lastPerStr = al.get(i).toString();
//System.out.println("lastPerStr: " + lastPerStr);
for (int j = 0; j <= lastPerStr.length(); j++) {
tempStr = lastPerStr.substring(0,j) + ch +
lastPerStr.substring(j, lastPerStr.length());
locAl.add(tempStr);
//System.out.println("tempStr: " + tempStr);
}
}
if(al.isEmpty()){
al.add(ch);
} else {
al.clear();
al = locAl;
}
}
private static void printArrayList(ArrayList al){
for (int i = 0; i < al.size(); i++) {
System.out.print(al.get(i) + " ");
}
}
//Rotate and create words beginning with all letter possible and push to stack 1
//Read from stack1 and for each word create words with other letters at the next location by rotation and so on
/* eg : man
1. push1 - man, anm, nma
2. pop1 - nma , push2 - nam,nma
pop1 - anm , push2 - amn,anm
pop1 - man , push2 - mna,man
*/
public class StringPermute {
static String str;
static String word;
static int top1 = -1;
static int top2 = -1;
static String[] stringArray1;
static String[] stringArray2;
static int strlength = 0;
public static void main(String[] args) throws IOException {
System.out.println("Enter String : ");
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bfr = new BufferedReader(isr);
str = bfr.readLine();
word = str;
strlength = str.length();
int n = 1;
for (int i = 1; i <= strlength; i++) {
n = n * i;
}
stringArray1 = new String[n];
stringArray2 = new String[n];
push(word, 1);
doPermute();
display();
}
public static void push(String word, int x) {
if (x == 1)
stringArray1[++top1] = word;
else
stringArray2[++top2] = word;
}
public static String pop(int x) {
if (x == 1)
return stringArray1[top1--];
else
return stringArray2[top2--];
}
public static void doPermute() {
for (int j = strlength; j >= 2; j--)
popper(j);
}
public static void popper(int length) {
// pop from stack1 , rotate each word n times and push to stack 2
if (top1 > -1) {
while (top1 > -1) {
word = pop(1);
for (int j = 0; j < length; j++) {
rotate(length);
push(word, 2);
}
}
}
// pop from stack2 , rotate each word n times w.r.t position and push to
// stack 1
else {
while (top2 > -1) {
word = pop(2);
for (int j = 0; j < length; j++) {
rotate(length);
push(word, 1);
}
}
}
}
public static void rotate(int position) {
char[] charstring = new char[100];
for (int j = 0; j < word.length(); j++)
charstring[j] = word.charAt(j);
int startpos = strlength - position;
char temp = charstring[startpos];
for (int i = startpos; i < strlength - 1; i++) {
charstring[i] = charstring[i + 1];
}
charstring[strlength - 1] = temp;
word = new String(charstring).trim();
}
public static void display() {
int top;
if (top1 > -1) {
while (top1 > -1)
System.out.println(stringArray1[top1--]);
} else {
while (top2 > -1)
System.out.println(stringArray2[top2--]);
}
}
}
Another simple way is to loop through the string, pick the character that is not used yet and put it to a buffer, continue the loop till the buffer size equals to the string length. I like this back tracking solution better because:
Easy to understand
Easy to avoid duplication
The output is sorted
Here is the java code:
List<String> permute(String str) {
if (str == null) {
return null;
}
char[] chars = str.toCharArray();
boolean[] used = new boolean[chars.length];
List<String> res = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
Arrays.sort(chars);
helper(chars, used, sb, res);
return res;
}
void helper(char[] chars, boolean[] used, StringBuilder sb, List<String> res) {
if (sb.length() == chars.length) {
res.add(sb.toString());
return;
}
for (int i = 0; i < chars.length; i++) {
// avoid duplicates
if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
continue;
}
// pick the character that has not used yet
if (!used[i]) {
used[i] = true;
sb.append(chars[i]);
helper(chars, used, sb, res);
// back tracking
sb.deleteCharAt(sb.length() - 1);
used[i] = false;
}
}
}
Input str: 1231
Output list: {1123, 1132, 1213, 1231, 1312, 1321, 2113, 2131, 2311, 3112, 3121, 3211}
Noticed that the output is sorted, and there is no duplicate result.
Recursion is not necessary, even you can calculate any permutation directly, this solution uses generics to permute any array.
Here is a good information about this algorihtm.
For C# developers here is more useful implementation.
public static void main(String[] args) {
String word = "12345";
Character[] array = ArrayUtils.toObject(word.toCharArray());
long[] factorials = Permutation.getFactorials(array.length + 1);
for (long i = 0; i < factorials[array.length]; i++) {
Character[] permutation = Permutation.<Character>getPermutation(i, array, factorials);
printPermutation(permutation);
}
}
private static void printPermutation(Character[] permutation) {
for (int i = 0; i < permutation.length; i++) {
System.out.print(permutation[i]);
}
System.out.println();
}
This algorithm has O(N) time and space complexity to calculate each permutation.
public class Permutation {
public static <T> T[] getPermutation(long permutationNumber, T[] array, long[] factorials) {
int[] sequence = generateSequence(permutationNumber, array.length - 1, factorials);
T[] permutation = generatePermutation(array, sequence);
return permutation;
}
public static <T> T[] generatePermutation(T[] array, int[] sequence) {
T[] clone = array.clone();
for (int i = 0; i < clone.length - 1; i++) {
swap(clone, i, i + sequence[i]);
}
return clone;
}
private static int[] generateSequence(long permutationNumber, int size, long[] factorials) {
int[] sequence = new int[size];
for (int j = 0; j < sequence.length; j++) {
long factorial = factorials[sequence.length - j];
sequence[j] = (int) (permutationNumber / factorial);
permutationNumber = (int) (permutationNumber % factorial);
}
return sequence;
}
private static <T> void swap(T[] array, int i, int j) {
T t = array[i];
array[i] = array[j];
array[j] = t;
}
public static long[] getFactorials(int length) {
long[] factorials = new long[length];
long factor = 1;
for (int i = 0; i < length; i++) {
factor *= i <= 1 ? 1 : i;
factorials[i] = factor;
}
return factorials;
}
}
My implementation based on Mark Byers's description above:
static Set<String> permutations(String str){
if (str.isEmpty()){
return Collections.singleton(str);
}else{
Set <String> set = new HashSet<>();
for (int i=0; i<str.length(); i++)
for (String s : permutations(str.substring(0, i) + str.substring(i+1)))
set.add(str.charAt(i) + s);
return set;
}
}
Permutation of String:
public static void main(String args[]) {
permu(0,"ABCD");
}
static void permu(int fixed,String s) {
char[] chr=s.toCharArray();
if(fixed==s.length())
System.out.println(s);
for(int i=fixed;i<s.length();i++) {
char c=chr[i];
chr[i]=chr[fixed];
chr[fixed]=c;
permu(fixed+1,new String(chr));
}
}
Here is another simpler method of doing Permutation of a string.
public class Solution4 {
public static void main(String[] args) {
String a = "Protijayi";
per(a, 0);
}
static void per(String a , int start ) {
//bse case;
if(a.length() == start) {System.out.println(a);}
char[] ca = a.toCharArray();
//swap
for (int i = start; i < ca.length; i++) {
char t = ca[i];
ca[i] = ca[start];
ca[start] = t;
per(new String(ca),start+1);
}
}//per
}
A java implementation to print all the permutations of a given string considering duplicate characters and prints only unique characters is as follow:
import java.util.Set;
import java.util.HashSet;
public class PrintAllPermutations2
{
public static void main(String[] args)
{
String str = "AAC";
PrintAllPermutations2 permutation = new PrintAllPermutations2();
Set<String> uniqueStrings = new HashSet<>();
permutation.permute("", str, uniqueStrings);
}
void permute(String prefixString, String s, Set<String> set)
{
int n = s.length();
if(n == 0)
{
if(!set.contains(prefixString))
{
System.out.println(prefixString);
set.add(prefixString);
}
}
else
{
for(int i=0; i<n; i++)
{
permute(prefixString + s.charAt(i), s.substring(0,i) + s.substring(i+1,n), set);
}
}
}
}
String permutaions using Es6
Using reduce() method
const permutations = str => {
if (str.length <= 2)
return str.length === 2 ? [str, str[1] + str[0]] : [str];
return str
.split('')
.reduce(
(acc, letter, index) =>
acc.concat(permutations(str.slice(0, index) + str.slice(index + 1)).map(val => letter + val)),
[]
);
};
console.log(permutations('STR'));
In case anyone wants to generate the permutations to do something with them, instead of just printing them via a void method:
static List<int[]> permutations(int n) {
class Perm {
private final List<int[]> permutations = new ArrayList<>();
private void perm(int[] array, int step) {
if (step == 1) permutations.add(array.clone());
else for (int i = 0; i < step; i++) {
perm(array, step - 1);
int j = (step % 2 == 0) ? i : 0;
swap(array, step - 1, j);
}
}
private void swap(int[] array, int i, int j) {
int buffer = array[i];
array[i] = array[j];
array[j] = buffer;
}
}
int[] nVector = new int[n];
for (int i = 0; i < n; i++) nVector [i] = i;
Perm perm = new Perm();
perm.perm(nVector, n);
return perm.permutations;
}
I'm writing a program that will print the unique character in a string (entered through a scanner). I've created a method that tries to accomplish this but I keep getting characters that are not repeats, instead of a character (or characters) that is unique to the string. I want the unique letters only.
Here's my code:
import java.util.Scanner;
public class Sameness{
public static void main (String[]args){
Scanner kb = new Scanner (System.in);
String word = "";
System.out.println("Enter a word: ");
word = kb.nextLine();
uniqueCharacters(word);
}
public static void uniqueCharacters(String test){
String temp = "";
for (int i = 0; i < test.length(); i++){
if (temp.indexOf(test.charAt(i)) == - 1){
temp = temp + test.charAt(i);
}
}
System.out.println(temp + " ");
}
}
And here's sample output with the above code:
Enter a word:
nreena
nrea
The expected output would be: ra
Based on your desired output, you have to replace a character that initially has been already added when it has a duplicated later, so:
public static void uniqueCharacters(String test){
String temp = "";
for (int i = 0; i < test.length(); i++){
char current = test.charAt(i);
if (temp.indexOf(current) < 0){
temp = temp + current;
} else {
temp = temp.replace(String.valueOf(current), "");
}
}
System.out.println(temp + " ");
}
How about applying the KISS principle:
public static void uniqueCharacters(String test) {
System.out.println(test.chars().distinct().mapToObj(c -> String.valueOf((char)c)).collect(Collectors.joining()));
}
The accepted answer will not pass all the test case for example
input -"aaabcdd"
desired output-"bc"
but the accepted answer will give -abc
because the character a present odd number of times.
Here I have used ConcurrentHasMap to store character and the number of occurrences of character then removed the character if the occurrences is more than one time.
import java.util.concurrent.ConcurrentHashMap;
public class RemoveConductive {
public static void main(String[] args) {
String s="aabcddkkbghff";
String[] cvrtar=s.trim().split("");
ConcurrentHashMap<String,Integer> hm=new ConcurrentHashMap<>();
for(int i=0;i<cvrtar.length;i++){
if(!hm.containsKey(cvrtar[i])){
hm.put(cvrtar[i],1);
}
else{
hm.put(cvrtar[i],hm.get(cvrtar[i])+1);
}
}
for(String ele:hm.keySet()){
if(hm.get(ele)>1){
hm.remove(ele);
}
}
for(String key:hm.keySet()){
System.out.print(key);
}
}
}
Though to approach a solution I would suggest you to try and use a better data structure and not just string. Yet, you can simply modify your logic to delete already existing duplicates using an else as follows :
public static void uniqueCharacters(String test) {
String temp = "";
for (int i = 0; i < test.length(); i++) {
char ch = test.charAt(i);
if (temp.indexOf(ch) == -1) {
temp = temp + ch;
} else {
temp.replace(String.valueOf(ch),""); // added this to your existing code
}
}
System.out.println(temp + " ");
}
This is an interview question. Find Out all the unique characters of a string.
Here is the complete solution. The code itself is self explanatory.
public class Test12 {
public static void main(String[] args) {
String a = "ProtijayiGiniGina";
allunique(a);
}
private static void allunique(String a) {
int[] count = new int[256];// taking count of characters
for (int i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
count[ch]++;
}
for (int i = 0; i < a.length(); i++) {
char chh = a.charAt(i);
// character which has arrived only one time in the string will be printed out
if (count[chh] == 1) {
System.out.println("index => " + i + " and unique character => " + a.charAt(i));
}
}
}// unique
}
In Python :
def firstUniqChar(a):
count = [0] *256
for i in a: count[ord(i)] += 1
element = ""
for item in a:
if (count[ord(item)] == 1):
element = item;
break;
return element
a = "GiniGinaProtijayi";
print(firstUniqChar(a)) # output is P
public static String input = "10 5 5 10 6 6 2 3 1 3 4 5 3";
public static void uniqueValue (String numbers) {
String [] str = input.split(" ");
Set <String> unique = new HashSet <String> (Arrays.asList(str));
System.out.println(unique);
for (String value:unique) {
int count = 0;
for ( int i= 0; i<str.length; i++) {
if (value.equals(str[i])) {
count++;
}
}
System.out.println(value+"\t"+count);
}
}
public static void main(String [] args) {
uniqueValue(input);
}
Step1: To find the unique characters in a string, I have first taken the string from user.
Step2: Converted the input string to charArray using built in function in java.
Step3: Considered two HashSet (set1 for storing all characters even if it is getting repeated, set2 for storing only unique characters.
Step4 : Run for loop over the array and check that if particular character is not there in set1 then add it to both set1 and set2. if that particular character is already there in set1 then add it to set1 again but remove it from set2.( This else part is useful when particular character is getting repeated odd number of times).
Step5 : Now set2 will have only unique characters. Hence, just print that set2.
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String str = input.next();
char arr[] = str.toCharArray();
HashSet<Character> set1=new HashSet<Character>();
HashSet<Character> set2=new HashSet<Character>();
for(char i:arr)
{
if(set1.contains(i))
{
set1.add(i);
set2.remove(i);
}
else
{
set1.add(i);
set2.add(i);
}
}
System.out.println(set2);
}
I would store all the characters of the string in an array that you will loop through to check if the current characters appears there more than once. If it doesn't, then add it to temp.
public static void uniqueCharacters(String test) {
String temp = "";
char[] array = test.toCharArray();
int count; //keep track of how many times the character exists in the string
outerloop: for (int i = 0; i < test.length(); i++) {
count = 0; //reset the count for every new letter
for(int j = 0; j < array.length; j++) {
if(test.charAt(i) == array[j])
count++;
if(count == 2){
count = 0;
continue outerloop; //move on to the next letter in the string; this will skip the next two lines below
}
}
temp += test.charAt(i);
System.out.println("Adding.");
}
System.out.println(temp);
}
I have added comments for some more detail.
import java.util.*;
import java.lang.*;
class Demo
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter String");
String s1=sc.nextLine();
try{
HashSet<Object> h=new HashSet<Object>();
for(int i=0;i<s1.length();i++)
{
h.add(s1.charAt(i));
}
Iterator<Object> itr=h.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
catch(Exception e)
{
System.out.println("error");
}
}
}
If you don't want to use additional space:
String abc="developer";
System.out.println("The unique characters are-");
for(int i=0;i<abc.length();i++)
{
for(int j=i+1;j<abc.length();j++)
{
if(abc.charAt(i)==abc.charAt(j))
abc=abc.replace(String.valueOf(abc.charAt(j))," ");
}
}
System.out.println(abc);
Time complexity O(n^2) and no space.
This String algorithm is used to print unique characters in a string.It runs in O(n) runtime where n is the length of the string.It supports ASCII characters only.
static String printUniqChar(String s) {
StringBuilder buildUniq = new StringBuilder();
boolean[] uniqCheck = new boolean[128];
for (int i = 0; i < s.length(); i++) {
if (!uniqCheck[s.charAt(i)]) {
uniqCheck[s.charAt(i)] = true;
if (uniqCheck[s.charAt(i)])
buildUniq.append(s.charAt(i));
}
}
public class UniqueCharactersInString {
public static void main(String []args){
String input = "aabbcc";
String output = uniqueString(input);
System.out.println(output);
}
public static String uniqueString(String s){
HashSet<Character> uniques = new HashSet<>();
uniques.add(s.charAt(0));
String out = "";
out += s.charAt(0);
for(int i =1; i < s.length(); i++){
if(!uniques.contains(s.charAt(i))){
uniques.add(s.charAt(i));
out += s.charAt(i);
}
}
return out;
}
}
What would be the inneficiencies of this answer? How does it compare to other answers?
Based on your desired output you can replace each character already present with a blank character.
public static void uniqueCharacters(String test){
String temp = "";
for(int i = 0; i < test.length(); i++){
if (temp.indexOf(test.charAt(i)) == - 1){
temp = temp + test.charAt(i);
} else {
temp.replace(String.valueOf(temp.charAt(i)), "");
}
}
System.out.println(temp + " ");
}
public void uniq(String inputString) {
String result = "";
int inputStringLen = inputStr.length();
int[] repeatedCharacters = new int[inputStringLen];
char inputTmpChar;
char tmpChar;
for (int i = 0; i < inputStringLen; i++) {
inputTmpChar = inputStr.charAt(i);
for (int j = 0; j < inputStringLen; j++) {
tmpChar = inputStr.charAt(j);
if (inputTmpChar == tmpChar)
repeatedCharacters[i]++;
}
}
for (int k = 0; k < inputStringLen; k++) {
inputTmpChar = inputStr.charAt(k);
if (repeatedCharacters[k] == 1)
result = result + inputTmpChar + " ";
}
System.out.println ("Unique characters: " + result);
}
In first for loop I count the number of times the character repeats in the string. In the second line I am looking for characters repetitive once.
how about this :)
for (int i=0; i< input.length();i++)
if(input.indexOf(input.charAt(i)) == input.lastIndexOf(input.charAt(i)))
System.out.println(input.charAt(i) + " is unique");
package extra;
public class TempClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
String abcString="hsfj'pwue2hsu38bf74sa';fwe'rwe34hrfafnosdfoasq7433qweid";
char[] myCharArray=abcString.toCharArray();
TempClass mClass=new TempClass();
mClass.countUnique(myCharArray);
mClass.countEach(myCharArray);
}
/**
* This is the program to find unique characters in array.
* #add This is nice.
* */
public void countUnique(char[] myCharArray) {
int arrayLength=myCharArray.length;
System.out.println("Array Length is: "+arrayLength);
char[] uniqueValues=new char[myCharArray.length];
int uniqueValueIndex=0;
int count=0;
for(int i=0;i<arrayLength;i++) {
for(int j=0;j<arrayLength;j++) {
if (myCharArray[i]==myCharArray[j] && i!=j) {
count=count+1;
}
}
if (count==0) {
uniqueValues[uniqueValueIndex]=myCharArray[i];
uniqueValueIndex=uniqueValueIndex+1;
count=0;
}
count=0;
}
for(char a:uniqueValues) {
System.out.println(a);
}
}
/**
* This is the program to find count each characters in array.
* #add This is nice.
* */
public void countEach(char[] myCharArray) {
}
}
Here str will be your string to find the unique characters.
function getUniqueChars(str){
let uniqueChars = '';
for(let i = 0; i< str.length; i++){
for(let j= 0; j< str.length; j++) {
if(str.indexOf(str[i]) === str.lastIndexOf(str[j])) {
uniqueChars += str[i];
}
}
}
return uniqueChars;
}
public static void main(String[] args) {
String s = "aaabcdd";
char a[] = s.toCharArray();
List duplicates = new ArrayList();
List uniqueElements = new ArrayList();
for (int i = 0; i < a.length; i++) {
uniqueElements.add(a[i]);
for (int j = i + 1; j < a.length; j++) {
if (a[i] == a[j]) {
duplicates.add(a[i]);
break;
}
}
}
uniqueElements.removeAll(duplicates);
System.out.println(uniqueElements);
System.out.println("First Unique : "+uniqueElements.get(0));
}
Output :
[b, c]
First Unique : b
import java.util.*;
public class Sameness{
public static void main (String[]args){
Scanner kb = new Scanner (System.in);
String word = "";
System.out.println("Enter a word: ");
word = kb.nextLine();
uniqueCharacters(word);
}
public static void uniqueCharacters(String test){
for(int i=0;i<test.length();i++){
if(test.lastIndexOf(test.charAt(i))!=i)
test=test.replaceAll(String.valueOf(test.charAt(i)),"");
}
System.out.println(test);
}
}
public class Program02
{
public static void main(String[] args)
{
String inputString = "abhilasha";
for (int i = 0; i < inputString.length(); i++)
{
for (int j = i + 1; j < inputString.length(); j++)
{
if(inputString.toCharArray()[i] == inputString.toCharArray()[j])
{
inputString = inputString.replace(String.valueOf(inputString.charAt(j)), "");
}
}
}
System.out.println(inputString);
}
}
I need to find all the palindromes in a string. It takes user input
example: "abbaalla"
it loops through creating a substring that changes as the loop progresses.
example: checks palindrome "a" (true) "ab"(false) "abb" (false) "abba" (true) and so on..
once it reaches the max length of the word it iterates the start of the substring and repeats
example: check palindrome "b" "bb" "bba" and so on..
I need to change the code so that once it finds the first largest palindrome ("abba") the start of the loop will take place after that substring. so the next palindrome should read "alla"
the final output should be a string that includes all palindromes. in this case;
output: "abba alla"
Also this program currently results in: String index out of range: -1
public static String findAllPalindromes(String input){
int indexStart = 0;
int wordMax = input.length();
int wordLength;
String checkPalindrome;
String allPalindromes = "";
for (wordLength = 2; wordLength <= wordMax; wordLength++) {
//creates a substring to check against isAllPalindrome method
checkPalindrome = input.substring(indexStart, wordLength);
//checks checkPalindrome string to see if it is a palindrome
if (isAllPalindrome(checkPalindrome) == true){
allPalindromes += " " + checkPalindrome;
if (checkPalindrome.length() >= allPalindromes.length()){
allPalindromes = checkPalindrome;
}
}
//once program reads string through once, increment index and scan text again
if (wordLength == wordMax && indexStart < wordMax){
indexStart++;
wordLength = 0;
}
}
System.out.println("The palindromes in the text are: ");
System.out.println(allPalindromes);
return allPalindromes;
}
public static Set<CharSequence> printAllPalindromes(String input) {
if (input.length() <= 2) {
return Collections.emptySet();
}
Set<CharSequence> out = new HashSet<CharSequence>();
int length = input.length();
for (int i = 1; i <= length; i++) {
for (int j = i - 1, k = i; j >= 0 && k < length; j--, k++) {
if (input.charAt(j) == input.charAt(k)) {
out.add(input.subSequence(j, k + 1));
} else {
break;
}
}
}
return out;
}
Simple Brute force way-->
public class AllPalindromes {
public static boolean checkPalindrome(String str) {
for(int i=0;i<=str.length()/2;i++)
if(str.charAt(i)!=str.charAt(str.length()-1-i))
return false;
return true;
}
public static void printAllPalindrome(String str) {
for(int i=0;i<=str.length();i++)
for(int j=i;j<str.length();j++)
if(checkPalindrome(str.substring(i,j+1)))
System.out.println(str.substring(i,j+1));
}
public static void main(String[] args) {
printAllPalindrome("abbaalla");
}
}
Here is the solution which displays all palindromes. (Only those palindromes which are of length greater than 3. You can change the if condition inside the loop if you want to print them all.)
Note that #jw23's solution does not display the palindromes which are of even length — only the odd length ones.
public class HelloWorld{
public static void printPalindromes(String s) {
if (s == null || s.length() < 3)
return;
System.out.println("Odd Length Palindromes:");
// Odd Length Palindromes
for (int i=1; i<s.length()-1; i++) {
for (int j=i-1,k=i+1; j>=0 && k<s.length(); j--,k++) {
if (s.charAt(j) == s.charAt(k)) {
if (k-j+1 >= 3)
System.out.println(s.substring(j, k+1) + " with index " +j+ " and "+k);
}
else
break;
}
}
System.out.println("\nEven Length Palindromes:");
// Even Length Palindromes
for (int i=1; i<s.length()-1; i++) {
for (int j=i,k=i+1; j>=0 && k<s.length(); j--,k++) {
if (s.charAt(j) == s.charAt(k)) {
if (k-j+1 >= 3)
System.out.println(s.substring(j, k+1) + " with index " +j+ " and "+k);
}
else
break;
}
}
}
public static void main(String[] args){
String s = "abcbaaabbaa";
printPalindromes(s);
}
}
public class Palindrome
{
static int count=0;
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
String s1=sc.next();
String array[]=s1.split("");
System.out.println("Palindromes are :");
for(int i=0;i<=array.length;i++)
{
for(int j=0;j<i;j++)
{
String B=s1.substring(j,i);
verify(B);
}
}
System.out.println("\n"+count);
sc.close();
}
public static void verify(String s1)
{
StringBuilder sb=new StringBuilder(s1);
String s2=sb.reverse().toString();
if(s1.equals(s2))
{
System.out.print(s1+" ");
count++;
}
}
}
My own logic for palindrome program for all substrings
public class Test1 {
public static void main(String[] args) {
String s = "bob";
ArrayList<Character> chr = new ArrayList<Character>();
ArrayList<String> subs= new ArrayList<String>();
for (int i=0;i<s.length();i++)
{
chr.add(s.charAt(i));
}
System.out.println(chr.toString());
StringBuilder subString = new StringBuilder();
for(int i=0; i < s.length();i++)
{
for(int j=i+1;j<s.length();j++)
{
for(int k=i;k<=j;k++)
{
subString.append(chr.get(k));
}
System.out.println(subString.toString());
subs.add(subString.toString());
subString.setLength(0);
}
}
System.out.println(subs);
for(String st : subs)
{
String st2 = new StringBuffer(st).reverse().toString();
if(st.equals(st2))
{
System.out.println(st+" is a palindrome");
}
else
{
System.out.println(st+" not a palindrome");
}
}
}
}
Print All Palindromes in the string
import java.util.*;
class AllPalindroms
{
public static void main(String args[])
{
String input = "abbaalla";
if (input.length() <= 1)
{
System.out.println("Not Palindrome Found.");
}
else
{
int length = input.length();
Set<String> set = new HashSet<String>();
for (int i = 0; i <length; i++)
{
//if(i==0)
for (int j=i+1;j<length+1;j++)
{
String s = input.substring(i, j);
StringBuffer sb = new StringBuffer(s);
sb.reverse();
if(s.equals(sb.toString()) && s.length()>1)
{
set.add(s);
}
}
}
System.out.println(set);
}
}
}
My code to count all palindromes in a string:
import java.util.Scanner;
public class CountPalindromeSapient {
static int count = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the given string: ");
String inputStr = sc.nextLine();
countPalindrome(inputStr);
System.out.println("\nTotal count of Palindromes are: "+count);
sc.close();
}
private static int countPalindrome(String inputStr) {
int count = 0;
int len = inputStr.length();
int startIndex =0;
String subString = "";
System.out.println( "Possible substrings are: ");
for (int i = 0; i < len; i++) {
for (int j = startIndex; j <= len; j++) {
subString = inputStr.substring(startIndex, j);
System.out.println(subString);
count = checkPalindrome(subString);
}
startIndex++;
}
return count;
}
private static int checkPalindrome(String subString) {
// TODO Auto-generated method stub
int subLen = subString.length();
boolean isPalindrome = false;
for(int k=0; k<subLen; k++,subLen-- ) { // Important
if (subString.charAt(k) != subString.charAt(subLen -1)) {
isPalindrome = false;
break;
}else {
isPalindrome = true;
}
}
if(isPalindrome == true) {
count ++;
}
return count;
}
}
class StringTest {
public static void main(String[] args) {
StringTest test = new StringTest();
boolean bool = test.checkPalindrom("abbaalla");
if(!bool)
System.out.println("String is not palindrom");
}
private boolean checkPalindrom(String k){
int[] count= new int[k.length()];
boolean[] arr = new boolean[k.length()];
for(int t=0;t<k.length();t++){
int j=0;
char ch = k.charAt(t);
for(int x=t+1;x<k.length();x++){
if(j<count.length){
if(ch == k.charAt(x))
count[j] = x + 1;
else
count[j] = 0;
j++;
}
}
arr[t] = workOnArr(count,t,k);
}
for(int z=0;z<arr.length;z++){
if(arr[z])
return true;
}
return false;
}
private boolean workOnArr(int[] s,int z,String w){
int j = s.length - 1;
while(j -- > 0){
if(s[j] != 0){
if(isPalindrom(w.substring(z, s[j]))){
if(w.substring(z, s[j]).length() > 1){
System.out.println(w.substring(z, s[j]).length());
System.out.println(w.substring(z, s[j]));
}
return true;
}
}
}
return false;
}
private boolean isPalindrom(String s){
int j= s.length() -1;
for(int i=0;i<s.length()/2;i++){
if(s.charAt(i) != s.charAt(j))
return false;
j--;
}
return true;
}
}
output:-
given palindrom are:-
abba, bb, aa, alla, ll
Question: All the palindromes from a word.
public class Test4 {
public static void main(String[] args) {
String a = "ProtijayiMeyeMADAMGiniiniGSoudiptaGina";
allpalindromicsubstrings(a);
}// main
private static void allpalindromicsubstrings(String a) {
Set<String> set = new HashSet<String>();
for (int i = 0; i < a.length(); i++) {
// odd length palindrome
expand(a, i, i, set);
// even length palindrome
expand(a, i, i + 1, set);
} // for
set.parallelStream().filter(words -> words.length() > 1).distinct().forEach(System.out::println);
}// ee
private static void expand(String a, int start, int last, Set<String> set) {
// run till a[start...last] is a palindrome
while (start >= 0 && last <= a.length() - 1 && a.charAt(start) == a.charAt(last)) {
set.add(a.substring(start, last + 1));
// expand in both directions
start--;
last++;
}
}// ee
}
The output palindromes in the word =>
niin
ADA
eye
MADAM
iniini
GiniiniG
ii
MeyeM
ini
Print all the palindromes in a string:
public class test1 {
public static void main(String[] args) {
String a = "Protijayi Meye MADAM GiniiniG Soudipta Gina";
List<String> list = Arrays.stream(a.split(" ")).collect(Collectors.toList());
System.out.println(list);
List<String> plist = new ArrayList<>();
for(int i = 0 ; i <list.size();i++) {
String curr =list.get(i);
if(ispalin(curr)) {plist.add(curr);}
}//for
System.out.println("palindrome list => " +plist);
}//main
private static boolean ispalin(String curr) {
if(curr == null || curr.length() == 0) {return false;}
return new StringBuffer(curr).reverse().toString().equals(curr);
}
}
The output is: palindrome list => [MADAM, GiniiniG]
Another Method in Java 8:
public class B {
public static void main(String[] args) {
String a = "Protijayi Meye MADAM GiniiniG Soudipta Gina";
List<String> list = Arrays.stream(a.split(" ")).collect(Collectors.toList());
// list to stream
// for Multi Threaded environment
Stream<String> stream = list.parallelStream();
// also,Stream<String> stream = list.stream(); for single Threaded environment
long palindrome = stream.filter(B::isPalindrome)// find all palindromes
.peek(System.out::println) // write each match
.count();// terminal - return a count
System.out.println("Count of palindromes: " + palindrome);
// System.out.println("List => " + list);
}
private static boolean isPalindrome(String aa) {
return new StringBuffer(aa).reverse().toString().equals(aa);
}
}
Output:
GiniiniG
MADAM
Count of palindromes: 2
Java program to enter a string and frame a word by joining all the first character of each word.
Display a new word.
import java.util.*;
public class Anshu {
public static void main(String args[]) {
Scanner in = new Scanner(System.in)
System.out.println("Enter a string");
String s = in .nextLine();
char ch = s.charAt(0);
System.out.print(ch);
s = s.toUpperCase;
int l = s.length();
for (int i = 0; i < l; i++)
char a = s.charAt(i);
if (Character.isWhiteSpace())
System.out.print(s.charAt(i + 1) + "");
}
}
How can I find the number of occurrences of a character in a string?
For example: The quick brown fox jumped over the lazy dog.
Some example outputs are below,
'a' = 1
'o' = 4
'space' = 8
'.' = 1
You could use the following, provided String s is the string you want to process.
Map<Character,Integer> map = new HashMap<Character,Integer>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (map.containsKey(c)) {
int cnt = map.get(c);
map.put(c, ++cnt);
} else {
map.put(c, 1);
}
}
Note, it will count all of the chars, not only letters.
Java 8 way:
"The quick brown fox jumped over the lazy dog."
.chars()
.mapToObj(i -> (char) i)
.collect(Collectors.groupingBy(Object::toString, Collectors.counting()));
void Findrepeter(){
String s="mmababctamantlslmag";
int distinct = 0 ;
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j < s.length(); j++) {
if(s.charAt(i)==s.charAt(j))
{
distinct++;
}
}
System.out.println(s.charAt(i)+"--"+distinct);
String d=String.valueOf(s.charAt(i)).trim();
s=s.replaceAll(d,"");
distinct = 0;
}
}
import java.io.*;
public class CountChar
{
public static void main(String[] args) throws IOException
{
String ch;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the Statement:");
ch=br.readLine();
int count=0,len=0;
do
{
try
{
char name[]=ch.toCharArray();
len=name.length;
count=0;
for(int j=0;j<len;j++)
{
if((name[0]==name[j])&&((name[0]>=65&&name[0]<=91)||(name[0]>=97&&name[0]<=123)))
count++;
}
if(count!=0)
System.out.println(name[0]+" "+count+" Times");
ch=ch.replace(""+name[0],"");
}
catch(Exception ex){}
}
while(len!=1);
}
}
Output
Enter the Statement:asdf23123sfsdf
a 1 Times
s 3 Times
d 2 Times
f 3 Times
A better way would be to create a Map to store your count. That would be a Map<Character, Integer>
You need iterate over each character of your string, and check whether its an alphabet. You can use Character#isAlphabetic method for that. If it is an alphabet, increase its count in the Map. If the character is not already in the Map then add it with a count of 1.
NOTE: - Character.isAlphabetic method is new in Java 7. If you are using an older version, you should use Character#isLetter
String str = "asdfasdfafk asd234asda";
Map<Character, Integer> charMap = new HashMap<Character, Integer>();
char[] arr = str.toCharArray();
for (char value: arr) {
if (Character.isAlphabetic(value)) {
if (charMap.containsKey(value)) {
charMap.put(value, charMap.get(value) + 1);
} else {
charMap.put(value, 1);
}
}
}
System.out.println(charMap);
OUTPUT: -
{f=3, d=4, s=4, a=6, k=1}
If your string only contains alphabets then you can use some thing like this.
public class StringExample {
public static void main(String[] args) {
String str = "abcdabghplhhnfl".toLowerCase();
// create a integer array for 26 alphabets.
// where index 0,1,2.. will be the container for frequency of a,b,c...
Integer[] ar = new Integer[26];
// fill the integer array with character frequency.
for(int i=0;i<str.length();i++) {
int j = str.charAt(i) -'a';
if(ar[j]==null) {
ar[j]= 1;
}else {
ar[j]+= 1;
}
}
// print only those alphabets having frequency greater then 1.
for(int i=0;i<ar.length;i++) {
if(ar[i]!=null && ar[i]>1) {
char c = (char) (97+i);
System.out.println("'"+c+"' comes "+ar[i]+" times.");
}
}
}
}
Output:
'a' comes 2 times.
'b' comes 2 times.
'h' comes 3 times.
'l' comes 2 times.
Finding the duplicates in a String:
Example 1 : Using HashMap
public class a36 {
public static void main(String[] args) {
String a = "Gini Rani";
fix(a);
}//main
public static void fix(String a ){
Map<Character ,Integer> map = new HashMap<>();
for (int i = 0; i <a.length() ; i++ ) {
char ch = a.charAt(i);
map.put(ch , map.getOrDefault(ch,0) +1 );
}//for
List<Character> list = new ArrayList<>();
Set<Map.Entry<Character ,Integer> > entrySet = map.entrySet();
for ( Map.Entry<Character ,Integer> entry : entrySet) {
list.add( entry.getKey() );
System.out.printf( " %s : %d %n" , entry.getKey(), entry.getValue() );
}//for
System.out.println("Duplicate elements => " + list);
}//fix
}
Example 2 : using Arrays.stream() in Java 8
public class a37 {
public static void main(String[] args) {
String aa = "Protijayi Gini";
String[] stringarray = aa.split("");
Map<String , Long> map = Arrays.stream(stringarray)
.collect(Collectors.groupingBy(c -> c , Collectors.counting()));
map.forEach( (k, v) -> System.out.println(k + " : "+ v) );
}
}
This is the implementation without using any Collection and with complexity order of n. Although the accepted solution is good enough and does not use Collection as well but it seems, it is not taking care of special characters.
import java.util.Arrays;
public class DuplicateCharactersInString {
public static void main(String[] args) {
String string = "check duplicate charcters in string";
string = string.toLowerCase();
char[] charAr = string.toCharArray();
Arrays.sort(charAr);
for (int i = 1; i < charAr.length;) {
int count = recursiveMethod(charAr, i, 1);
if (count > 1) {
System.out.println("'" + charAr[i] + "' comes " + count + " times");
i = i + count;
} else
i++;
}
}
public static int recursiveMethod(char[] charAr, int i, int count) {
if (ifEquals(charAr[i - 1], charAr[i])) {
count = count + recursiveMethod(charAr, ++i, count);
}
return count;
}
public static boolean ifEquals(char a, char b) {
return a == b;
}
}
Output :
' ' comes 4 times
'a' comes 2 times
'c' comes 5 times
'e' comes 3 times
'h' comes 2 times
'i' comes 3 times
'n' comes 2 times
'r' comes 3 times
's' comes 2 times
't' comes 3 times
public class dublicate
{
public static void main(String...a)
{
System.out.print("Enter the String");
Scanner sc=new Scanner(System.in);
String st=sc.nextLine();
int [] ar=new int[256];
for(int i=0;i<st.length();i++)
{
ar[st.charAt(i)]=ar[st.charAt(i)]+1;
}
for(int i=0;i<256;i++)
{
char ch=(char)i;
if(ar[i]>0)
{
if(ar[i]==1)
{
System.out.print(ch);
}
else
{
System.out.print(ch+""+ar[i]);
}
}
}
}
}
Use google guava Multiset<String>.
Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(words);
for(Multiset.Entry<E> entry:wordsMultiset.entrySet()){
System.out.println(entry.getElement()+" - "+entry.getCount());
}
public static void main(String args[]) {
char Char;
int count;
String a = "Hi my name is Rahul";
a = a.toLowerCase();
for (Char = 'a'; Char <= 'z'; Char++) {
count = 0;
for (int i = 0; i < a.length(); i++) {
if (a.charAt(i) == Char) {
count++;
}
}
System.out.println("Number of occurences of " + Char + " is " + count);
}
}
public static void main(String[] args) {
String name="AnuvratAnuvra";
char[] arr = name.toCharArray();
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for(char val:arr){
map.put(val,map.containsKey(val)?map.get(val)+1:1);
}
for (Entry<Character, Integer> entry : map.entrySet()) {
if(entry.getValue()>1){
Character key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + ":"+value);
}
}
}
class A {
public static void getDuplicates(String S) {
int count = 0;
String t = "";
for (int i = 0; i < S.length() - 1; i++) {
for (int j = i + 1; j < S.length(); j++) {
if (S.charAt(i) == S.charAt(j) && !t.contains(S.charAt(j) + "")) {
t = t + S.charAt(i);
}
}
}
System.out.println(t);
}
}
class B
public class B {
public static void main(String[] args){
A.getDuplicates("mymgsgkkabcdyy");
}
}
You can also achieve it by iterating over your String and using a switch to check each individual character, adding a counter whenever it finds a match. Ah, maybe some code will make it clearer:
Main Application:
public static void main(String[] args) {
String test = "The quick brown fox jumped over the lazy dog.";
int countA = 0, countO = 0, countSpace = 0, countDot = 0;
for (int i = 0; i < test.length(); i++) {
switch (test.charAt(i)) {
case 'a':
case 'A': countA++; break;
case 'o':
case 'O': countO++; break;
case ' ': countSpace++; break;
case '.': countDot++; break;
}
}
System.out.printf("%s%d%n%s%d%n%s%d%n%s%d", "A: ", countA, "O: ", countO, "Space: ", countSpace, "Dot: ", countDot);
}
Output:
A: 1
O: 4
Space: 8
Dot: 1
import java.util.HashMap;
import java.util.Scanner;
public class HashMapDemo {
public static void main(String[] args) {
//Create HashMap object to Store Element as Key and Value
HashMap<Character,Integer> hm= new HashMap<Character,Integer>();
//Enter Your String From Console
System.out.println("Enter an String:");
//Create Scanner Class Object From Retrive the element from console to our java application
Scanner sc = new Scanner(System.in);
//Store Data in an string format
String s1=sc.nextLine();
//find the length of an string and check that hashmap object contain the character or not by using
//containskey() if that map object contain element only one than count that value as one or if it contain more than one than increment value
for(int i=0;i<s1.length();i++){
if(!hm.containsKey(s1.charAt(i))){
hm.put(s1.charAt(i),(Integer)1);
}//if
else{
hm.put(s1.charAt(i),hm.get(s1.charAt(i))+1);
}//else
}//for
System.out.println("The Charecters are:"+hm);
}//main
}//HashMapDemo
There are three ways to find duplicates
public class WAP_PrintDuplicates {
public static void main(String[] args) {
String input = "iabccdeffghhijkkkl";
findDuplicate1(input);
findDuplicate2(input);
findDuplicate3(input);
}
private static void findDuplicate3(String input) {
HashMap<Character, Integer> hm = new HashMap<Character, Integer>();
for (int i = 0; i < input.length() - 1; i++) {
int ch = input.charAt(i);
if (hm.containsKey(input.charAt(i))) {
int value = hm.get(input.charAt(i));
hm.put(input.charAt(i), value + 1);
} else {
hm.put(input.charAt(i), 1);
}
}
Set<Entry<Character, Integer>> entryObj = hm.entrySet();
for (Entry<Character, Integer> entry : entryObj) {
if (entry.getValue() > 1) {
System.out.println("Duplicate: " + entry.getKey());
}
}
}
private static void findDuplicate2(String input) {
int i = 0;
for (int j = i + 1; j < input.length(); j++, i++) {
if (input.charAt(i) == input.charAt(j)) {
System.out.println("Duplicate is: " + input.charAt(i));
}
}
}
private static void findDuplicate1(String input) {
// TODO Auto-generated method stub
for (int i = 0; i < input.length(); i++) {
for (int j = i + 1; j < input.length(); j++) {
if (input.charAt(i) == input.charAt(j)) {
System.out.println("Duplicate is: " + input.charAt(i));
}
}
}
}
}
Using Eclipse Collections CharAdapter and CharBag:
CharBag bag =
Strings.asChars("The quick brown fox jumped over the lazy dog.").toBag();
Assert.assertEquals(1, bag.occurrencesOf('a'));
Assert.assertEquals(4, bag.occurrencesOf('o'));
Assert.assertEquals(8, bag.occurrencesOf(' '));
Assert.assertEquals(1, bag.occurrencesOf('.'));
Note: I am a committer for Eclipse Collections
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class DuplicateCountChar{
public static void main(String[] args) {
Scanner inputString = new Scanner(System.in);
String token = inputString.nextLine();
char[] ch = token.toCharArray();
Map<Character, Integer> dupCountMap = new HashMap<Character,Integer>();
for (char c : ch) {
if(dupCountMap.containsKey(c)) {
dupCountMap.put(c, dupCountMap.get(c)+1);
}else {
dupCountMap.put(c, 1);
}
}
for (char c : ch) {
System.out.println("Key = "+c+ "Value : "+dupCountMap.get(c));
}
Set<Character> keys = dupCountMap.keySet();
for (Character character : keys) {
System.out.println("Key = "+character+ " Value : " + dupCountMap.get(character));
}
}**
In java... using for loop:
import java.util.Scanner;
/**
*
* #author MD SADDAM HUSSAIN */
public class Learn {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String input = sc.next();
char process[] = input.toCharArray();
boolean status = false;
int index = 0;
for (int i = 0; i < process.length; i++) {
for (int j = 0; j < process.length; j++) {
if (i == j) {
continue;
} else {
if (process[i] == process[j]) {
status = true;
index = i;
break;
} else {
status = false;
}
}
}
if (status) {
System.out.print("" + process[index]);
}
}
}
}
public class StringCountwithOutHashMap {
public static void main(String[] args) {
System.out.println("Plz Enter Your String: ");
Scanner sc = new Scanner(System.in);
String s1 = sc.nextLine();
int count = 0;
for (int i = 0; i < s1.length(); i++) {
for (int j = 0; j < s1.length(); j++) {
if (s1.charAt(i) == s1.charAt(j)) {
count++;
}
}
System.out.println(s1.charAt(i) + " --> " + count);
String d = String.valueOf(s1.charAt(i)).trim();
s1 = s1.replaceAll(d, "");
count = 0;
}}}
public class CountH {
public static void main(String[] args) {
String input = "Hi how are you";
char charCount = 'h';
int count = 0;
input = input.toLowerCase();
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == charCount) {
count++;
}
}
System.out.println(count);
}
}
public class DuplicateValue {
public static void main(String[] args) {
String s = "hezzz";
char []st=s.toCharArray();
int count=0;
Set<Character> ch=new HashSet<>();
for(Character cg:st){
if(ch.add(cg)==false){
int occurrences = Collections.frequency(ch, cg);
count+=occurrences;
if(count>1){
System.out.println(cg + ": This character exist more than one time");
}
else{
System.out.println(cg);
}
}
}
System.out.println(count);
}
}
Map<Character,Integer> listMap = new HashMap<Character,Integer>();
Scanner in= new Scanner(System.in);
System.out.println("enter the string");
String name=in.nextLine().toString();
Integer value=0;
for(int i=0;i<name.length();i++){
if(i==0){
listMap.put(name.charAt(0), 1);
}
else if(listMap.containsKey(name.charAt(i))){
value=listMap.get(name.charAt(i));
listMap.put(name.charAt(i), value+1);
}else listMap.put(name.charAt(i),1);
}
System.out.println(listMap);
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String reverse1;
String reverse2;
int count = 0;
while(n > 0)
{
String A = sc.next();
String B = sc.next();
reverse1 = new StringBuffer(A).reverse().toString();
reverse2 = new StringBuffer(B).reverse().toString();
if(!A.equals(reverse1))
{
for(int i = 0; i < A.length(); i++)
{
for(int j = 0; j < A.length(); j++)
{
if(A.charAt(j) == A.charAt(i))
{
count++;
}
}
if(count % 2 != 0)
{
A.replace(A.charAt(i),"");
count = 0;
}
}
System.out.println(A);
}
n--;
}
}
}
public class list {
public static String name(Character k){
String s="the quick brown fox jumped over the lazy dog.";
int count=0;
String l1="";
String l="";
List<Character> list=new ArrayList<Character>();
for(int i1=0;i1<s.length();i1++){
list.add(s.charAt(i1));
}
list.sort(null);
for (Character character : list) {
l+=character;
}
for (int i1=0;i1<l.length();i1++) {
if((l.charAt(i1)==k)){
count+=1;
l1=l.charAt(i1)+" "+Integer.toString(count);
if(k==' '){
l1="Space"+" "+Integer.toString(count);
}
}else{
count=0;
}
}
return l1;
}
public static void main(String[] args){
String g = name('.');
System.out.println(g);
}
}
Simple and Easy way to find char occurrences >
void findOccurrences() {
String s = "The quick brown fox jumped over the lazy dog.";
Map<String, Integer> occurrences = new LinkedHashMap<String, Integer>();
for (String ch : s.split("")) {
Integer count = occurrences.get(ch);
occurrences.put(ch, count == null ? 1 : count + 1);
}
System.out.println(occurrences);
}
This will print output as:
{T=1, h=2, e=4, =8, q=1, u=2, i=1, c=1, k=1, b=1, r=2, o=4, w=1, n=1, f=1, x=1, j=1, m=1, p=1, d=2, v=1, t=1, l=1, a=1, z=1, y=1, g=1, .=1}
String str = "anand";
Map<Character, Integer> map
= new HashMap<Character, Integer>();
// Converting string into a char array
char[] charArray = str.toCharArray();
for (char c : charArray) {
if (map.containsKey(c)) {
// If character is present increment count by 1
map.put(c, map.get(c) + 1);
}
else {
// If character is not present
//putting this character into map with 1 as it's value.
map.put(c, 1);
}
}
for (Map.Entry<Character, Integer> entry :
map.entrySet()) {
System.out.println(entry.getKey()
+ " : "
+ entry.getValue());
}
Output:
a:2 n:2 d:1
Use the below code snippet
import java.util.HashMap;
import java.util.Map;
public class CountDuplicateChar {
public static void main(String... strings) {
withSortedString("aaaaabbcccccc");
withUnSortedString("aaaaab bcc *#ccccf");
withHashMap("bala");
}
private static void withHashMap(String inputString) {
Map<Character, Integer> map = new HashMap<>();
char[] charArray = inputString.toCharArray();
for (int i = 0 ; i < charArray.length ; i++ ){
if (map.containsKey(charArray[i])) {
map.put(charArray[i], map.get(charArray[i]) +1);
} else {
map.put(charArray[i], 1);
}
}
System.out.println(map);
}
private static void withUnSortedString(String unSortedString) {
int len = 0;
do {
char[] ch = unSortedString.toCharArray();
if (ch.length ==0)
break;
int count = 0 ;
for ( int i = 0 ; i < ch.length; i++) {
if (ch[0] == ch[i]) {
count++;
}
}
System.out.println(ch[0] + " - " + count + "times");
unSortedString = unSortedString.replace(""+ch[0],"");
}while (len!=1);
}
private static void withSortedString(String s) {
for(int i=0; i<s.length(); i++)
{
System.out.print(s.charAt(i)+""+(s.lastIndexOf(s.charAt(i))-s.indexOf(s.charAt(i))+1));
i = s.lastIndexOf(s.charAt(i));
}
System.out.println(" ");
}
}
Using Java 8 streams with groupingBy()
//way 1
String name = "anandha";
Map<Character,Long> map = name.chars()
.mapToObj(ch -> (char)ch)
.collect(Collectors.groupingBy(ch -> ch, Collectors.counting());
System.out.println(map);
using LinkedHashmap
//way2
String name = "anandha";
char[] charArray = name.toChararray();
Map<Character,Integer> map = new LinkedHashmap<>();
for(char ch: charArray)
{
if(map.containsKey(ch))
{
map.put(ch,map.get(ch)+1);
}else
{
map.put(ch,1)
}
}
map.foreach((key,value)->{
{
System.out.println(key +" : "+ value);
}
});
//(OR) iterate map using the way above or below
for(Map.Entry mp: map.entrySet())
{
System.out.println(mp.getKey()+" : "+ mp.getValue());
}
}
public static void main(String[] args) {
char[] array = "aabsbdcbdgratsbdbcfdgs".toCharArray();
char[][] countArr = new char[array.length][2];
int lastIndex = 0;
for (char c : array) {
int foundIndex = -1;
for (int i = 0; i < lastIndex; i++) {
if (countArr[i][0] == c) {
foundIndex = i;
break;
}
}
if (foundIndex >= 0) {
int a = countArr[foundIndex][1];
countArr[foundIndex][1] = (char) ++a;
} else {
countArr[lastIndex][0] = c;
countArr[lastIndex][1] = '1';
lastIndex++;
}
}
for (int i = 0; i < lastIndex; i++) {
System.out.println(countArr[i][0] + " " + countArr[i][1]);
}
}
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;
}
}