StacksQueues/Subsets/Java
From charlesreid1
Contents
Algorithm for finding permutations of subsets in lexicographic order, no recursion
Here are the steps:
To find permutations, in lexicographic order:
1. Sort the list of items and print this as the first permutation
2. Let i be the last index such that input[i] < input[i+1]
(if no such index, we are done)
3. Let j be the last index such that input[i] < input[j]
4. Swap input[i]
with input[j]
5. Reverse input[i+1]
through input[input.length-1]
Example
Pass the flag "CHARLES"
First permutation is sorted: ACEHLRS
Second string is ACEHLSR
Third string is ACEHRLS
etc.
Code
See https://git.charlesreid1.com/cs/java/src/master/stacks-queues-deques/subset/StringPermutations.java
the main method/test
import java.io.*; import java.util.*; class Oops extends ArrayIndexOutOfBoundsException {} public class StringPermutations { public static void main(String[] args) { // Start with strings, then move to generics String theString = "CHARLES"; LinkedQueue<String> permutations = stringPermutations(thestring); System.out.println(permutations.size()); }
utility methods
Had to implement two utility methods:
public static void swap(char[] input, int i, int j) { char t = input[i]; input[i] = input[j]; input[j] = t; } public static void reverseFrom(char[] input, int startIndex) { // prolly shoulda used a stack. int len = input.length; int n = len - startIndex - 1; // if n odd, ignores middle index // if n even, swaps exactly half for(int k=0; k<(n/2); k++) { int ix = startIndex + k; int jx = len-1-k; swap(input,ix,jx); } }
Core algorithm
Finally, the core swapping algorithm, applied to char arrays:
public static LinkedQueue<String> stringPermutations(String s_input) { LinkedQueue<String> q = new LinkedQueue<String>(); // Save useful info int n = s_input.length(); char[] input = s_input.toCharArray(); Arrays.sort(input); // First is sorted string q.enqueue(new String(input)); boolean done = false; try { // Loop until we reach end while(!done) { // Step 1: // let i be the last index such that input[i] < input[i+1] // (if no such index, i=0 and we are done) int i = -1; for(int k=0; k<(n-1); k++) { if(input[k] < input[k+1]) { i = k; } } if(i<0) { // No such index, we are done done = true; break; } // Step 2: // let j be the last index such that input[i] < input[j] int j = -1; for(int k=i+1; k<n; k++) { if(input[i] < input[k]) { j = k; } } // Step 3: // swap i and j swap(input,i,j); // Step 4: // reverse i+1 thru length-1 reverseFrom(input, i+1); q.enqueue(new String(input)); } } catch(ArrayIndexOutOfBoundsException e) { System.out.println("OOPSIE"); } return q; } }
Flags
Algorithms Part of Computer Science Notes
Series on Algorithms
Algorithms/Sort · Algorithmic Analysis of Sort Functions · Divide and Conquer · Divide and Conquer/Master Theorem Three solid O(n log n) search algorithms: Merge Sort · Heap Sort · Quick Sort Algorithm Analysis/Merge Sort · Algorithm Analysis/Randomized Quick Sort
Algorithms/Search · Binary Search · Binary Search Modifications
Algorithms/Combinatorics · Algorithms/Combinatorics and Heuristics · Algorithms/Optimization · Divide and Conquer
Algorithms/Strings · Algorithm Analysis/Substring Pattern Matching
Algorithm complexity · Theta vs Big O Amortization · Amortization/Aggregate Method · Amortization/Accounting Method Algorithm Analysis/Matrix Multiplication
Estimation Estimation · Estimation/BitsAndBytes
Algorithm Practice and Writeups Project Euler · Five Letter Words · Letter Coverage
|