排列组合是高中是学到的 知识,理论上很清楚,但如何使用代码实现,却一直没有尝试过,近段时间由于项目需要,写一个排列的算法,想不到却花费了不少时间。
需求很简单,就是典型的排列应用。
例如输入:C0,C1,C2,C3,C4,输出C0,C1,C2,C3,C4的所有排列。
实现代码:
/// <summary>
/// 输出所有排列的数据
/// </summary>
/// <param name="columns">输入的排列的所有元素</param>
/// <param name="columnsContain">输出元素列表,已添加的元素</param>
/// <param name="key"></param>
/// <returns></returns>
private static string CreateAllSequenceData(List<string> columns, List<string> columnsContain, string key)
{
StringBuilder strs = new StringBuilder();
List<string> columnsContaininer = new List<string>();
bool hasAddParentcolumns = false;//是否已添加上层循环传入的元素
for (int i = 0; i < columns.Count; i++)
{
string item = columns[i];
if (!hasAddParentcolumns)
{
columnsContaininer.AddRange(columnsContain);
hasAddParentcolumns = true;
}
if (columnsContaininer.Count == columns.Count)//所有元素已添加,输出排列
{
string value = GetSequenceKey(columnsContaininer);
strs.AppendLine(key + ":" + value);
break;
}
if (!columnsContaininer.Contains(item))//当前元素还没有添加到输出元素列表中
{
columnsContaininer.Add(item);
if (columnsContaininer.Count == columns.Count)//所有元素已添加,输出排列
{
string value = GetSequenceKey(columnsContaininer);
strs.AppendLine(key + ":" + value);
break;
}
else//还有元素没有添加,递归调用
{
strs.Append(CreateAllSequenceData(columns, columnsContaininer, key));
}
columnsContaininer.Clear();//情况内部循环递归调用添加的元素
hasAddParentcolumns = false;
}
}
return strs.ToString();
}
private static string GetSequenceKey(List<string> columns)
{
StringBuilder strs = new StringBuilder();
for (int i = 0; i < columns.Count; i++)
{
strs.Append(columns[i] + "_");
}
return strs.ToString();
}
//生成所有排列
public static string CreateAllGroupingData(List<string> columns)
{
StringBuilder strs = new StringBuilder();
string key = GetSequenceKey(columns);
List<string> columnsContain = new List<string>();
strs.Append(CreateAllSequenceData(columns, columnsContain, key));
return strs.ToString();
}
/// <summary>
/// 测试代码
/// </summary>
public static void Test()
{
List<string> columns = new List<string>();
columns.Add("c0");
columns.Add("c1");
columns.Add("c2");
columns.Add("c3");
string text = CreateAllGroupingData(columns);
WrieData(text);
}
private static void WrieData(string text)
{
string file = "ZuheTestout.js";
StreamWriter sr = new StreamWriter(file);
sr.WriteLine(text);
sr.Close();
}
第二种算法:
private static string CreateAllSequenceData2(List<string> columns, List<string> columnsContain, string key,int maxlength)
{
StringBuilder strs = new StringBuilder();
List<string> columnsContaininer = new List<string>();
List<string> InnerColumns = GetInnerColumns(columns, columnsContain);
bool hasAddParentcolumns = false;//是否已添加上层循环传入的元素
for (int i = 0; i < InnerColumns.Count; i++)
{
string item = InnerColumns[i];
if (!hasAddParentcolumns)
{
columnsContaininer.AddRange(columnsContain);
hasAddParentcolumns = true;
}
columnsContaininer.Add(item);
if (columnsContaininer.Count == maxlength)//所有元素已添加,输出排列
{
string value = GetSequenceKey(columnsContaininer);
strs.AppendLine(key + ":" + value);
return strs.ToString();
}
else//还有元素没有添加,递归调用
{
strs.Append(CreateAllSequenceData2(InnerColumns, columnsContaininer, key, maxlength));
columnsContaininer.Clear();//情况内部循环递归调用添加的元素
hasAddParentcolumns = false;
}
}
return strs.ToString();
}
private static List<string> GetInnerColumns(List<string> columnsAll, List<string> columnsContain)
{
List<string> InnerColumns = new List<string>();
for (int i = 0; i < columnsAll.Count;i++ )
{
string item = columnsAll[i];
if (!columnsContain.Contains(item)) {
InnerColumns.Add(item);
}
}
return InnerColumns;
} //生成所有组合
public static string CreateAllGroupingData(List<string> columns)
{
StringBuilder strs = new StringBuilder();
string key = GetSequenceKey(columns);
List<string> columnsContain = new List<string>();
strs.Append(CreateAllSequenceData2(columns, columnsContain, key, columns.Count));
// strs.Append(CreateAllSequenceData2(columns, columnsContain, key, columns.Count, 0, ""));
return strs.ToString();
}
第三种
private static string CreateAllSequenceData3(List<string> columns, List<string> columnsContain, string key, int maxlength,int columnsContainlength, string parentcolumn)
{
StringBuilder strs = new StringBuilder();
List<string> columnsContaininer = new List<string>();
columnsContaininer.AddRange(columnsContain);
columnsContaininer.Add(parentcolumn);
List<string> InnerColumns = GetInnerColumns(columns, columnsContaininer);
for (int i = 0; i < InnerColumns.Count; i++)
{
string item = InnerColumns[i];
if (columnsContainlength + 1 == maxlength)//所有元素已添加,输出排列
{
columnsContaininer.Add(item);
string value = GetSequenceKey(columnsContaininer);
strs.AppendLine(key + ":" + value);
return strs.ToString();
}
else//还有元素没有添加,递归调用
{
strs.Append(CreateAllSequenceData3(InnerColumns, columnsContaininer, key, maxlength, columnsContainlength + 1, item));
}
}
return strs.ToString();
}
//生成所有组合
public static string CreateAllGroupingData(List<string> columns)
{
StringBuilder strs = new StringBuilder();
string key = GetSequenceKey(columns);
List<string> columnsContain = new List<string>();
// strs.Append(CreateAllSequenceData2(columns, columnsContain, key, columns.Count));
strs.Append(CreateAllSequenceData3(columns, columnsContain, key, columns.Count, 0, ""));
return strs.ToString();
}