Count Matching Subsequences - c#

This is what I need to do:
Create a function that receives a text string, and a search string, and returns how many times the search string appears in the string, as a subsequence of its letters in order.
For example, if you receive the word "Hhoola" and the substring "hola", the answer would be 4, because you could take the first H with the first O (and with the L and with the A), the first H with the second O, the second H with the first O, or the second H with the second O. If you receive "hobla", the answer would be 1. If you receive "ohla", the answer would be 0, because after the H there is no O to complete the sequence in order.
This is what i got so far:
int count = 0;
void Function(string text, string subText)
{
for (int i = 0; i < text.Length; i++)
{
if (text[i] == subText[0])
{
for (int j = 0; j < subText.Length; j++)
{
if (text[i + j] != subText[j])
{
break;
}
if (j == subText.Length - 1)
{
count++;
}
}
}
}
}
string text = Console.ReadLine().ToLower();
string subText = Console.ReadLine().ToLower();
ReceibeText(text, subText);

The code should look like this. Code doesn't work but is close.
public class SubSequences
{
string input = "";
string word = "";
int count = 0;
public void FindMatches(string input, string word)
{
this.input = input;
this.word = word;
FindMatchesRecursive(0, 0);
}
public void FindMatchesRecursive(int inputIndex, int wordIndex)
{
for (int i = inputIndex; i < input.Length - word.Length; i++ )
{
for (int j = wordIndex; j < input.Length - word.Length; j++)
{
if (word.Substring(i) == input.Substring(j))
{
if (j == word.Length)
{
FindMatchesRecursive(i + 1, j + 1);
}
else
{
Console.WriteLine("Word Matches");
}
}
}
}
}

Related

Simple spell checker using Levenshtein distance

I have to implement a simple spell checker. Basically I have to user input an incorrect sentence or a word, then a number N, and then N correct words each on new line. The program has to output "incorrect word: suggestion". If there is no suggestions available it should output "incorrect word: no suggestions" and if all the words from sentence are correct it should display "Correct text!". The typos can be:
Misspeled word.
Swapped letters.
Extra letter.
Missing letter.
To do this I implemented Levensthein minumim distance algorithm, which calculates the minimum number of modifications that a string has to take to be transformed into another string. All the test cases are fine but I want to reduce the cyclomatic complexity of the main method from 27 to below 26. Any suggestion would be helpful. For the example:
Thsi is an texzt fr tet
5
This
an
text
for
test
It displays:
Thsi: This
an: no suggestions
texzt: text
fr: for
tet: text test
using System;
using System.Collections.Generic;
namespace MisspelledWords
{
class Program
{
static void Main(string[] args)
{
string sentence = Console.ReadLine();
sentence = sentence.ToLower();
int numWords = int.Parse(Console.ReadLine());
const int doi = 2;
const int doi2 = 3;
int index = 0;
int index1 = 0;
string[] correctWords = new string[numWords];
for (int i = 0; i < numWords; i++)
{
correctWords[i] = Console.ReadLine();
}
foreach (string word in sentence.Split(' '))
{
index++;
int minDistance = int.MaxValue;
string closestWord = "";
foreach (string correctWord in correctWords)
{
int distance = GetLevenshteinDistance(word, correctWord);
if (distance < minDistance)
{
minDistance = distance;
closestWord = correctWord;
}
}
Message(minDistance, closestWord, word, index, ref index1, correctWords);
if (index1 != 0)
{
return;
}
}
static void Message(int minDistance, string closestWord, string word, int index, ref int index1, string[] correctWords)
{
if (minDistance >= doi)
{
// Print the misspelled word followed by "no suggestions"
Console.WriteLine(word + ": (no suggestion)");
}
else if (minDistance < doi && closestWord != word || minDistance >= doi2)
{
// Find all correct words that have the same minimum distance
List<string> suggestions = new List<string>();
foreach (string correctWord in correctWords)
{
int distance = GetLevenshteinDistance(word, correctWord);
if (distance == minDistance)
{
suggestions.Add(correctWord);
}
}
// Print the misspelled word followed by the suggestions
Console.Write(word + ": ");
Console.WriteLine(string.Join(" ", suggestions));
}
else if (minDistance == 0 && index > 1)
{
Console.WriteLine("Text corect!");
index1++;
}
}
static int Min(int value1, int value2, int value3)
{
return Math.Min(Math.Min(value1, value2), value3);
}
static int GetLevenshteinDistance(string word1, string word2)
{
int[,] distance = new int[word1.Length + 1, word2.Length + 1];
InitializeDistanceMatrix(distance, word1, word2);
CalculateLevenshteinDistance(distance, word1, word2);
return distance[word1.Length, word2.Length];
}
static void InitializeDistanceMatrix(int[,] distance, string word1, string word2)
{
for (int i = 0; i <= word1.Length; i++)
{
for (int j = 0; j <= word2.Length; j++)
{
if (i == 0)
{
distance[i, j] = j;
}
else if (j == 0)
{
distance[i, j] = i;
}
}
}
}
static void CalculateLevenshteinDistance(int[,] distance, string word1, string word2)
{
for (int i = 0; i <= word1.Length; i++)
{
for (int j = 0; j <= word2.Length; j++)
{
CLD(i, j, distance, word1, word2);
}
}
}
static void CLD(int i, int j, int[,] distance, string word1, string word2)
{
const int v = 2;
if (i <= 0 || j <= 0)
{
return;
}
distance[i, j] = Min(
distance[i - 1, j] + 1,
distance[i, j - 1] + 1,
distance[i - 1, j - 1] + (word1[i - 1] == word2[j - 1] ? 0 : 1));
// Check if swapping the characters at positions i and j results in a new minimum distance
if (i <= 1 || j <= 1 || word1[i - 1] != word2[j - v] || word1[i - v] != word2[j - 1])
{
return;
}
distance[i, j] = Math.Min(distance[i, j], distance[i - v, j - v] + 1);
}
Console.ReadLine();
}
}
}

C# return string in Sine-Wave format

I'm trying to create a function which will return string in Triangle Sine-Wave format:
but currently, my format is only in Wave format:
Code below:
public static void printWave(string str)
{
int height = 3;
// Get length of the string
int len = str.Length;
// Create a 2d character array
char[,] matrixArray = new char[height, len];
char[] charArray = str.ToCharArray();
// for counting the
// rows of the ZigZag
int row = 0;
bool down = true;
for (int i = 0; i < len; i++)
{
// put characters
// in the matrix
matrixArray[row, i] = charArray[i];
// You have reached the bottom
if (row == height - 1)
down = false;
else if (row == 0)
down = true;
if (down)
row++;
else
row--;
}
// Print the Zig-Zag String
for (int i = 0; i < height; i++)
{
for (int j = 0; j < len; j++)
{
Console.Write(matrixArray[i, j] + " ");
}
Console.Write("\n");
}
}
Can you please help me modify my code to it will return triangle sin wave format?
We can use 3 separate StringBuilders to append to depending on our boolean top and a simple even value comparison. A quick TL;DR is that anything at an even index goes in the middle row, and then we flip between appending to the top or bottom row:
public static void printWave(string str)
{
//for use to determine top or bottom StringBuilder
bool top = true;
//will be used to generate each row of the output
StringBuilder topString = new StringBuilder();
StringBuilder middleString = new StringBuilder();
StringBuilder bottomString = new StringBuilder();
//iterate through paramter string
for (int i = 0; i < str.Length; i++)
{
//if char is at an even index, it goes in the middle StringBuilder, blank spaces in top and bottom builders
if (i%2 == 0)
{
topString.Append(" ");
middleString.Append(str[i]);
bottomString.Append(" ");
}
//if not even index, determine top or bottom row
else
{
//simply check our boolean and then flip it after use
if (top)
{
topString.Append(str[i]);
middleString.Append(" ");
bottomString.Append(" ");
top = false;
}
else
{
topString.Append(" ");
middleString.Append(" ");
bottomString.Append(str[i]);
top = true;
}
}
}
//write each row of strings on new lines
Console.WriteLine(topString.ToString());
Console.WriteLine(middleString.ToString());
Console.WriteLine(bottomString.ToString());
}
For a variable height:
public static void printWave(string str)
{
//height we want the wave to reach
int height = 5;
//determine "middle" row
int startingRow = height / 2;
int currentRow = startingRow; //this one is for modifying inside loop
bool up = true;
//2D array to hold the rows
char[,] arr = new char[height, str.Length];
for (int i = 0; i < str.Length; i++)
{
for (int j = 0; j < height; j++)
{
if (j == currentRow)
{
arr[j, i] = str[i];
}
else
arr[j, i] = ' ';
}
//could probably break this into more digestible pieces if time to think about it
if (up)
{
if (currentRow == 0)
{
up = false;
currentRow++;
}
else
{
currentRow--;
}
}
else
{
if (currentRow == height - 1)
{
up = true;
currentRow--;
}
else
{
currentRow++;
}
}
}
for (int k = 0; k < height; k++)
{
for (int l = 0; l < str.Length; l++)
{
Console.Write(arr[k, l]);
}
Console.WriteLine();
}
}
Examples of height = 5 and height = 6 output:
And finally, height = 7
This version works, but it's hard-coded to just the 3 rows like the question shows. If larger waves are needed, or especially if the size of the wave depends on the input string, then this may be hard to adjust to the requirements.
public static void PrintWave(string str)
{
printWithRowLogic(str, (i) => (i - 1) % 4 == 0);
Console.WriteLine();
printWithRowLogic(str, (i) => i % 2 == 0);
Console.WriteLine();
printWithRowLogic(str, (i) => (i - 3) % 4 == 0);
}
private static void printWithRowLogic(string str, Func<int, bool> checkLogic)
{
for (int i = 0; i < str.Length; i++)
Console.Write(checkLogic(i) ? str[i] : ' ');
}

How I can check if substring contain another substring c#

//the word skill it's a substring for two string i want to compare based it
string first = "skill.Name";
string second = "jobskillRelation";
first.Contains(second);
You can use Longest Common Substring code provided here, the C# version is like this:
public static string lcs(string a, string b)
{
var lengths = new int[a.Length, b.Length];
int greatestLength = 0;
string output = "";
for (int i = 0; i < a.Length; i++)
{
for (int j = 0; j < b.Length; j++)
{
if (a[i] == b[j])
{
lengths[i, j] = i == 0 || j == 0 ? 1 : lengths[i - 1, j - 1] + 1;
if (lengths[i, j] > greatestLength)
{
greatestLength = lengths[i, j];
output = a.Substring(i - greatestLength + 1, greatestLength);
}
}
else
{
lengths[i, j] = 0;
}
}
}
return output;
}
so the usage will be:
var LCS = lcs(first,second)
If you want to compare two string to see if both contain a certain keyword, this may help.
Boolean compare(string first, string second, string keyword)
{
if (first.Contains(keyword) && second.Contains(keyword))
return true;
return false;
}

Search a word in the given string in C#?

I have to find subtext in text without using builtin function of string.
public static void Main(string[] args)
{
string subtext = "polly";
string text = "polly put the katle on,polly put the katle on,polly put the katle on,we all have tea";
int i, j, found;
int strLen, wordLen;
strLen = text.Length;
wordLen = subtext.Length;
for (i = 0; i < strLen - wordLen; i++)
{
found = 1;
for (j = 0; j < wordLen; j++)
{
if (text[i + j] != subtext[j])
{
found = 0;
break;
}
}
if (found == 1)
{
Console.WriteLine(" found at index:", subtext, i);
Console.ReadLine();
}
}
}
I am not sure how long you would like to search, your current code seems to find all indexes (or at least that seems to be the intent)
Some things you could change however is instead of always starting the loop, you could validate the if the char at position i matches the first char of the subtext, and if not continue.
When you want to write the data to the console, don't forget to add the spaceholders for your arguments, like:
Console.WriteLine("found {0} at index: {1}", subtext, i);
For the rest, I guess your current implementation is okay, but you could add some validations, like ensuring that both texts are available, and if subtext is longer than the text, simply return -1 directly.
For a simple find of first index, I wrote this one up, it still looks pretty similar to yours
private static int FindIn( string text, string sub ) {
if (string.IsNullOrWhiteSpace( text ) || string.IsNullOrWhiteSpace( sub ) ) {
return string.IsNullOrWhiteSpace( sub ) ? 0 : -1;
}
if (text.Length < sub.Length) {
return -1;
}
for (int i = 0; i < text.Length - sub.Length; i++) {
if (text[i] != sub[0]) {
continue;
}
var matched = true;
for (int j = 1; j < sub.Length && i + j < text.Length; j++) {
if (text[i+j] != sub[j]) {
matched = false;
break;
}
}
if (matched) {
return i;
}
}
return -1;
}
Which you can play around with here
There are a lot of pattern-matching algorithms in this book, i will leave here c# implementation of Knuth-Morris-Pratt algorithm.
static int[] GetPrefix(string s)
{
int[] result = new int[s.Length];
result[0] = 0;
int index = 0;
for (int i = 1; i < s.Length; i++)
{
while (index >= 0 && s[index] != s[i]) { index--; }
index++;
result[i] = index;
}
return result;
}
static int FindSubstring(string pattern, string text)
{
int res = -1;
int[] pf = GetPrefix(pattern);
int index = 0;
for (int i = 0; i < text.Length; i++)
{
while (index > 0 && pattern[index] != text[i]) { index = pf[index - 1]; }
if (pattern[index] == text[i]) index++;
if (index == pattern.Length)
{
return res = i - index + 1;
}
}
return res;
}
If you are looking for all occurance of the subtect in the text you can use the following code:
public static void Main(string[] args)
{
string subtext = "polly";
string text = "polly put the katle on,polly put the katle on,polly put the katle on,we all have tea";
int index = 0;
int startPosition = 0;
bool found = false;
while (index < text.Length - 1)
{
if (subtext[0] == text[index])
{
startPosition = index;
index++;
for (int j = 1; j <= subtext.Length - 1; j++)
{
if (subtext[j] != text[index])
{
found = false;
break;
}
else
{
found = true;
}
index++;
}
}
if (found)
{
Console.WriteLine("{0} found at index: {1}", subtext, startPosition);
found = false;
}
index++;
}
Console.ReadLine();
}
If you are looking only for the first occurance add break in the "if (found)" condition

How to random order a 3 digit number on a list box? [duplicate]

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;
}

Categories

Resources