#region
/// <summary>
/// 全排列 递归 考虑重复
/// Peter
/// </summary>
public static String[] Permutation(String s)
{
if (s.Length == 1)
{
String[] res = new String[1];
res[0] = s;
return res;
}
else
{
StringBuilder sbuilder = new StringBuilder();
Char[] cs = s.ToCharArray();
Array.Sort(cs);
s = new String(cs);
Char pre = '0';
for (Int32 i = 0; i < s.Length; i++)
{
if (i == 0)
{
pre = s[i];
sbuilder.Append(String.Join(",", Merge(s[i], Permutation(s.Substring(0, i) + s.Substring(i + 1)))) + ",");
}
else
{
if (s[i] == pre)
{
continue;
}
else
{
sbuilder.Append(String.Join(",", Merge(s[i], Permutation(s.Substring(0, i) + s.Substring(i + 1)))) + ",");
pre = s[i];
}
}
}
return sbuilder.ToString().Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);
}
}
public static String[] Merge(Char c, String[] s)
{
for (Int32 i = 0; i < s.Length; i++)
{
s[i] = c + s[i];
}
return s;
}
#endregion
#region
/// <summary>
/// 全排列 非递归 没有重复元素!
/// Peter
/// 给定已知序列 P = A1A2A3An ( Ai!=Aj , (1<=i<=n , 1<=j<=n, i != j ) )
/// 方法为:
/// 1.从低位到高位(从后向前),找出“不符合趋势”的数字。即找到一个Pi,使P(i) < P(i+1)。
/// 若找不到这样的pi,说明我们已经找到最后一个全排列,可以返回了。
/// 2.在 P(i+1)P(i+2)Pn 中,找到一个P(j),便得 P(j)"刚刚好大于"P(i).
/// ("刚刚好大于"的意思是:在 P(i+1)P(i+2)Pn 中所有大于P(i)的元素构成的集合中最小的元素.)
/// 3.交换 P(i) , P(j) 的位置.注意:此处不改变i和j的值,改变的是P(i)和P(j).
/// 4.交换后, P(1)P(2)P(3)P(n) 并不是准确的后一个排列。因为根据第1步的查找,我们有P(i+1) > P(i+2) > . > Pn
/// 即使进行了Pi和Pj的交换,这仍然是这一部分最大的一个排列。将此排列逆序倒置(变成最小的排列)即为所求的下一个排列.
/// 5.重复步骤1-4,直到步骤1中找不到“不符合趋势”的数字.
/// </summary>
public static List<String> Permutation1(String s)
{
Char[] cs = s.ToCharArray();
Array.Sort(cs);
s = new String(cs);
List<String> list = new List<String>();
list.Add(s);
while (true)
{
s = FindNext(s);
if (s == null)
break;
list.Add(s);
}
return list;
}
public static String FindNext(String cur)
{
Int32 p1, p2;
for (Int32 i = cur.Length - 1; i > 0; i--)
{
if (cur[i - 1] < cur[i])
{
p1 = i - 1;
char min = cur[i];
p2 = i;
for (Int32 j = i; j < cur.Length; j++)
{
if (cur[j] > cur[p1])
{
if (cur[j] < min)
{
min = cur[j];
p2 = j;
}
}
}
Char[] cs = cur.ToCharArray();
char temp = cs[p1];
cs[p1] = cs[p2];
cs[p2] = temp;
Array.Reverse(cs, p1 + 1, cs.Length - p1 - 1);
return new String(cs);
}
}
return null;
}
#endregion
static void Main(string[] args)
{
Program p = new Program();
String str = "abcc";
Int32 start = Environment.TickCount;
String[] res = Program.Permutation(str);
Console.WriteLine("time :" + (Environment.TickCount - start));
Console.WriteLine(res.Length);
foreach (String s in res)
Console.WriteLine(s);
Console.WriteLine("--------------");
start = Environment.TickCount;
List<String> res2 = Program.Permutation1(str);
Console.WriteLine("time :" + (Environment.TickCount - start));
Console.WriteLine(res2.Count);
foreach (String s in res2)
Console.WriteLine(s);
}
转载于:https://www.cnblogs.com/Peter-Zhang/archive/2010/07/27/1786000.html