排列组合是高中是学到的 知识,理论上非常清楚。但怎样使用代码实现,却一直没有尝试过,近段时间因为项目须要,写一个组合的算法。想不到却花费了不少时间。
需求非常easy,就是典型的组合应用。
比如输入:C0,C1,C2,C3,C4,输出C0,C1,C2,C3,C4的全部组合。
因为输入数据的个数不确定。自然不能使用一般的循环,仅仅能使用递归加循环。
经过不断的实验的和測试,发现有两种实现方法。
1依据组合长度的输出,比如对于输入C0,C1,C2,C3,C4的五个元素,先输出,一个元素的全部组合,再输出两个元素的全部组合,一次类推,直到全部元素的组合都输出完毕。
详细实现代码:
public static void CreatSumData2(List<string> columnNameList)
{
string res = "";
// 一个元素
for (int i = 0; i < columnNameList.Count; i++)//
{
string name = columnNameList[i];
List<string> listContion = new List<string>();
listContion.Add(name);
res += OutPutData(listContion);
listContion.Clear();
}
//两个以上元素
int length = 2;
int max = columnNameList.Count;//组合的最大元素个数
while (length <= max)//一直循环到全部元素的组合,每一次循环,处理某一个长度的组合
{
for (int i = 0; i <= columnNameList.Count - length + 1; i++)//
{
string name = columnNameList[i];
int currentlLvel = i + 1;
List<string> hasAddNameList = new List<string>();//保存已加入的元素
hasAddNameList.Add(name);
res += addOneContion(hasAddNameList, columnNameList, currentlLvel, length);
hasAddNameList.Clear();//清空元素
}
length++;
}
WrieData(res);
}
/// <summary>
/// 加入一个元素
/// </summary>
/// <param name="hasAddNameList">已加入的元素</param>
/// <param name="columnNameList">全部可能的元素</param>
/// <param name="currentlLvel"></param>
/// <param name="currentMaxLength">加入的元素的最大个数</param>
/// <returns></returns>
private static string addOneContion(List<string> hasAddNameList, List<string> columnNameList, int currentlLvel, int currentMaxLength)
{
string res = "";
bool hasAddOutNames = false;
int currentlLvelInner = currentlLvel;
if (hasAddNameList.Count == currentMaxLength)
{
res += OutPutData(hasAddNameList);
hasAddNameList.Clear();
return res;
}
List<string> hasAddNameListInner = new List<string>();
for (int i = currentlLvelInner; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
currentlLvelInner++;
if (!hasAddOutNames)
{
hasAddNameListInner.AddRange(hasAddNameList);
hasAddOutNames = true;
}
hasAddNameListInner.Add(colunmname);
if (hasAddNameListInner.Count == currentMaxLength)
{
res += OutPutData(hasAddNameListInner);
hasAddNameListInner.Clear();
hasAddOutNames = false;
}
else
{
res += addOneContion(hasAddNameListInner, columnNameList, currentlLvelInner, currentMaxLength);
hasAddNameListInner.Clear();
hasAddOutNames = false;
}
}
return res;
}
改进版:
public static void CreatSumData22(List<string> columnNameList)
{
string res = "";
// 一个元素
for (int i = 0; i < columnNameList.Count; i++)//
{
string name = columnNameList[i];
List<string> listContion = new List<string>();
res += OutPutData(listContion, name);
}
//两个以上元素
int length = 2;
int max = columnNameList.Count;//组合的最大元素个数
while (length <= max)//一直循环到全部元素的组合,每一次循环,处理某一个长度的组合
{
for (int i = 0; i <= columnNameList.Count - length + 1; i++)//
{
string name = columnNameList[i];
List<string> hasAddNameList = new List<string>();//保存已加入的元素
res += addOneContion(hasAddNameList, columnNameList, i + 1, length, name);
}
length++;
}
WrieData(res);
}
/// <summary>
/// 加入一个元素
/// </summary>
/// <param name="hasAddNameList">已加入的元素</param>
/// <param name="columnNameList">全部可能的元素</param>
/// <param name="startIndex"></param>
/// <param name="currentMaxLength">加入的元素的最大个数</param>
/// <returns></returns>
private static string addOneContion(List<string> hasAddNameList, List<string> columnNameList, int startIndex, int currentMaxLength,string parentName)
{
string res = "";
List<string> hasAddNameListInner = new List<string>();
hasAddNameListInner.AddRange(hasAddNameList);
hasAddNameListInner.Add(parentName);
for (int i = startIndex; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
if (hasAddNameListInner.Count + 1 == currentMaxLength)
{
res += OutPutData(hasAddNameListInner, colunmname);
}
else
{
res += addOneContion(hasAddNameListInner, columnNameList, i+1, currentMaxLength, colunmname);
}
}
return res;
}
private static string OutPutData(List<string> listold,string name)
{
List<string> listoldinner = new List<string>();
listoldinner.AddRange(listold);
listoldinner.Add(name);
return OutPutData(listoldinner);
}
2 依据元素的输出。比如对于输入C0,C1,C2,C3,C4的五个元素。先输出包括C0这个元素的全部组合,再输出包括C1但不包括C0的全部组合。一次类推。直到全部元素的组合都输出完毕。
详细实现代码
public static void CreatSumData(List<string> columnNameList)
{
string res = "";
List<string> hasAddNameList = new List<string>();
for (int i = 0; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
int currentlLvel = i;
currentlLvel++;
hasAddNameList.Add(colunmname);
res += OutPutData(hasAddNameList);
res += CreatNextLevelData(hasAddNameList, columnNameList, currentlLvel);
hasAddNameList.Clear();
}
WrieData(res);
}
private static string CreatNextLevelData(List<string> hasAddNameList, List<string> columnNameList, int currentlLvel)
{
string res = "";
List<string> hasAddNameListInner = new List<string>();
bool hasAddOutNames = false;
int currentlLvelInner = currentlLvel;
for (int i = currentlLvelInner; i < columnNameList.Count; i++)//
{
if (!hasAddOutNames) {
hasAddNameListInner.AddRange(hasAddNameList);
}
string colunmname = columnNameList[i];
currentlLvelInner++;
hasAddNameListInner.Add(colunmname);
res += OutPutData(hasAddNameListInner);
res += CreatNextLevelData(hasAddNameListInner, columnNameList, currentlLvelInner);
hasAddOutNames = false;
hasAddNameListInner.Clear();
}
return res;
}
改进版
public static void CreatSumData1(List<string> columnNameList)
{
string res = "";
List<string> hasAddNameList = new List<string>();
for (int i = 0; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
res += OutPutData(hasAddNameList, colunmname);
res += CreatNextLevelData(hasAddNameList, columnNameList, i+1, colunmname);
}
WrieData(res);
}
private static string CreatNextLevelData(List<string> hasAddNameList, List<string> columnNameList, int startIndex, string parentcolumn)
{
string res = "";
List<string> hasAddNameListInner = new List<string>();
hasAddNameListInner.AddRange(hasAddNameList);
hasAddNameListInner.Add(parentcolumn);
for (int i = startIndex; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
res += OutPutData(hasAddNameListInner, colunmname);
res += CreatNextLevelData(hasAddNameListInner, columnNameList, i + 1, colunmname);
}
return res;
}
完整的代码:
#region 依据组合长度的输出
public static void CreatSumData2(List<string> columnNameList)
{
string res = "";
// 一个元素
for (int i = 0; i < columnNameList.Count; i++)//
{
string name = columnNameList[i];
List<string> listContion = new List<string>();
listContion.Add(name);
res += OutPutData(listContion);
listContion.Clear();
}
//两个以上元素
int length = 2;
int max = columnNameList.Count;//组合的最大元素个数
while (length <= max)//一直循环到全部元素的组合,每一次循环,处理某一个长度的组合
{
for (int i = 0; i <= columnNameList.Count - length + 1; i++)//
{
string name = columnNameList[i];
int currentlLvel = i + 1;
List<string> hasAddNameList = new List<string>();//保存已加入的元素
hasAddNameList.Add(name);
res += addOneContion(hasAddNameList, columnNameList, currentlLvel, length);
hasAddNameList.Clear();//清空元素
}
length++;
}
WrieData(res);
}
public static void CreatSumData22(List<string> columnNameList)
{
string res = "";
// 一个元素
for (int i = 0; i < columnNameList.Count; i++)//
{
string name = columnNameList[i];
List<string> listContion = new List<string>();
res += OutPutData(listContion, name);
}
//两个以上元素
int length = 2;
int max = columnNameList.Count;//组合的最大元素个数
while (length <= max)//一直循环到全部元素的组合,每一次循环,处理某一个长度的组合
{
for (int i = 0; i <= columnNameList.Count - length + 1; i++)//
{
string name = columnNameList[i];
List<string> hasAddNameList = new List<string>();//保存已加入的元素
res += addOneContion(hasAddNameList, columnNameList, i + 1, length, name);
}
length++;
}
WrieData(res);
}
/// <summary>
/// 加入一个元素
/// </summary>
/// <param name="hasAddNameList">已加入的元素</param>
/// <param name="columnNameList">全部可能的元素</param>
/// <param name="startIndex"></param>
/// <param name="currentMaxLength">加入的元素的最大个数</param>
/// <returns></returns>
private static string addOneContion(List<string> hasAddNameList, List<string> columnNameList, int startIndex, int currentMaxLength,string parentName)
{
string res = "";
List<string> hasAddNameListInner = new List<string>();
hasAddNameListInner.AddRange(hasAddNameList);
hasAddNameListInner.Add(parentName);
for (int i = startIndex; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
if (hasAddNameListInner.Count + 1 == currentMaxLength)
{
res += OutPutData(hasAddNameListInner, colunmname);
}
else
{
res += addOneContion(hasAddNameListInner, columnNameList, i+1, currentMaxLength, colunmname);
}
}
return res;
}
private static string OutPutData(List<string> listold,string name)
{
List<string> listoldinner = new List<string>();
listoldinner.AddRange(listold);
listoldinner.Add(name);
return OutPutData(listoldinner);
}
/// <summary>
/// 加入一个元素
/// </summary>
/// <param name="hasAddNameList">已加入的元素</param>
/// <param name="columnNameList">全部可能的元素</param>
/// <param name="currentlLvel"></param>
/// <param name="currentMaxLength">加入的元素的最大个数</param>
/// <returns></returns>
private static string addOneContion(List<string> hasAddNameList, List<string> columnNameList, int currentlLvel, int currentMaxLength)
{
string res = "";
bool hasAddOutNames = false;
int currentlLvelInner = currentlLvel;
if (hasAddNameList.Count == currentMaxLength)
{
res += OutPutData(hasAddNameList);
hasAddNameList.Clear();
return res;
}
List<string> hasAddNameListInner = new List<string>();
for (int i = currentlLvelInner; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
currentlLvelInner++;
if (!hasAddOutNames)
{
hasAddNameListInner.AddRange(hasAddNameList);
hasAddOutNames = true;
}
hasAddNameListInner.Add(colunmname);
if (hasAddNameListInner.Count == currentMaxLength)
{
res += OutPutData(hasAddNameListInner);
hasAddNameListInner.Clear();
hasAddOutNames = false;
}
else
{
res += addOneContion(hasAddNameListInner, columnNameList, currentlLvelInner, currentMaxLength);
hasAddNameListInner.Clear();
hasAddOutNames = false;
}
}
return res;
}
#endregion
#region 依据列输出
public static void CreatSumData(List<string> columnNameList)
{
string res = "";
List<string> hasAddNameList = new List<string>();
for (int i = 0; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
int currentlLvel = i;
currentlLvel++;
hasAddNameList.Add(colunmname);
res += OutPutData(hasAddNameList);
res += CreatNextLevelData(hasAddNameList, columnNameList, currentlLvel);
hasAddNameList.Clear();
}
WrieData(res);
}
public static void CreatSumData1(List<string> columnNameList)
{
string res = "";
List<string> hasAddNameList = new List<string>();
for (int i = 0; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
res += OutPutData(hasAddNameList, colunmname);
res += CreatNextLevelData(hasAddNameList, columnNameList, i+1, colunmname);
}
WrieData(res);
}
private static string CreatNextLevelData(List<string> hasAddNameList, List<string> columnNameList, int startIndex, string parentcolumn)
{
string res = "";
List<string> hasAddNameListInner = new List<string>();
hasAddNameListInner.AddRange(hasAddNameList);
hasAddNameListInner.Add(parentcolumn);
for (int i = startIndex; i < columnNameList.Count; i++)//
{
string colunmname = columnNameList[i];
res += OutPutData(hasAddNameListInner, colunmname);
res += CreatNextLevelData(hasAddNameListInner, columnNameList, i + 1, colunmname);
}
return res;
}
private static string CreatNextLevelData(List<string> hasAddNameList, List<string> columnNameList, int currentlLvel)
{
string res = "";
List<string> hasAddNameListInner = new List<string>();
bool hasAddOutNames = false;
int currentlLvelInner = currentlLvel;
for (int i = currentlLvelInner; i < columnNameList.Count; i++)//
{
if (!hasAddOutNames) {
hasAddNameListInner.AddRange(hasAddNameList);
}
string colunmname = columnNameList[i];
currentlLvelInner++;
hasAddNameListInner.Add(colunmname);
res += OutPutData(hasAddNameListInner);
res += CreatNextLevelData(hasAddNameListInner, columnNameList, currentlLvelInner);
hasAddOutNames = false;
hasAddNameListInner.Clear();
}
return res;
}
#endregion
private static string OutPutData(List<string> listold)
{
string text = "";
for (int i = 0; i < listold.Count; i++)
{
string item = listold[i];
text += "[\"" + item + "\"]";
}
return text + "\r\n";
}
private static void WrieData(string text)
{
string file = "ZuheTestout.js";
StreamWriter sr = new StreamWriter(file);
sr.WriteLine(text);
sr.Close();
}
浙公网安备 33010602011771号