A common task in programming interviews (not from my experience of interviews though) is to take a string or an integer and list every possible permutation.
Is there an example of how this is done and the logic behind solving such a problem?
I've seen a few code snippets but they weren't well commented/explained and thus hard to follow.
First of all: it smells like recursion of course!
Since you also wanted to know the principle, I did my best to explain it human language. I think recursion is very easy most of the times. You only have to grasp two steps:
The first step
All the other steps (all with the same logic)
In human language:
In short:
The permutation of 1 element is one element.
The permutation of a set of elements is a list each of the elements, concatenated with every permutation of the other elements.
Example:
If the set just has one element -->
return it.
perm(a) -> a
If the set has two characters: for
each element in it: return the
element, with the permutation of the
rest of the elements added, like so:
perm(ab) ->
a + perm(b) -> ab
b + perm(a) -> ba
Further: for each character in the set: return a character, concatenated with a permutation of > the rest of the set
perm(abc) ->
a + perm(bc) --> abc, acb
b + perm(ac) --> bac, bca
c + perm(ab) --> cab, cba
perm(abc...z) -->
a + perm(...), b + perm(....)
....
I found the pseudocode on http://www.programmersheaven.com/mb/Algorithms/369713/369713/permutation-algorithm-help/:
makePermutations(permutation) {
if (length permutation < required length) {
for (i = min digit to max digit) {
if (i not in permutation) {
makePermutations(permutation+i)
}
}
}
else {
add permutation to list
}
}
C#
OK, and something more elaborate (and since it is tagged c #), from http://radio.weblogs.com/0111551/stories/2002/10/14/permutations.html :
Rather lengthy, but I decided to copy it anyway, so the post is not dependent on the original.
The function takes a string of characters, and writes down every possible permutation of that exact string, so for example, if "ABC" has been supplied, should spill out:
ABC, ACB, BAC, BCA, CAB, CBA.
Code:
class Program
{
private static void Swap(ref char a, ref char b)
{
if (a == b) return;
var temp = a;
a = b;
b = temp;
}
public static void GetPer(char[] list)
{
int x = list.Length - 1;
GetPer(list, 0, x);
}
private static void GetPer(char[] list, int k, int m)
{
if (k == m)
{
Console.Write(list);
}
else
for (int i = k; i <= m; i++)
{
Swap(ref list[k], ref list[i]);
GetPer(list, k + 1, m);
Swap(ref list[k], ref list[i]);
}
}
static void Main()
{
string str = "sagiv";
char[] arr = str.ToCharArray();
GetPer(arr);
}
}
It's just two lines of code if LINQ is allowed to use. Please see my answer here.
EDIT
Here is my generic function which can return all the permutations (not combinations) from a list of T:
static IEnumerable<IEnumerable<T>>
GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(e => !t.Contains(e)),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
Example:
IEnumerable<IEnumerable<int>> result =
GetPermutations(Enumerable.Range(1, 3), 3);
Output - a list of integer-lists:
{1,2,3} {1,3,2} {2,1,3} {2,3,1} {3,1,2} {3,2,1}
As this function uses LINQ so it requires .net 3.5 or higher.
Here I have found the solution. It was written in Java, but I have converted it to C#. I hope it will help you.
Here's the code in C#:
static void Main(string[] args)
{
string str = "ABC";
char[] charArry = str.ToCharArray();
Permute(charArry, 0, 2);
Console.ReadKey();
}
static void Permute(char[] arry, int i, int n)
{
int j;
if (i==n)
Console.WriteLine(arry);
else
{
for(j = i; j <=n; j++)
{
Swap(ref arry[i],ref arry[j]);
Permute(arry,i+1,n);
Swap(ref arry[i], ref arry[j]); //backtrack
}
}
}
static void Swap(ref char a, ref char b)
{
char tmp;
tmp = a;
a=b;
b = tmp;
}
Recursion is not necessary, here is good information about this solution.
var values1 = new[] { 1, 2, 3, 4, 5 };
foreach (var permutation in values1.GetPermutations())
{
Console.WriteLine(string.Join(", ", permutation));
}
var values2 = new[] { 'a', 'b', 'c', 'd', 'e' };
foreach (var permutation in values2.GetPermutations())
{
Console.WriteLine(string.Join(", ", permutation));
}
Console.ReadLine();
I have been used this algorithm for years, it has O(N) time and space complexity to calculate each permutation.
public static class SomeExtensions
{
public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> enumerable)
{
var array = enumerable as T[] ?? enumerable.ToArray();
var factorials = Enumerable.Range(0, array.Length + 1)
.Select(Factorial)
.ToArray();
for (var i = 0L; i < factorials[array.Length]; i++)
{
var sequence = GenerateSequence(i, array.Length - 1, factorials);
yield return GeneratePermutation(array, sequence);
}
}
private static IEnumerable<T> GeneratePermutation<T>(T[] array, IReadOnlyList<int> sequence)
{
var clone = (T[]) array.Clone();
for (int i = 0; i < clone.Length - 1; i++)
{
Swap(ref clone[i], ref clone[i + sequence[i]]);
}
return clone;
}
private static int[] GenerateSequence(long number, int size, IReadOnlyList<long> factorials)
{
var sequence = new int[size];
for (var j = 0; j < sequence.Length; j++)
{
var facto = factorials[sequence.Length - j];
sequence[j] = (int)(number / facto);
number = (int)(number % facto);
}
return sequence;
}
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
private static long Factorial(int n)
{
long result = n;
for (int i = 1; i < n; i++)
{
result = result * i;
}
return result;
}
}
class Program
{
public static void Main(string[] args)
{
Permutation("abc");
}
static void Permutation(string rest, string prefix = "")
{
if (string.IsNullOrEmpty(rest)) Console.WriteLine(prefix);
// Each letter has a chance to be permutated
for (int i = 0; i < rest.Length; i++)
{
Permutation(rest.Remove(i, 1), prefix + rest[i]);
}
}
}
Slightly modified version in C# that yields needed permutations in an array of ANY type.
// USAGE: create an array of any type, and call Permutations()
var vals = new[] {"a", "bb", "ccc"};
foreach (var v in Permutations(vals))
Console.WriteLine(string.Join(",", v)); // Print values separated by comma
public static IEnumerable<T[]> Permutations<T>(T[] values, int fromInd = 0)
{
if (fromInd + 1 == values.Length)
yield return values;
else
{
foreach (var v in Permutations(values, fromInd + 1))
yield return v;
for (var i = fromInd + 1; i < values.Length; i++)
{
SwapValues(values, fromInd, i);
foreach (var v in Permutations(values, fromInd + 1))
yield return v;
SwapValues(values, fromInd, i);
}
}
}
private static void SwapValues<T>(T[] values, int pos1, int pos2)
{
if (pos1 != pos2)
{
T tmp = values[pos1];
values[pos1] = values[pos2];
values[pos2] = tmp;
}
}
First of all, sets have permutations, not strings or integers, so I'll just assume you mean "the set of characters in a string."
Note that a set of size n has n! n-permutations.
The following pseudocode (from Wikipedia), called with k = 1...n! will give all the permutations:
function permutation(k, s) {
for j = 2 to length(s) {
swap s[(k mod j) + 1] with s[j]; // note that our array is indexed starting at 1
k := k / j; // integer division cuts off the remainder
}
return s;
}
Here's the equivalent Python code (for 0-based array indexes):
def permutation(k, s):
r = s[:]
for j in range(2, len(s)+1):
r[j-1], r[k%j] = r[k%j], r[j-1]
k = k/j+1
return r
I liked FBryant87 approach since it's simple. Unfortunately, it does like many other "solutions" not offer all permutations or of e.g. an integer if it contains the same digit more than once. Take 656123 as an example. The line:
var tail = chars.Except(new List<char>(){c});
using Except will cause all occurrences to be removed, i.e. when c = 6, two digits are removed and we are left with e.g. 5123. Since none of the solutions I tried solved this, I decided to try and solve it myself by FBryant87's code as base. This is what I came up with:
private static List<string> FindPermutations(string set)
{
var output = new List<string>();
if (set.Length == 1)
{
output.Add(set);
}
else
{
foreach (var c in set)
{
// Remove one occurrence of the char (not all)
var tail = set.Remove(set.IndexOf(c), 1);
foreach (var tailPerms in FindPermutations(tail))
{
output.Add(c + tailPerms);
}
}
}
return output;
}
I simply just remove the first found occurrence using .Remove and .IndexOf. Seems to work as intended for my usage at least. I'm sure it could be made cleverer.
One thing to note though: The resulting list may contain duplicates, so make sure you either make the method return e.g. a HashSet instead or remove the duplicates after the return using any method you like.
Here is a simple solution in c# using recursion,
void Main()
{
string word = "abc";
WordPermuatation("",word);
}
void WordPermuatation(string prefix, string word)
{
int n = word.Length;
if (n == 0) { Console.WriteLine(prefix); }
else
{
for (int i = 0; i < n; i++)
{
WordPermuatation(prefix + word[i],word.Substring(0, i) + word.Substring(i + 1, n - (i+1)));
}
}
}
Here's a purely functional F# implementation:
let factorial i =
let rec fact n x =
match n with
| 0 -> 1
| 1 -> x
| _ -> fact (n-1) (x*n)
fact i 1
let swap (arr:'a array) i j = [| for k in 0..(arr.Length-1) -> if k = i then arr.[j] elif k = j then arr.[i] else arr.[k] |]
let rec permutation (k:int,j:int) (r:'a array) =
if j = (r.Length + 1) then r
else permutation (k/j+1, j+1) (swap r (j-1) (k%j))
let permutations (source:'a array) = seq { for k = 0 to (source |> Array.length |> factorial) - 1 do yield permutation (k,2) source }
Performance can be greatly improved by changing swap to take advantage of the mutable nature of CLR arrays, but this implementation is thread safe with regards to the source array and that may be desirable in some contexts.
Also, for arrays with more than 16 elements int must be replaced with types with greater/arbitrary precision as factorial 17 results in an int32 overflow.
Here is an easy to understand permutaion function for both string and integer as input. With this you can even set your output length(which in normal case it is equal to input length)
String
static ICollection<string> result;
public static ICollection<string> GetAllPermutations(string str, int outputLength)
{
result = new List<string>();
MakePermutations(str.ToCharArray(), string.Empty, outputLength);
return result;
}
private static void MakePermutations(
char[] possibleArray,//all chars extracted from input
string permutation,
int outputLength//the length of output)
{
if (permutation.Length < outputLength)
{
for (int i = 0; i < possibleArray.Length; i++)
{
var tempList = possibleArray.ToList<char>();
tempList.RemoveAt(i);
MakePermutations(tempList.ToArray(),
string.Concat(permutation, possibleArray[i]), outputLength);
}
}
else if (!result.Contains(permutation))
result.Add(permutation);
}
and for Integer just change the caller method and MakePermutations() remains untouched:
public static ICollection<int> GetAllPermutations(int input, int outputLength)
{
result = new List<string>();
MakePermutations(input.ToString().ToCharArray(), string.Empty, outputLength);
return result.Select(m => int.Parse(m)).ToList<int>();
}
example 1: GetAllPermutations("abc",3);
"abc" "acb" "bac" "bca" "cab" "cba"
example 2: GetAllPermutations("abcd",2);
"ab" "ac" "ad" "ba" "bc" "bd" "ca" "cb" "cd" "da" "db" "dc"
example 3: GetAllPermutations(486,2);
48 46 84 86 64 68
Building on #Peter's solution, here's a version that declares a simple LINQ-style Permutations() extension method that works on any IEnumerable<T>.
Usage (on string characters example):
foreach (var permutation in "abc".Permutations())
{
Console.WriteLine(string.Join(", ", permutation));
}
Outputs:
a, b, c
a, c, b
b, a, c
b, c, a
c, b, a
c, a, b
Or on any other collection type:
foreach (var permutation in (new[] { "Apples", "Oranges", "Pears"}).Permutations())
{
Console.WriteLine(string.Join(", ", permutation));
}
Outputs:
Apples, Oranges, Pears
Apples, Pears, Oranges
Oranges, Apples, Pears
Oranges, Pears, Apples
Pears, Oranges, Apples
Pears, Apples, Oranges
using System;
using System.Collections.Generic;
using System.Linq;
public static class PermutationExtension
{
public static IEnumerable<T[]> Permutations<T>(this IEnumerable<T> source)
{
var sourceArray = source.ToArray();
var results = new List<T[]>();
Permute(sourceArray, 0, sourceArray.Length - 1, results);
return results;
}
private static void Swap<T>(ref T a, ref T b)
{
T tmp = a;
a = b;
b = tmp;
}
private static void Permute<T>(T[] elements, int recursionDepth, int maxDepth, ICollection<T[]> results)
{
if (recursionDepth == maxDepth)
{
results.Add(elements.ToArray());
return;
}
for (var i = recursionDepth; i <= maxDepth; i++)
{
Swap(ref elements[recursionDepth], ref elements[i]);
Permute(elements, recursionDepth + 1, maxDepth, results);
Swap(ref elements[recursionDepth], ref elements[i]);
}
}
}
Here is the function which will print all permutaion.
This function implements logic Explained by peter.
public class Permutation
{
//http://www.java2s.com/Tutorial/Java/0100__Class-Definition/RecursivemethodtofindallpermutationsofaString.htm
public static void permuteString(String beginningString, String endingString)
{
if (endingString.Length <= 1)
Console.WriteLine(beginningString + endingString);
else
for (int i = 0; i < endingString.Length; i++)
{
String newString = endingString.Substring(0, i) + endingString.Substring(i + 1);
permuteString(beginningString + endingString.ElementAt(i), newString);
}
}
}
static void Main(string[] args)
{
Permutation.permuteString(String.Empty, "abc");
Console.ReadLine();
}
The below is my implementation of permutation . Don't mind the variable names, as i was doing it for fun :)
class combinations
{
static void Main()
{
string choice = "y";
do
{
try
{
Console.WriteLine("Enter word :");
string abc = Console.ReadLine().ToString();
Console.WriteLine("Combinatins for word :");
List<string> final = comb(abc);
int count = 1;
foreach (string s in final)
{
Console.WriteLine("{0} --> {1}", count++, s);
}
Console.WriteLine("Do you wish to continue(y/n)?");
choice = Console.ReadLine().ToString();
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
} while (choice == "y" || choice == "Y");
}
static string swap(string test)
{
return swap(0, 1, test);
}
static List<string> comb(string test)
{
List<string> sec = new List<string>();
List<string> first = new List<string>();
if (test.Length == 1) first.Add(test);
else if (test.Length == 2) { first.Add(test); first.Add(swap(test)); }
else if (test.Length > 2)
{
sec = generateWords(test);
foreach (string s in sec)
{
string init = s.Substring(0, 1);
string restOfbody = s.Substring(1, s.Length - 1);
List<string> third = comb(restOfbody);
foreach (string s1 in third)
{
if (!first.Contains(init + s1)) first.Add(init + s1);
}
}
}
return first;
}
static string ShiftBack(string abc)
{
char[] arr = abc.ToCharArray();
char temp = arr[0];
string wrd = string.Empty;
for (int i = 1; i < arr.Length; i++)
{
wrd += arr[i];
}
wrd += temp;
return wrd;
}
static List<string> generateWords(string test)
{
List<string> final = new List<string>();
if (test.Length == 1)
final.Add(test);
else
{
final.Add(test);
string holdString = test;
while (final.Count < test.Length)
{
holdString = ShiftBack(holdString);
final.Add(holdString);
}
}
return final;
}
static string swap(int currentPosition, int targetPosition, string temp)
{
char[] arr = temp.ToCharArray();
char t = arr[currentPosition];
arr[currentPosition] = arr[targetPosition];
arr[targetPosition] = t;
string word = string.Empty;
for (int i = 0; i < arr.Length; i++)
{
word += arr[i];
}
return word;
}
}
Here's a high level example I wrote which illustrates the human language explanation Peter gave:
public List<string> FindPermutations(string input)
{
if (input.Length == 1)
return new List<string> { input };
var perms = new List<string>();
foreach (var c in input)
{
var others = input.Remove(input.IndexOf(c), 1);
perms.AddRange(FindPermutations(others).Select(perm => c + perm));
}
return perms;
}
This is my solution which it is easy for me to understand
class ClassicPermutationProblem
{
ClassicPermutationProblem() { }
private static void PopulatePosition<T>(List<List<T>> finalList, List<T> list, List<T> temp, int position)
{
foreach (T element in list)
{
List<T> currentTemp = temp.ToList();
if (!currentTemp.Contains(element))
currentTemp.Add(element);
else
continue;
if (position == list.Count)
finalList.Add(currentTemp);
else
PopulatePosition(finalList, list, currentTemp, position + 1);
}
}
public static List<List<int>> GetPermutations(List<int> list)
{
List<List<int>> results = new List<List<int>>();
PopulatePosition(results, list, new List<int>(), 1);
return results;
}
}
static void Main(string[] args)
{
List<List<int>> results = ClassicPermutationProblem.GetPermutations(new List<int>() { 1, 2, 3 });
}
If performance and memory is an issue, I suggest this very efficient implementation. According to Heap's algorithm in Wikipedia, it should be the fastest. Hope it will fits your need :-) !
Just as comparison of this with a Linq implementation for 10! (code included):
This: 36288000 items in 235 millisecs
Linq: 36288000 items in 50051 millisecs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace WpfPermutations
{
/// <summary>
/// EO: 2016-04-14
/// Generator of all permutations of an array of anything.
/// Base on Heap's Algorithm. See: https://en.wikipedia.org/wiki/Heap%27s_algorithm#cite_note-3
/// </summary>
public static class Permutations
{
/// <summary>
/// Heap's algorithm to find all pmermutations. Non recursive, more efficient.
/// </summary>
/// <param name="items">Items to permute in each possible ways</param>
/// <param name="funcExecuteAndTellIfShouldStop"></param>
/// <returns>Return true if cancelled</returns>
public static bool ForAllPermutation<T>(T[] items, Func<T[], bool> funcExecuteAndTellIfShouldStop)
{
int countOfItem = items.Length;
if (countOfItem <= 1)
{
return funcExecuteAndTellIfShouldStop(items);
}
var indexes = new int[countOfItem];
for (int i = 0; i < countOfItem; i++)
{
indexes[i] = 0;
}
if (funcExecuteAndTellIfShouldStop(items))
{
return true;
}
for (int i = 1; i < countOfItem;)
{
if (indexes[i] < i)
{ // On the web there is an implementation with a multiplication which should be less efficient.
if ((i & 1) == 1) // if (i % 2 == 1) ... more efficient ??? At least the same.
{
Swap(ref items[i], ref items[indexes[i]]);
}
else
{
Swap(ref items[i], ref items[0]);
}
if (funcExecuteAndTellIfShouldStop(items))
{
return true;
}
indexes[i]++;
i = 1;
}
else
{
indexes[i++] = 0;
}
}
return false;
}
/// <summary>
/// This function is to show a linq way but is far less efficient
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="length"></param>
/// <returns></returns>
static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(e => !t.Contains(e)),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
/// <summary>
/// Swap 2 elements of same type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="a"></param>
/// <param name="b"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
/// <summary>
/// Func to show how to call. It does a little test for an array of 4 items.
/// </summary>
public static void Test()
{
ForAllPermutation("123".ToCharArray(), (vals) =>
{
Debug.Print(String.Join("", vals));
return false;
});
int[] values = new int[] { 0, 1, 2, 4 };
Debug.Print("Non Linq");
ForAllPermutation(values, (vals) =>
{
Debug.Print(String.Join("", vals));
return false;
});
Debug.Print("Linq");
foreach(var v in GetPermutations(values, values.Length))
{
Debug.Print(String.Join("", v));
}
// Performance
int count = 0;
values = new int[10];
for(int n = 0; n < values.Length; n++)
{
values[n] = n;
}
Stopwatch stopWatch = new Stopwatch();
stopWatch.Reset();
stopWatch.Start();
ForAllPermutation(values, (vals) =>
{
foreach(var v in vals)
{
count++;
}
return false;
});
stopWatch.Stop();
Debug.Print($"Non Linq {count} items in {stopWatch.ElapsedMilliseconds} millisecs");
count = 0;
stopWatch.Reset();
stopWatch.Start();
foreach (var vals in GetPermutations(values, values.Length))
{
foreach (var v in vals)
{
count++;
}
}
stopWatch.Stop();
Debug.Print($"Linq {count} items in {stopWatch.ElapsedMilliseconds} millisecs");
}
}
}
Here's my solution in JavaScript (NodeJS). The main idea is that we take one element at a time, "remove it" from the string, vary the rest of the characters, and insert the element at the front.
function perms (string) {
if (string.length == 0) {
return [];
}
if (string.length == 1) {
return [string];
}
var list = [];
for(var i = 0; i < string.length; i++) {
var invariant = string[i];
var rest = string.substr(0, i) + string.substr(i + 1);
var newPerms = perms(rest);
for (var j = 0; j < newPerms.length; j++) {
list.push(invariant + newPerms[j]);
}
}
return list;
}
module.exports = perms;
And here are the tests:
require('should');
var permutations = require('../src/perms');
describe('permutations', function () {
it('should permute ""', function () {
permutations('').should.eql([]);
})
it('should permute "1"', function () {
permutations('1').should.eql(['1']);
})
it('should permute "12"', function () {
permutations('12').should.eql(['12', '21']);
})
it('should permute "123"', function () {
var expected = ['123', '132', '321', '213', '231', '312'];
var actual = permutations('123');
expected.forEach(function (e) {
actual.should.containEql(e);
})
})
it('should permute "1234"', function () {
// Wolfram Alpha FTW!
var expected = ['1234', '1243', '1324', '1342', '1423', '1432', '2134', '2143', '2314', '2341', '2413', '2431', '3124', '3142', '3214', '3241', '3412', '3421', '4123', '4132'];
var actual = permutations('1234');
expected.forEach(function (e) {
actual.should.containEql(e);
})
})
})
Here is the simplest solution I can think of:
let rec distribute e = function
| [] -> [[e]]
| x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]
let permute xs = Seq.fold (fun ps x -> List.collect (distribute x) ps) [[]] xs
The distribute function takes a new element e and an n-element list and returns a list of n+1 lists each of which has e inserted at a different place. For example, inserting 10 at each of the four possible places in the list [1;2;3]:
> distribute 10 [1..3];;
val it : int list list =
[[10; 1; 2; 3]; [1; 10; 2; 3]; [1; 2; 10; 3]; [1; 2; 3; 10]]
The permute function folds over each element in turn distributing over the permutations accumulated so far, culminating in all permutations. For example, the 6 permutations of the list [1;2;3]:
> permute [1;2;3];;
val it : int list list =
[[3; 2; 1]; [2; 3; 1]; [2; 1; 3]; [3; 1; 2]; [1; 3; 2]; [1; 2; 3]]
Changing the fold to a scan in order to keep the intermediate accumulators sheds some light on how the permutations are generated an element at a time:
> Seq.scan (fun ps x -> List.collect (distribute x) ps) [[]] [1..3];;
val it : seq<int list list> =
seq
[[[]]; [[1]]; [[2; 1]; [1; 2]];
[[3; 2; 1]; [2; 3; 1]; [2; 1; 3]; [3; 1; 2]; [1; 3; 2]; [1; 2; 3]]]
Lists permutations of a string. Avoids duplication when characters are repeated:
using System;
using System.Collections;
class Permutation{
static IEnumerable Permutations(string word){
if (word == null || word.Length <= 1) {
yield return word;
yield break;
}
char firstChar = word[0];
foreach( string subPermute in Permutations (word.Substring (1)) ) {
int indexOfFirstChar = subPermute.IndexOf (firstChar);
if (indexOfFirstChar == -1) indexOfFirstChar = subPermute.Length;
for( int index = 0; index <= indexOfFirstChar; index++ )
yield return subPermute.Insert (index, new string (firstChar, 1));
}
}
static void Main(){
foreach( var permutation in Permutations ("aab") )
Console.WriteLine (permutation);
}
}
//Generic C# Method
private static List<T[]> GetPerms<T>(T[] input, int startIndex = 0)
{
var perms = new List<T[]>();
var l = input.Length - 1;
if (l == startIndex)
perms.Add(input);
else
{
for (int i = startIndex; i <= l; i++)
{
var copy = input.ToArray(); //make copy
var temp = copy[startIndex];
copy[startIndex] = copy[i];
copy[i] = temp;
perms.AddRange(GetPerms(copy, startIndex + 1));
}
}
return perms;
}
//usages
char[] charArray = new char[] { 'A', 'B', 'C' };
var charPerms = GetPerms(charArray);
string[] stringArray = new string[] { "Orange", "Mango", "Apple" };
var stringPerms = GetPerms(stringArray);
int[] intArray = new int[] { 1, 2, 3 };
var intPerms = GetPerms(intArray);
Base/Revise on Pengyang answer
And inspired from permutations-in-javascript
The c# version FunctionalPermutations should be this
static IEnumerable<IEnumerable<T>> FunctionalPermutations<T>(IEnumerable<T> elements, int length)
{
if (length < 2) return elements.Select(t => new T[] { t });
/* Pengyang answser..
return _recur_(list, length - 1).SelectMany(t => list.Where(e => !t.Contains(e)),(t1, t2) => t1.Concat(new T[] { t2 }));
*/
return elements.SelectMany((element_i, i) =>
FunctionalPermutations(elements.Take(i).Concat(elements.Skip(i + 1)), length - 1)
.Select(sub_ei => new[] { element_i }.Concat(sub_ei)));
}
I hope this will suffice:
using System;
public class Program
{
public static void Main()
{
//Example using word cat
permute("cat");
}
static void permute(string word){
for(int i=0; i < word.Length; i++){
char start = word[0];
for(int j=1; j < word.Length; j++){
string left = word.Substring(1,j-1);
string right = word.Substring(j);
Console.WriteLine(start+right+left);
}
if(i+1 < word.Length){
word = wordChange(word, i + 1);
}
}
}
static string wordChange(string word, int index){
string newWord = "";
for(int i=0; i<word.Length; i++){
if(i== 0)
newWord += word[index];
else if(i== index)
newWord += word[0];
else
newWord += word[i];
}
return newWord;
}
output:
cat
cta
act
atc
tca
tac
Here is the function which will print all permutations recursively.
public void Permutations(string input, StringBuilder sb)
{
if (sb.Length == input.Length)
{
Console.WriteLine(sb.ToString());
return;
}
char[] inChar = input.ToCharArray();
for (int i = 0; i < input.Length; i++)
{
if (!sb.ToString().Contains(inChar[i]))
{
sb.Append(inChar[i]);
Permutations(input, sb);
RemoveChar(sb, inChar[i]);
}
}
}
private bool RemoveChar(StringBuilder input, char toRemove)
{
int index = input.ToString().IndexOf(toRemove);
if (index >= 0)
{
input.Remove(index, 1);
return true;
}
return false;
}
class Permutation
{
public static List<string> Permutate(string seed, List<string> lstsList)
{
loopCounter = 0;
// string s="\w{0,2}";
var lstStrs = PermuateRecursive(seed);
Trace.WriteLine("Loop counter :" + loopCounter);
return lstStrs;
}
// Recursive function to find permutation
private static List<string> PermuateRecursive(string seed)
{
List<string> lstStrs = new List<string>();
if (seed.Length > 2)
{
for (int i = 0; i < seed.Length; i++)
{
str = Swap(seed, 0, i);
PermuateRecursive(str.Substring(1, str.Length - 1)).ForEach(
s =>
{
lstStrs.Add(str[0] + s);
loopCounter++;
});
;
}
}
else
{
lstStrs.Add(seed);
lstStrs.Add(Swap(seed, 0, 1));
}
return lstStrs;
}
//Loop counter variable to count total number of loop execution in various functions
private static int loopCounter = 0;
//Non recursive version of permuation function
public static List<string> Permutate(string seed)
{
loopCounter = 0;
List<string> strList = new List<string>();
strList.Add(seed);
for (int i = 0; i < seed.Length; i++)
{
int count = strList.Count;
for (int j = i + 1; j < seed.Length; j++)
{
for (int k = 0; k < count; k++)
{
strList.Add(Swap(strList[k], i, j));
loopCounter++;
}
}
}
Trace.WriteLine("Loop counter :" + loopCounter);
return strList;
}
private static string Swap(string seed, int p, int p2)
{
Char[] chars = seed.ToCharArray();
char temp = chars[p2];
chars[p2] = chars[p];
chars[p] = temp;
return new string(chars);
}
}
Here is a C# answer which is a little simplified.
public static void StringPermutationsDemo()
{
strBldr = new StringBuilder();
string result = Permute("ABCD".ToCharArray(), 0);
MessageBox.Show(result);
}
static string Permute(char[] elementsList, int startIndex)
{
if (startIndex == elementsList.Length)
{
foreach (char element in elementsList)
{
strBldr.Append(" " + element);
}
strBldr.AppendLine("");
}
else
{
for (int tempIndex = startIndex; tempIndex <= elementsList.Length - 1; tempIndex++)
{
Swap(ref elementsList[startIndex], ref elementsList[tempIndex]);
Permute(elementsList, (startIndex + 1));
Swap(ref elementsList[startIndex], ref elementsList[tempIndex]);
}
}
return strBldr.ToString();
}
static void Swap(ref char Char1, ref char Char2)
{
char tempElement = Char1;
Char1 = Char2;
Char2 = tempElement;
}
Output:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
Here is one more implementation of the algo mentioned.
public class Program
{
public static void Main(string[] args)
{
string str = "abcefgh";
var astr = new Permutation().GenerateFor(str);
Console.WriteLine(astr.Length);
foreach(var a in astr)
{
Console.WriteLine(a);
}
//a.ForEach(Console.WriteLine);
}
}
class Permutation
{
public string[] GenerateFor(string s)
{
if(s.Length == 1)
{
return new []{s};
}
else if(s.Length == 2)
{
return new []{s[1].ToString()+s[0].ToString(),s[0].ToString()+s[1].ToString()};
}
var comb = new List<string>();
foreach(var c in s)
{
string cStr = c.ToString();
var sToProcess = s.Replace(cStr,"");
if (!string.IsNullOrEmpty(sToProcess) && sToProcess.Length>0)
{
var conCatStr = GenerateFor(sToProcess);
foreach(var a in conCatStr)
{
comb.Add(c.ToString()+a);
}
}
}
return comb.ToArray();
}
}
Here's another appraoch that is slighly more generic.
void Main()
{
var perms = new Permutations<char>("abc");
perms.Generate();
}
class Permutations<T> {
private List<T> permutation = new List<T>();
HashSet<T> chosen;
int n;
List<T> sequence;
public Permutations(IEnumerable<T> sequence)
{
this.sequence = sequence.ToList();
this.n = this.sequence.Count;
chosen = new HashSet<T>();
}
public void Generate()
{
if(permutation.Count == n) {
Console.WriteLine(string.Join(",",permutation));
}
else
{
foreach(var elem in sequence)
{
if(chosen.Contains(elem)) continue;
chosen.Add(elem);
permutation.Add(elem);
Generate();
chosen.Remove(elem);
permutation.Remove(elem);
}
}
}
}
Given an array A with zero index and N integers find equal elements with different positions in the array. Pair of indexes (P,Q) such that 0 <= P < Q < N such that A[P] = A[Q]. My algorithm is below but I am looking for a O(N*logN) solution.
public int solution(int[] A)
{
int N = A.Length;
int count = 0;
for (int j = 0; j < N; j++)
{
count += FindPairs(A[j], j, A);
}
return count;
}
public int FindPairs(int item, int ci, int[] A)
{
int len = A.Length;
int counter=0;
int k = ci+1;
while (k < len)
{
if (item == A[k])
counter++;
k++;
}
return counter;
}
From your code, it looks like the goal is to return the count of ascending duplicate pairs in A.
We observe that if there are m occurrences of the number x in A, then the number of ascending duplicate pairs of the value x is m choose 2, or m (m - 1) / 2.
So, we sum up m (m - 1) / 2 for each unique x, giving us the answer.
In pseudocode, this looks like:
count = new Dictionary();
foreach a in A {
count[a]++;
}
total = 0;
foreach key, value in count {
total += value * (value - 1) / 2;
}
return total;
This algorithm is O(N).
Recent interview question … here is what I did:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Codility
{
internal class Program
{
public struct Indice
{
public Indice(int p, int q)
{
P = p;
Q = q;
}
public int P;
public int Q;
public override string ToString()
{
return string.Format("({0}, {1})", P, Q);
}
}
private static void Main(string[] args)
{
// 0 1 2 3 4 5
int[] list = new int[] {3,3,3,3,3,3};
int answer = GetPairCount(list);
Console.WriteLine("answer = " + answer);
Console.ReadLine();
}
private static int GetPairCount(int[] A)
{
if (A.Length < 2) return 0;
Dictionary<int, Dictionary<Indice, Indice>> tracker = new Dictionary<int, Dictionary<Indice, Indice>>();
for (int i = 0; i < A.Length; i++)
{
int val = A[i];
if (!tracker.ContainsKey(val))
{
Dictionary<Indice, Indice> list = new Dictionary<Indice, Indice>();
Indice seed = new Indice(i, -1);
list.Add(seed, seed);
tracker.Add(val, list);
}
else
{
Dictionary<Indice, Indice> list = tracker[val];
foreach (KeyValuePair<Indice,Indice> item in list.ToList())
{
Indice left = new Indice(item.Value.P, i);
Indice right = new Indice(i, item.Value.Q);
if (!list.ContainsKey(left))
{
list.Add(left, left);
Console.WriteLine("left= " + left);
}
if (!list.ContainsKey(right))
{
list.Add(right, right);
Console.WriteLine("\t\tright= " + right);
}
}
}
}
return tracker.SelectMany(kvp => kvp.Value).Count(num => num.Value.Q > num.Value.P);
}
}
}
I think this is best version I got in c#.
static void Main(string[] args)
{
var a = new int[6] { 3, 5, 6, 3, 3, 5 };
//Push the indices into an array:
int[] indices = new int[a.Count()];
for (int p = 0; p < a.Count(); ++p) indices[p] = p;
//Sort the indices according to the value of the corresponding element in a:
Array.Sort(indices, (k, l) =>Compare(a[k], a[l]));
//Then just pull out blocks of indices with equal corresponding elements from indices:
int count = 0;
int i = 0;
while (i < indices.Count())
{
int start = i;
while (i < indices.Count() && a[indices[i]] == a[indices[start]])
{
++i;
}
int thisCount = i - start;
int numPairs = thisCount * (thisCount - 1) / 2;
count += numPairs;
}
Console.WriteLine(count);
Console.ReadKey();
}
//Compare function to return interger
private static int Compare(int v1, int v2)
{
if (v2 > v1)
return 1;
if (v1 == v2)
return 0;
else
return -1;
}
This approach has O(n log n) complexity overall, because of the sorting. The counting of the groups is linear.
Try this:
private static int GetIdenticalPairCount(int[] input)
{
int identicalPairCount = 0;
Dictionary<int, int> identicalCountMap = new Dictionary<int, int>();
foreach (int i in input)
{
if (identicalCountMap.ContainsKey(i))
{
identicalCountMap[i] = identicalCountMap[i] + 1;
if (identicalCountMap[i] > 1)
{
identicalPairCount += identicalCountMap[i];
}
else
{
identicalPairCount++;
}
}
else
{
identicalCountMap.Add(i, 0);
}
}
return identicalPairCount;
}
Test my version:
public int solution(int[] A)
{
int N = A.Length;
int count = 0;
for (int j = 0; j < N - 1; j++)
for (int i = j + 1; i < N; i++)
if (A[i] == A[j])
count++;
return count;
}
My requirements are simple:
Be able to define dimensions of bit array, i.e: 5 bytes.
bool Get(bitIndex: int)
Set(bitIndex: int)
Is there a c# equivalent which provides similar functionality to BitSet in Java?
Here's the scenario:
Initialize 5 bytes, all bits are 0(false).
Set byte 3, bit 8 to TRUE.
Get status of byte 3, bit 8.
UPDATE: Solution from Michael Bray:
static void Main(string[] args)
{
// Set for 5 bytes
BitArray ba = new BitArray(8 * 5);
// Set bit #1 on byte #4
ba.Set(GetBitNum(4, 1), true);
// Get bit #1 on byte #4
bool v = ba.Get(GetBitNum(4, 1));
}
static int GetBitNum(int byteNum, int bitNum) // Assumes index starts at 1
{
return (byteNum - 1) * 8 + (bitNum - 1);
}
System.Collections.BitArray is pretty close, but it's a bit lacking in features. I wrote a helper class that implements a lot of features you might need for BitArray some time ago, but I'd have to dig it up. Let me know if you think you need it.
EDIT: As requested in the comments below, I've posted the code at http://pastebin.com/GLyzcUZC. As I discuss, though, it's benefits over stock BitArray are minimal, as I wrote it for some specific needs that I had. Do with it as you wish.
EDIT 2: As Miguel pointed out in the comments, there are some implementation issues that make my 'BitArray' code not so good... I had already realized the deficiencies and had re-written a new version called BoolArray (to distinguish from BitArray) that doesn't suffer from those problems :
namespace Utils
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Threading;
/// <summary>
/// A replacement for BitArray
/// </summary>
public class BoolArray : IEnumerable, ICollection, ICloneable
{
private UInt32[] bits = null;
private int _length = 0;
private static UInt32 ONE = (UInt32)1 << 31;
private object _syncRoot;
private static Func<byte[], byte[]> EndianFixer = null;
#region Constructors
static BoolArray()
{
if (BitConverter.IsLittleEndian) EndianFixer = (a) => a.Reverse().ToArray();
else EndianFixer = (a) => a;
}
public BoolArray(BoolArray srcBits)
{
this.InitializeFrom(srcBits.ToArray());
}
public BoolArray(BitArray srcBits)
{
this._length = srcBits.Count;
this.bits = new UInt32[RequiredSize(this._length)];
for (int i = 0; i < srcBits.Count; i++) this[i] = srcBits[i];
}
public BoolArray(int v)
{
ICollection<byte> bytes = EndianFixer(BitConverter.GetBytes(v)).ToList();
InitializeFrom(bytes);
}
public BoolArray(ICollection<bool> srcBits)
{
this.InitializeFrom(srcBits.ToArray());
}
public BoolArray(ICollection<byte> srcBits)
{
InitializeFrom(srcBits);
}
public BoolArray(ICollection<short> srcBits)
{
ICollection<byte> bytes = srcBits.SelectMany(v => EndianFixer(BitConverter.GetBytes(v))).ToList();
InitializeFrom(bytes);
}
public BoolArray(ICollection<ushort> srcBits)
{
ICollection<byte> bytes = srcBits.SelectMany(v => EndianFixer(BitConverter.GetBytes(v))).ToList();
InitializeFrom(bytes);
}
public BoolArray(ICollection<int> srcBits)
{
ICollection<byte> bytes = srcBits.SelectMany(v => EndianFixer(BitConverter.GetBytes(v))).ToList();
InitializeFrom(bytes);
}
public BoolArray(ICollection<uint> srcBits)
{
ICollection<byte> bytes = srcBits.SelectMany(v => EndianFixer(BitConverter.GetBytes(v))).ToList();
InitializeFrom(bytes);
}
public BoolArray(ICollection<long> srcBits)
{
ICollection<byte> bytes = srcBits.SelectMany(v => EndianFixer(BitConverter.GetBytes(v))).ToList();
InitializeFrom(bytes);
}
public BoolArray(ICollection<ulong> srcBits)
{
ICollection<byte> bytes = srcBits.SelectMany(v => EndianFixer(BitConverter.GetBytes(v))).ToList();
InitializeFrom(bytes);
}
public BoolArray(int capacity, bool defaultValue = false)
{
this.bits = new UInt32[RequiredSize(capacity)];
this._length = capacity;
// Only need to do this if true, because default for all bits is false
if (defaultValue) for (int i = 0; i < this._length; i++) this[i] = true;
}
private void InitializeFrom(ICollection<byte> srcBits)
{
this._length = srcBits.Count * 8;
this.bits = new UInt32[RequiredSize(this._length)];
for (int i = 0; i < srcBits.Count; i++)
{
uint bv = srcBits.Skip(i).Take(1).Single();
for (int b = 0; b < 8; b++)
{
bool bitVal = ((bv << b) & 0x0080) != 0;
int bi = 8 * i + b;
this[bi] = bitVal;
}
}
}
private void InitializeFrom(ICollection<bool> srcBits)
{
this._length = srcBits.Count;
this.bits = new UInt32[RequiredSize(this._length)];
int index = 0;
foreach (var b in srcBits) this[index++] = b;
}
private static int RequiredSize(int bitCapacity)
{
return (bitCapacity + 31) >> 5;
}
#endregion
public bool this[int index]
{
get
{
if (index >= _length) throw new IndexOutOfRangeException();
int byteIndex = index >> 5;
int bitIndex = index & 0x1f;
return ((bits[byteIndex] << bitIndex) & ONE) != 0;
}
set
{
if (index >= _length) throw new IndexOutOfRangeException();
int byteIndex = index >> 5;
int bitIndex = index & 0x1f;
if (value) bits[byteIndex] |= (ONE >> bitIndex);
else bits[byteIndex] &= ~(ONE >> bitIndex);
}
}
#region Interfaces implementation
#region IEnumerable
public IEnumerator GetEnumerator()
{
//for (int i = 0; i < _length; i++) yield return this[i];
return this.ToArray().GetEnumerator();
}
#endregion
#region ICollection
public void CopyTo(Array array, int index)
{
if (array == null) throw new ArgumentNullException("array");
if (index < 0) throw new ArgumentOutOfRangeException("index");
if (array.Rank != 1) throw new ArgumentException("Multidimensional array not supported");
if (array is UInt32[]) Array.Copy(this.bits, 0, array, index, (this.Count + sizeof(UInt32) - 1) / sizeof(UInt32));
else if (array is bool[]) Array.Copy(this.ToArray(), 0, array, index, this.Count);
else throw new ArgumentException("Array type not supported (UInt32[] or bool[] only)");
}
public int Count
{
get { return this._length; }
private set
{
if (value > this._length) Extend(value - this._length);
else this._length = Math.Max(0, value);
}
}
public bool IsSynchronized
{
get { return false; }
}
public object SyncRoot
{
get
{
if (this._syncRoot == null) Interlocked.CompareExchange<object>(ref this._syncRoot, new object(), null);
return _syncRoot;
}
}
#endregion
#region ICloneable
public object Clone()
{
return new BoolArray(this);
}
// Not part of ICloneable, but better - returns a strongly-typed result
public BoolArray Dup()
{
return new BoolArray(this);
}
#endregion
#endregion
#region String Conversions
public override string ToString()
{
return ToBinaryString();
//return ToHexString(" ", " ■ ");
}
public static BoolArray FromHexString(string hex)
{
if (hex == null) throw new ArgumentNullException("hex");
List<bool> bits = new List<bool>();
for (int i = 0; i < hex.Length; i++)
{
int b = byte.Parse(hex[i].ToString(), NumberStyles.HexNumber);
bits.Add((b >> 3) == 1);
bits.Add(((b & 0x7) >> 2) == 1);
bits.Add(((b & 0x3) >> 1) == 1);
bits.Add((b & 0x1) == 1);
}
BoolArray ba = new BoolArray(bits.ToArray());
return ba;
}
public string ToHexString(string bitSep8 = null, string bitSep128 = null)
{
string s = string.Empty;
int b = 0;
bool[] bbits = this.ToArray();
for (int i = 1; i <= bbits.Length; i++)
{
b = (b << 1) | (bbits[i - 1] ? 1 : 0);
if (i % 4 == 0)
{
s = s + string.Format("{0:x}", b);
b = 0;
}
if (i % (8 * 16) == 0)
{
s = s + bitSep128;
}
else if (i % 8 == 0)
{
s = s + bitSep8;
}
}
int ebits = bbits.Length % 4;
if (ebits != 0)
{
b = b << (4 - ebits);
s = s + string.Format("{0:x}", b);
}
return s;
}
public static BoolArray FromBinaryString(string bin, char[] trueChars = null)
{
if (trueChars == null) trueChars = new char[] { '1', 'Y', 'y', 'T', 't' };
if (bin == null) throw new ArgumentNullException("bin");
BoolArray ba = new BoolArray(bin.Length);
for (int i = 0; i < bin.Length; i++) ba[i] = bin[i].In(trueChars);
return ba;
}
public string ToBinaryString(char setChar = '1', char unsetChar = '0')
{
return new string(this.ToArray().Select(v => v ? setChar : unsetChar).ToArray());
}
#endregion
#region Class Methods
public bool[] ToArray()
{
bool[] vbits = new bool[this._length];
for (int i = 0; i < _length; i++) vbits[i] = this[i];
return vbits;
}
public BoolArray Append(ICollection<bool> addBits)
{
int startPos = this._length;
Extend(addBits.Count);
bool[] bitArray = addBits.ToArray();
for (int i = 0; i < bitArray.Length; i++) this[i + startPos] = bitArray[i];
return this;
}
public BoolArray Append(BoolArray addBits)
{
return this.Append(addBits.ToArray());
}
public static BoolArray Concatenate(params BoolArray[] bArrays)
{
return new BoolArray(bArrays.SelectMany(ba => ba.ToArray()).ToArray());
}
private void Extend(int numBits)
{
numBits += this._length;
int reqBytes = RequiredSize(numBits);
if (reqBytes > this.bits.Length)
{
UInt32[] newBits = new UInt32[reqBytes];
this.bits.CopyTo(newBits, 0);
this.bits = newBits;
}
this._length = numBits;
}
public bool Get(int index)
{
return this[index];
}
public BoolArray GetBits(int startBit = 0, int numBits = -1)
{
if (numBits == -1) numBits = bits.Length;
return new BoolArray(this.ToArray().Skip(startBit).Take(numBits).ToArray());
}
public BoolArray Repeat(int numReps)
{
bool[] oBits = this.ToArray();
List<bool> nBits = new List<bool>();
for(int i=0; i<numReps; i++) nBits.AddRange(oBits);
this.InitializeFrom(nBits);
return this;
}
public BoolArray Reverse()
{
int n = this.Count;
for(int i=0; i<n/2; i++)
{
bool b1 = this[i];
this[i] = this[n - i - 1];
this[n - i - 1] = b1;
}
return this;
}
public BoolArray Set(int index, bool v)
{
this[index] = v;
return this;
}
public BoolArray SetAll(bool v)
{
for (int i = 0; i < this.Count; i++) this[i] = v;
return this;
}
public BoolArray SetBits(ICollection<bool> setBits, int destStartBit = 0, int srcStartBit = 0, int numBits = -1, bool allowExtend = false)
{
if (setBits == null) throw new ArgumentNullException("setBits");
if ((destStartBit < 0) || (destStartBit >= this.Count)) throw new ArgumentOutOfRangeException("destStartBit");
if ((srcStartBit < 0) || (srcStartBit >= setBits.Count)) throw new ArgumentOutOfRangeException("srcStartBit");
bool[] sBits;
if (setBits is bool[]) sBits = (bool[])setBits;
else sBits = setBits.ToArray();
if (numBits == -1) numBits = setBits.Count;
if (numBits > (setBits.Count - srcStartBit)) numBits = setBits.Count - srcStartBit;
int diffSize = numBits - (this.Count - destStartBit);
if (diffSize > 0)
{
if (allowExtend) Extend(diffSize);
else numBits = this.Count - destStartBit;
}
for (int i = 0; i < numBits; i++) this[destStartBit + i] = sBits[srcStartBit + i];
return this;
}
public List<BoolArray> SplitEvery(int numBits)
{
int i = 0;
List<BoolArray> bitSplits = new List<BoolArray>();
while (i < this.Count)
{
bitSplits.Add(this.GetBits(i, numBits));
i += numBits;
}
return bitSplits;
}
public byte[] ToBytes(int startBit = 0, int numBits = -1)
{
if (numBits == -1) numBits = this._length - startBit;
BoolArray ba = GetBits(startBit, numBits);
int nb = (numBits + 7) / 8;
byte[] bb = new byte[nb];
for (int i = 0; i < ba.Count; i++)
{
if (!ba[i]) continue;
int bp = 7 - (i % 8);
bb[i / 8] = (byte)((int)bb[i / 8] | (1 << bp));
}
return bb;
}
#endregion
#region Logical Bitwise Operations
public BoolArray BinaryBitwiseOp(Func<bool, bool, bool> op, BoolArray ba, int start = 0)
{
for (int i = 0; i < ba.Count; i++)
{
if (start + i >= this.Count) break;
this[start + i] = op(this[start + i], ba[i]);
}
return this;
}
public BoolArray Xor(BoolArray xor, int start = 0)
{
return BinaryBitwiseOp((a, b) => (a ^ b), xor, start);
}
public BoolArray And(BoolArray and, int start = 0)
{
return BinaryBitwiseOp((a, b) => (a & b), and, start);
}
public BoolArray Or(BoolArray or, int start = 0)
{
return BinaryBitwiseOp((a, b) => (a | b), or, start);
}
public BoolArray Not(int start = 0, int len = -1)
{
for (int i = start; i < this.Count; i++)
{
if (--len == -1) break;
this[i] = !this[i];
}
return this;
}
#endregion
#region Class Operators
public static BoolArray operator +(BoolArray a, BoolArray b)
{
return a.Dup().Append(b);
}
public static BoolArray operator |(BoolArray a, BoolArray b)
{
return a.Dup().Or(b);
}
public static BoolArray operator &(BoolArray a, BoolArray b)
{
return a.Dup().And(b);
}
public static BoolArray operator ^(BoolArray a, BoolArray b)
{
return a.Dup().Xor(b);
}
public static BoolArray operator ~(BoolArray a)
{
return a.Dup().Not();
}
public static BoolArray operator <<(BoolArray a, int shift)
{
return a.Dup().Append(new bool[shift]);
}
public static BoolArray operator >>(BoolArray a, int shift)
{
return new BoolArray(a.ToArray().Take(Math.Max(0, a.Count - shift)).ToArray());
}
public static bool operator ==(BoolArray a, BoolArray b)
{
if (a.Count != b.Count) return false;
for (int i = 0; i < a.Count; i++) if (a[i] != b[i]) return false;
return true;
}
public override bool Equals(object obj)
{
if (!(obj is BoolArray)) return false;
return (this == (BoolArray)obj);
}
public override int GetHashCode()
{
return this.ToHexString().GetHashCode();
}
public static bool operator !=(BoolArray a, BoolArray b)
{
return !(a == b);
}
#endregion
}
}
I had the same issue, but had more than just the one Cardinality method to convert. So, I opted to port the entire BitSet class. Fortunately it was self-contained.
Here is the Gist of the C# port.
I have also added it to the open source BoboBrowse.Net project.
I have also ported the version from Apache Harmony (which is essentially a carbon copy of the JDK) and added it to the general library J2N so it is easy to consume.