Recursive String permutation with repetitions allowed - java

Hi I'm trying to figure out an efficient way to get all permutations of a string but also allowing repetition of characters. (for example for string "ab" the output would be "aa, bb, ba, ab")
I have my code working correctly without repetition but I'm not sure how to go about modifying it to allow repetition of characters and only seem to find ways of doing this without repetition of characters.
Here is the code that I have:
public static ArrayList<String> permutationsUnique(String word) {
ArrayList<String> result = new ArrayList<String>();
if (word.length() == 0) {
result.add(word);
return result;
} else {
for (int i = 0; i < word.length(); i++) {
String shorter = word.substring(0, i) + word.substring(i + 1);
ArrayList<String> shorterPermutations = permutationsUnique(shorter);
for (String s : shorterPermutations) {
result.add(word.charAt(i) + s);
}
}
return result;
}
}
I would really appreciate if some one can guide me in the right direction.
Thank you

I know this question was asked long back, but I just worked on one java program to have permutation of integers with repetitions allowed. I am putting my code here, in case if someone needs it.
This program can generate permutations for specified length. i.e.
For integers 1,2 and lengthOfSinglePermutation = 2, output should be
11
21
12
22
For integers 1,2 and lengthOfSinglePermutation = 3, output should be
111
211
121
221
112
212
122
222
Hope this helps.
public class PermutationsWithRepetitions {
public static void main(String[] args) {
int[] input = { 1, 2 };
int lengthOfSinglePermutation = 3;
// we need to check number of unique values in array
Set<Integer> arrValues = new HashSet<Integer>();
for (int i : input) {
arrValues.add(i);
}
int noOfUniqueValues = arrValues.size();
int[] indexes = new int[lengthOfSinglePermutation];
int totalPermutations = (int) Math.pow(noOfUniqueValues, lengthOfSinglePermutation);
for (int i = 0; i < totalPermutations; i++) {
for (int j = 0; j < lengthOfSinglePermutation; j++) {
System.out.print(input[indexes[j]]);
}
System.out.println();
for (int j = 0; j < lengthOfSinglePermutation; j++) {
if (indexes[j] >= noOfUniqueValues - 1) {
indexes[j] = 0;
}
else {
indexes[j]++;
break;
}
}
}
}
}

Sorry, my previous answer was somewhat unrelated. DELETED. This will definitely work :-
static void Recur(String prefix, String str)
{
if(prefix.length()==str.length())
{
System.out.println(prefix); return;
}
for(int i=0; i<str.length(); i++)
Recur(prefix+str.charAt(i),str);
}
public static void main (String[] args)
{
String str = "AB";
}
The output is
AA
AB
BA
BB

I have another solution with a char array, but it works for any kind of array. Here, instead of print the characters (or whatever data type you want to), you can add your list and append the elements to it.
static void permuteAll(char [] a)
{
permuteArray(a, new char[a.length], 0);
}
static void permuteArray(char [] a, char [] s, int j)
{
if(j == a.length)
{
System.out.println(new String(s));
return;
}
for(int i = 0; i < a.length; i++)
{
s[j] = a[i];
permuteArray(a, s, j+1);
}
}

public static void main(String args[]){
String str="ABC";
int maxSize =3;
char[] chars = str.toCharArray();
getCombination(chars, maxSize);
}
static void getCombination(char[]chars, int maxSize){
for(int i=0; i<chars.length; i++){
combination(String.valueOf(chars[i]),chars,maxSize);
}
}
static void combination(String prefix,char[] chars, int maxSize) {
if(prefix.length()>=maxSize){
System.out.println(prefix);
}
else {
for(int j= 0; j<chars.length;j++)
{
String newPrefix =prefix.concat(String.valueOf(chars[j]));
combination(newPrefix,chars, maxSize);
}
}
}

Related

Iterate over an array and get all multiples of 10 java

I am very new to Java and I am trying to iterate over an array of integers and get all multiples of 10. What I get with my code is the elements in the array printed 100 times since that is the length of the array. I know it is very basic but I just can't figure the problem out. This is what I have:
import java.util.Arrays;
public class ArrayThings {
public static void main(String[] args) {
int[] myFirstArray = new int[100];
for (int i = 0; i < myFirstArray.length; i++) {
myFirstArray[i] = i;
}
for (int i : myFirstArray) {
if (i % 10 == 0) {
myFirstArray[i] = i;
} else {
i++;
}
System.out.println(Arrays.toString(myFirstArray));
}
}
}
I think that is what you want to do :
public class ArrayThings {
public static void main(String[] args) {
int[] myFirstArray = new int[100];
// array generation
for (int i = 0; i < myFirstArray.length; i++) {
myFirstArray[i] = i;
}
// printing multiples of 10
for (int i = 0; i < myFirstArray.length; i++) {
if (i % 10 == 0 && i != 0) {
System.out.println(myFirstArray[i]);
}
}
}
}
In Java-8 you can do it like below:
int result[] = IntStream.range(1, 100).filter(e -> e%10==0).toArray();
System.out.println(Arrays.toString(result));
Why do you need an array for printing multiples of 10? You could simply do:
public class ArrayThings{
public static void main(String[]args){
for(int i=0; i<101; i++) {
if(i%10==0 && i != 0){
System.out.println(i);
}
}
}}
P.S. you are printing whole array and not that particular element, that's why you are getting a wrong output.
You should move your print statement outside of the for loop, that is what is causing it to print 100 times.
Also your current code seems to do absolutely nothing. You are checking the modulo of i, then setting the value of myFirstArray to that value of i. The current value of myFirstArray at i, is already equal to i, as initialized in the first loop.
This should work
import java.util.Arrays;
public class ArrayThings {
public static void main(String[] args) {
int[] myFirstArray = new int[100];
int[] myMultiplesArray = new int[9];
for (int i = 0; i < myFirstArray.length; i++) {
myFirstArray[i] = i;
}
int j = 0;
for (int i : myFirstArray) {
if (i % 10 == 0) {
myMultiplesArray[j] = i;
j++;
}
}
System.out.println(Arrays.toString(myMultiplesArray));
}
}

Ordered Sampling with Replacement

Im really stuck in a rut for this one.
I want generate all the combinations such that there is Ordered Sampling with Replacement (i think this is what its called, see my example) and the result is output in an array of arrays (2D array).
For example
public static int[][] combinations(int n, int k)
on input n=3, k=2 would give:
[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
I'm really unsure how to do this efficiently. Any pointers are appreciated!
Here we have a set with n elements and we want to draw k samples from the set such that ordering matters and repetition is allowed.
Here the code:
public static void main(String[] args) {
int n = 4;
int k = 2;
int[][] result = combinations(n, k);
System.out.println(Arrays.deepToString(result));
//this will print:
//[[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]]
}
public static int[][] combinations(int n, int k) {
int[] nArray = IntStream.range(0, n).toArray();
List<String> list = new ArrayList<String>();
combinationStrings(k, nArray, "", list);
return fromArrayListToArray(list, k);
}
private static void combinationStrings(int k, int[] nArray, String currentString, List<String> list) {
if (currentString.length() == k) {
list.add(currentString);
} else {
for (int i = 0; i < nArray.length; i++) {
String oldCurrent = currentString;
currentString += nArray[i];
combinationStrings(k, nArray, currentString, list);
currentString = oldCurrent;
}
}
}
private static int[][] fromArrayListToArray(List<String> list, int k) {
int[][] result = new int[list.size()][k];
for (int i=0;i<list.size();i++) {
String[] split = list.get(i).split("\\B");
for (int j = 0; j < split.length; j++) {
result[i][j] = Integer.parseInt(split[j]);
}
}
return result;
}

Searching LinkedList, comparing two "Strings"?

I have a LinkedList where each node contains a word. I also have a variable that contains 6 randomly generated letters. I have a code the determines all possible letter combinations of those letters. I need to traverse through the linked list and determine the best "match" among the nodes.
Example:
-Letters generated: jghoot
-Linked list contains: cat, dog, cow, loot, hooter, ghlooter (I know ghlooter isn't a word)
The method would return hooter because it shares the most characters and is most similar to it. Any ideas?
I guess you could say I am looking for the word that the generated letters are a substring of.
use a nested for loop, compare each letter of your original string with the one you are comparing it to, and for each match, increase a local int variable. at the end of the loop, compare local int variable to global int variable that holds the "best" match till that one, and if bigger, store local int into global one, and put your found node into global node. at the end you should have a node which matches closest.
something like this
int currBest = 0;
int currBestNode = firstNodeOfLinkedList;
while(blabla)
{
int localBest = 0;
for(i= 0; i < currentNodeWord.length; i++)
{
for(j=0; j < originalWord.length;j++)
{
if(currentNodeWord[i] == originalWord[j])
{
localBest++
}
}
}
if(localBest > currBest)
{
currBest = localBest;
currBestNode = currentNodeStringBeingSearched;
}
}
// here u are out of ur loop, ur currBestNode should be set to the best match found.
hope that helps
If you're considering only character counts, first you need a method to count chars in a word
public int [] getCharCounts(String word) {
int [] result = new int['z' - 'a' + 1];
for(int i = 0; i<word.length(); i++) result[word.charAt(i) - 'a']++;
return result;
}
and then you need to compare character counts of two words
public static int compareCounts(int [] count1, int [] count2) [
int result = 0;
for(int i = 0; i<count1.length; i++) {
result += Math.min(count1[i], count2[i]);
}
return result;
}
public static void main(String[] args) {
String randomWord = "jghoot";
int [] randomWordCharCount = getCharCounts(randomWord);
ArrayList<String> wordList = new ArrayList();
String bestElement = null;
int bestMatch = -1;
for(String word : wordList) {
int [] wordCount = getCharCounts(word);
int cmp = compareCounts(randomWordCharCount, wordCount);
if(cmp > bestMatch) {
bestMatch = cmp;
bestElement = word;
}
}
System.out.println(word);
}
I think this works.
import java.util.*;
import java.io.*;
class LCSLength
{
public static void main(String args[])
{
ArrayList<String> strlist=new ArrayList<String>();
strlist.add(new String("cat"));
strlist.add(new String("cow"));
strlist.add(new String("hooter"));
strlist.add(new String("dog"));
strlist.add(new String("loot"));
String random=new String("jghoot"); //Your String
int maxLength=-1;
String maxString=new String();
for(String s:strlist)
{
int localMax=longestSubstr(s,random);
if(localMax>maxLength)
{
maxLength=localMax;
maxString=s;
}
}
System.out.println(maxString);
}
public static int longestSubstr(String first, String second) {
if (first == null || second == null || first.length() == 0 || second.length() == 0) {
return 0;
}
int maxLen = 0;
int fl = first.length();
int sl = second.length();
int[][] table = new int[fl+1][sl+1];
for(int s=0; s <= sl; s++)
table[0][s] = 0;
for(int f=0; f <= fl; f++)
table[f][0] = 0;
for (int i = 1; i <= fl; i++) {
for (int j = 1; j <= sl; j++) {
if (first.charAt(i-1) == second.charAt(j-1)) {
if (i == 1 || j == 1) {
table[i][j] = 1;
}
else {
table[i][j] = table[i - 1][j - 1] + 1;
}
if (table[i][j] > maxLen) {
maxLen = table[i][j];
}
}
}
}
return maxLen;
}
}
Credits: Wikipedia for longest common substring algorithm.
http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring

Sorting an array of strings in reverse alphabetical order in Java

I've been tasked with turning this code into a reverse sort, but for the life of me cannot figure out how to do it. These are my sort, findlargest and swap methods. I have a feeling I am missing something glaringly obvious here, any help would be really appreciated.
public static void sort(String[] arr)
{
for (int pass = 1; pass < arr.length; pass++)
{
int largestPos = findLargest(arr, arr.length - pass);
if (largestPos != arr.length - pass)
{
swap(arr, largestPos, arr.length - pass);
}
}
}
public static int findLargest(String[] arr, int num)
{
int largestPos = 0;
for (int i = 1; i <= num; i++)
{
if (arr[i].compareToIgnoreCase(arr[largestPos]) > 0)
{
largestPos = i;
}
}
return largestPos;
}
public static void swap(String[] arr, int first, int second)
{
String temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
}
Don't reinvent the wheel -
String[] strs = {"a", "b", "d", "c", "e"};
Arrays.sort(strs, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
System.out.println(Arrays.toString(strs));
[e, d, c, b, a]
Follow up from A. R. S.'s answer:
You could use a custom comparator if you are allowed to use the Arrays.Sort method...
Arrays.sort(stringArray, new Comparator<String>() {
#Override
public int compare(String t, String t1) {
return -t.compareToIgnoreCase(t1); //reverse the comparison, while ignoring case
}
});
Can you just turn findLargest to findSmallest, like this:
public static void sort(String[] arr) {
for (int pass = 1; pass < arr.length; pass++) {
int largestPos = findSmallest(arr, arr.length - pass);
if (largestPos != arr.length - pass) {
swap(arr, largestPos, arr.length - pass);
}
}
}
public static int findSmallest(String[] arr, int num) {
int largestPos = 0;
for (int i = 1; i <= num; i++) {
if (arr[i].compareToIgnoreCase(arr[largestPos]) < 0) {
largestPos = i;
}
}
return largestPos;
}
public static void swap(String[] arr, int first, int second) {
String temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
I think This is the one you need (if you don't think about collection framework).
public static void main(String args[]) {
String [] arr ={"abc","bac","cbc"};
String temp="";
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[j].compareTo(arr[i]) > 0){
temp = arr[i] ;
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(String val:arr){
System.out.println(val);
}
}
Output is
cbc
bac
abc
you can use Arrays.sort(arr) to sort in alphabetical order.
and then reverse it.
public static void sort(String[] arr) {
Arrays.sort(arr);
for (int i=0; i<arr.length/2; i++) {
swap(arr,i,arr.length-1-i);
}
}
Try this one if you want. In your version you are moving the largest towards the end of the array, resulting in alphabetical order.
Just in case you insist on your original approach, I have made some minor changes to your code:
public static void sort(String[] arr)
{
for (int pass = 1; pass < arr.length; pass++)
{
int largestPos = findLargest(arr, pass-1);
if (largestPos != pass - 1)
{
swap(arr, largestPos, pass - 1);
}
}
}
public static int findLargest(String[] arr, int num)
{
int largestPos = num;
for (int i = num+1; i < arr.length; i++)
{
if (arr[i].compareToIgnoreCase(arr[largestPos]) > 0)
{
largestPos = i;
}
}
return largestPos;
}
The most trivial one though, as suggested by Ian Roberts, is simply Arrays.sort(arr, Collections.reverseOrder());.
So, first we need to create String array, then use Arrays.sort(String[]);, then use for to reverse sort array to reverse order.
import java.util.Arrays;
public class SortClass {
public static void main(String[] args) {
String[] arrayString = new String[5];
arrayString[0] = "Cat";
arrayString[1] = "Apple";
arrayString[2] = "Dog";
arrayString[3] = "Mouse";
arrayString[4] = "kitchen";
Arrays.sort(arrayString);
String[] arrReverse = new String[arrayString.length];
for (int i = arrayString.length - 1; i >= 0; i--) {
arrReverse[arrayString.length - 1 - i] = arrayString[i];
}
}
}
String arr[]= new String[];
String s; //input string
int count=0;
for(int i=0;i<=s.length()-k;i++){
arr[i]=s.substring(i,i+k); //using substring method
count++;
}
int i=0;
int b=count;
while(count>0){
int j=0;
while(j<b){
if((arr[i].compareTo(arr[j])>0)){
String temp= arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
j++;
}
i++;
count--;
}
for(i=0;i<b;i++)
System.out.println(arr[i]);

Permutate a String to upper and lower case

I have a string, "abc". How would a program look like (if possible, in Java) who permute the String?
For example:
abc
ABC
Abc
aBc
abC
ABc
abC
AbC
Something like this should do the trick:
void printPermutations(String text) {
char[] chars = text.toCharArray();
for (int i = 0, n = (int) Math.pow(2, chars.length); i < n; i++) {
char[] permutation = new char[chars.length];
for (int j =0; j < chars.length; j++) {
permutation[j] = (isBitSet(i, j)) ? Character.toUpperCase(chars[j]) : chars[j];
}
System.out.println(permutation);
}
}
boolean isBitSet(int n, int offset) {
return (n >> offset & 1) != 0;
}
As you probably already know, the number of possible different combinations is 2^n, where n equals the length of the input string.
Since n could theoretically be fairly large, there's a chance that 2^n will exceed the capacity of a primitive type such as an int. (The user may have to wait a few years for all of the combinations to finish printing, but that's their business.)
Instead, let's use a bit vector to hold all of the possible combinations. We'll set the number of bits equal to n and initialize them all to 1. For example, if the input string is "abcdefghij", the initial bit vector values will be {1111111111}.
For every combination, we simply have to loop through all of the characters in the input string and set each one to uppercase if its corresponding bit is a 1, else set it to lowercase. We then decrement the bit vector and repeat.
For example, the process would look like this for an input of "abc":
Bits:   Corresponding Combo:
111    ABC
110    ABc
101    AbC
100    Abc
011    aBC
010    aBc
001    abC
000    abc
By using a loop rather than a recursive function call, we also avoid the possibility of a stack overflow exception occurring on large input strings.
Here is the actual implementation:
import java.util.BitSet;
public void PrintCombinations(String input) {
char[] currentCombo = input.toCharArray();
// Create a bit vector the same length as the input, and set all of the bits to 1
BitSet bv = new BitSet(input.length());
bv.set(0, currentCombo.length);
// While the bit vector still has some bits set
while(!bv.isEmpty()) {
// Loop through the array of characters and set each one to uppercase or lowercase,
// depending on whether its corresponding bit is set
for(int i = 0; i < currentCombo.length; ++i) {
if(bv.get(i)) // If the bit is set
currentCombo[i] = Character.toUpperCase(currentCombo[i]);
else
currentCombo[i] = Character.toLowerCase(currentCombo[i]);
}
// Print the current combination
System.out.println(currentCombo);
// Decrement the bit vector
DecrementBitVector(bv, currentCombo.length);
}
// Now the bit vector contains all zeroes, which corresponds to all of the letters being lowercase.
// Simply print the input as lowercase for the final combination
System.out.println(input.toLowerCase());
}
public void DecrementBitVector(BitSet bv, int numberOfBits) {
int currentBit = numberOfBits - 1;
while(currentBit >= 0) {
bv.flip(currentBit);
// If the bit became a 0 when we flipped it, then we're done.
// Otherwise we have to continue flipping bits
if(!bv.get(currentBit))
break;
currentBit--;
}
}
String str = "Abc";
str = str.toLowerCase();
int numOfCombos = 1 << str.length();
for (int i = 0; i < numOfCombos; i++) {
char[] combinations = str.toCharArray();
for (int j = 0; j < str.length(); j++) {
if (((i >> j) & 1) == 1 ) {
combinations[j] = Character.toUpperCase(str.charAt(j));
}
}
System.out.println(new String(combinations));
}
You can also use backtracking to solve this problem:
public List<String> letterCasePermutation(String S) {
List<String> result = new ArrayList<>();
backtrack(0 , S, "", result);
return result;
}
private void backtrack(int start, String s, String temp, List<String> result) {
if(start >= s.length()) {
result.add(temp);
return;
}
char c = s.charAt(start);
if(!Character.isAlphabetic(c)) {
backtrack(start + 1, s, temp + c, result);
return;
}
if(Character.isUpperCase(c)) {
backtrack(start + 1, s, temp + c, result);
c = Character.toLowerCase(c);
backtrack(start + 1, s, temp + c, result);
}
else {
backtrack(start + 1, s, temp + c, result);
c = Character.toUpperCase(c);
backtrack(start + 1, s, temp + c, result);
}
}
Please find here the code snippet for the above :
public class StringPerm {
public static void main(String[] args) {
String str = "abc";
String[] f = permute(str);
for (int x = 0; x < f.length; x++) {
System.out.println(f[x]);
}
}
public static String[] permute(String str) {
String low = str.toLowerCase();
String up = str.toUpperCase();
char[] l = low.toCharArray();
char u[] = up.toCharArray();
String[] f = new String[10];
f[0] = low;
f[1] = up;
int k = 2;
char[] temp = new char[low.length()];
for (int i = 0; i < l.length; i++)
{
temp[i] = l[i];
for (int j = 0; j < u.length; j++)
{
if (i != j) {
temp[j] = u[j];
}
}
f[k] = new String(temp);
k++;
}
for (int i = 0; i < u.length; i++)
{
temp[i] = u[i];
for (int j = 0; j < l.length; j++)
{
if (i != j) {
temp[j] = l[j];
}
}
f[k] = new String(temp);
k++;
}
return f;
}
}
You can do something like
```
import java.util.*;
public class MyClass {
public static void main(String args[]) {
String n=(args[0]);
HashSet<String>rs = new HashSet();
helper(rs,n,0,n.length()-1);
System.out.println(rs);
}
public static void helper(HashSet<String>rs,String res , int l, int n)
{
if(l>n)
return;
for(int i=l;i<=n;i++)
{
res=swap(res,i);
rs.add(res);
helper(rs,res,l+1,n);
res=swap(res,i);
}
}
public static String swap(String st,int i)
{
char c = st.charAt(i);
char ch[]=st.toCharArray();
if(Character.isUpperCase(c))
{
c=Character.toLowerCase(c);
}
else if(Character.isLowerCase(c))
{
c=Character.toUpperCase(c);
}
ch[i]=c;
return new String(ch);
}
}
```

Categories

Resources