编程访谈中的一项常见任务(不是根据我的访谈经验)是采用字符串或整数并列出每种可能的排列。
是否有一个例子说明如何做到这一点以及解决这个问题背后的逻辑?
我已经看过一些代码片段,但它们没有得到很好的评论/解释,因此难以理解。
答案 0 :(得分:143)
首先:它当然闻起来像递归!
既然你也想知道原理,我尽力解释它的人类语言。我认为大多数时候递归很容易。你只需要掌握两个步骤:
人类语言:
简而言之:
1. 1元素的排列是一个元素 2.一组元素的排列是每个元素的列表,与其他元素的每个排列连接。
<强> 实施例 强>
如果该集只有一个元素 - &gt;
归还它。
烫发(a) - &gt;一个强>如果集合有两个字符:for 其中的每个元素:返回 元素,与...的排列 其余的元素添加如下:
烫发(ab) - &gt;
a +烫发(b) - &gt; ab
b +烫发(a) - &gt; ba
此外:对于集合中的每个字符:返回一个字符,与&gt;的结合连接;其余的
烫发(abc) - &gt;
a + perm(bc) - &gt; abc , acb
b + perm(ac) - &gt; bac , bca
c + perm(ab) - &gt; cab , cba
烫发(abc ... z) - &gt;
a +烫发(...),b +烫发(....)
....
我在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#强>
好的,还有一些更精细的(因为它被标记为c#),来自http://radio.weblogs.com/0111551/stories/2002/10/14/permutations.html: 相当冗长,但无论如何我决定复制它,所以帖子不依赖于原文。
该函数接受一串字符,并记下该精确字符串的每个可能的排列,例如,如果提供了“ABC”,则应该溢出:
ABC,ACB,BAC,BCA,CAB,CBA。
代码:
class Program
{
private static void Swap(ref char a, ref char b)
{
if (a == b) return;
a ^= b;
b ^= a;
a ^= b;
}
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);
}
}
答案 1 :(得分:71)
如果允许使用LINQ,则只需两行代码。请参阅我的回答here。
修改强>
这是我的通用函数,它可以从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 }));
}
示例:
IEnumerable<IEnumerable<int>> result =
GetPermutations(Enumerable.Range(1, 3), 3);
输出 - 整数列表列表:
{1,2,3} {1,3,2} {2,1,3} {2,3,1} {3,1,2} {3,2,1}
由于此函数使用LINQ,因此它需要.net 3.5或更高版本。
答案 2 :(得分:33)
我在这里找到了解决方案。它是用Java编写的,但我已将其转换为C#。我希望它会对你有所帮助。
这是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;
}
答案 3 :(得分:19)
递归不是必需的,here是有关此解决方案的良好信息。
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();
我已经使用了这个算法多年,它有 O(N) 时间和空间复杂度来计算每个排列即可。
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;
}
}
答案 4 :(得分:11)
void permute (char *str, int ptr) {
int i, len;
len = strlen(str);
if (ptr == len) {
printf ("%s\n", str);
return;
}
for (i = ptr ; i < len ; i++) {
swap (&str[ptr], &str[i]);
permute (str, ptr + 1);
swap (&str[ptr], &str[i]);
}
}
您可以编写交换功能来交换字符 这将被称为permute(string,0);
答案 5 :(得分:9)
首先,集合具有排列,而不是字符串或整数,所以我假设你的意思是“字符串中的字符集。”
请注意,一组大小为n的n!正排列。
以下伪代码(来自维基百科),调用k = 1 ... n!将给出所有排列:
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;
}
这是等效的Python代码(对于基于0的数组索引):
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
答案 6 :(得分:7)
C#中稍微修改过的版本,可以在任何类型的数组中产生所需的排列。
// 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;
}
}
答案 7 :(得分:6)
我喜欢 FBryant87 方法,因为它很简单。不幸的是,它确实像许多其他“解决方案”不提供所有排列或例如如果它包含多次相同的数字,则为整数。以656123为例。这一行:
var tail = chars.Except(new List<char>(){c});
使用Except将导致所有出现被删除,即当c = 6时,两个数字被移除并且我们留下例如5123.由于我尝试的解决方案都没有解决这个问题,我决定尝试用 FBryant87 的代码作为基础解决它。这就是我想出的:
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;
}
我只是使用.Remove和.IndexOf删除第一个找到的事件。似乎至少可以按照我的用法工作。我相信它可以变得更聪明。
有一点需要注意:结果列表可能包含重复项,因此请确保您返回方法,例如改为使用HashSet或在返回后使用您喜欢的任何方法删除重复项。
答案 8 :(得分:5)
这是一个纯函数的F#实现:
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 }
通过更改交换以利用CLR数组的可变特性可以大大提高性能,但是这种实现对于源数组是线程安全的,并且在某些情况下可能是合乎需要的。 此外,对于具有16个以上元素的数组,int必须替换为具有更大/任意精度的类型,因为因子17会导致int32溢出。
答案 9 :(得分:5)
这是一篇很好的文章,涵盖了三种用于查找所有排列的算法,包括一种用于查找下一种排列的算法。
http://www.cut-the-knot.org/do_you_know/AllPerm.shtml
C ++和Python分别有内置的next_permutation和itertools.permutations函数。
答案 10 :(得分:5)
这是c#中使用递归的简单解决方案,
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)));
}
}
}
答案 11 :(得分:4)
这是一个易于理解的字符串和整数作为输入的permutaion函数。使用此,您甚至可以设置输出长度(在正常情况下,它等于输入长度)
<强> 字符串 强>
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);
}
和 整数 只需更改调用方法, MakePermutations()保持不变:
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>();
}
示例1:GetAllPermutations(“abc”,3); “abc”“acb”“bac”“bca”“cab”“cba”
示例2:GetAllPermutations(“abcd”,2); “ab”“ac”“ad”“ba”“bc”“bd”“ca”“cb”“cd”“da”“db”“dc”
示例3:GetAllPermutations(486,2); 48 46 84 86 64 68
答案 12 :(得分:3)
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]);
}
}
}
答案 13 :(得分:2)
以下是我对排列的实现。不要介意变量名称,因为我这样做是为了好玩:)
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;
}
}
答案 14 :(得分:2)
这是打印所有permutaion的功能。 该函数实现了彼得的逻辑解释。
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();
}
答案 15 :(得分:2)
这是我写的一个高级示例,其中说明了Peter给出的人类语言解释:
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;
}
答案 16 :(得分:1)
如果性能和内存是一个问题,我建议这个非常有效的实现。根据{{3}},它应该是最快的。希望它能满足您的需求:-)!
正如将其与10的Linq实现进行比较! (包括代码):
Linq:50051毫秒的36288000项
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
# both 'x-test' and 'x-test2' are sent
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
答案 17 :(得分:1)
列出字符串的排列。重复字符时避免重复:
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);
}
}
答案 18 :(得分:1)
这是我在JavaScript(NodeJS)中的解决方案。主要思想是我们一次取一个元素,从字符串中“删除它”,改变其余字符,并在前面插入元素。
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;
以下是测试:
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);
})
})
})
答案 19 :(得分:1)
这是我能想到的最简单的解决方案:
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
distribute
函数采用新元素e
和n
- 元素列表,并返回n+1
个列表的列表,每个列表都插入了e
在另一个地方。例如,在列表10
中的四个可能位置中的每一个位置插入[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]]
permute
函数依次折叠每个元素,然后分布到目前为止累积的排列,最终导致所有排列。例如,列表[1;2;3]
的6个排列:
> 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]]
将fold
更改为scan
以保留中间累加器,可以了解每次如何生成排列的排列:
> 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]]]
答案 20 :(得分:0)
我希望这足够了:
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;
}
输出:
cat
cta
act
atc
tca
tac
答案 21 :(得分:0)
c#版本
FunctionalPermutations
应该是这个
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)));
}
答案 22 :(得分:0)
在@Peter解决方案的基础上,这是一个声明适用于任何Permutations()
的简单LINQ样式IEnumerable<T>
扩展方法的版本。
用法(以字符串字符为例):
foreach (var permutation in "abc".Permutations())
{
Console.WriteLine(string.Join(", ", permutation));
}
输出:
a, b, c
a, c, b
b, a, c
b, c, a
c, b, a
c, a, b
或在其他任何收集类型上:
foreach (var permutation in (new[] { "Apples", "Oranges", "Pears"}).Permutations())
{
Console.WriteLine(string.Join(", ", permutation));
}
输出:
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]);
}
}
}
答案 23 :(得分:0)
//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);
答案 24 :(得分:0)
这是另一个提到的算法的实现。
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();
}
}
答案 25 :(得分:0)
这是我的解决方案,我很容易理解
public class FrameCreation extends JFrame{
static Vector<BallCreate> ballObjects = new Vector<BallCreate>();
static Timer timer;
Point m1;
Point m2;
static JFrame frame1;
static mouseHandler mouse;
public static void main(String args[]){
FrameCreation frame = new FrameCreation();
frame1 = new JFrame("Phyiscs Test");
frame1.setVisible(true);
frame1.setSize(520,530);
frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
mouse = frame.new mouseHandler();
frame1.addMouseListener(mouse);
}
public class mouseHandler extends JPanel implements MouseListener{
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
m1 = e.getPoint();
System.out.println("Mouse pressed");
}
@Override
public void mouseReleased(MouseEvent e) {
m2 = e.getPoint();
Thread queryThread = new Thread(){
double vX = m2.getX() - m1.getX();
double vY = m2.getY() - m1.getY();
public void run(){
createBall(m1.getX(),m1.getY(),vX,vY);
}
};
queryThread.start();
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
public void createBall(double posX, double posY, double vX, double vY){
BallCreate newBall = new BallCreate(posX,posY,50,vX,vY);
ballObjects.add(newBall);
frame1.add(newBall);
frame1.revalidate();
newBall.repaint();
}
}
答案 26 :(得分:0)
这是一个简单的C#答案。
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;
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
答案 27 :(得分:0)
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);
}
}
答案 28 :(得分:0)
这是一个以递归方式打印所有排列的函数。
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;
}
答案 29 :(得分:-1)
/// <summary>
/// Print All the Permutations.
/// </summary>
/// <param name="inputStr">input string</param>
/// <param name="strLength">length of the string</param>
/// <param name="outputStr">output string</param>
private void PrintAllPermutations(string inputStr, int strLength,string outputStr, int NumberOfChars)
{
//Means you have completed a permutation.
if (outputStr.Length == NumberOfChars)
{
Console.WriteLine(outputStr);
return;
}
//For loop is used to print permutations starting with every character. first print all the permutations starting with a,then b, etc.
for(int i=0 ; i< strLength; i++)
{
// Recursive call : for a string abc = a + perm(bc). b+ perm(ac) etc.
PrintAllPermutations(inputStr.Remove(i, 1), strLength - 1, outputStr + inputStr.Substring(i, 1), 4);
}
}