private void button1_Click( object sender, EventArgs e)
{
int n = 33 ;
int m = 6 ;
string [] set = new string [n];
for ( int i = 0 ; i < n; i ++ )
{
set [i] = (i).ToString().PadLeft( 2 , ' 0 ' );
}
List < string > result;
GC.Collect();
result = GetCombinationF2( set , m); // n=20 about 44ms, n=40 about 6s
// result = GetCombinationF3(set, m); // n=20 about 16ms n=40 about 2.5s
// result = GetCombinationF4(set, m); // n=20 about 95ms n=40 about 13s
for ( int i = 0 ; i < 10 ; i ++ )
{
this .txtResult.Text += result[i] + " \r\n " ;
}
}
#region 组合算法
#region 组合算法2(非递归方法)
static List < string > GetCombinationF2( string [] strArray, int selectCount)
{
int totalCount = strArray.Length;
int [] currentSelect = new int [selectCount];
int last = selectCount - 1 ;
List < string > output = new List < string > ();
string s;
// 付初始值
for ( int i = 0 ; i < selectCount; i ++ )
currentSelect[i] = i;
while ( true )
{
s = "" ;
// 输出部分,生成的时候从0计数,所以输出的时候+1
for ( int i = 0 ; i < selectCount; i ++ )
{
s += strArray[currentSelect[i]] + " \t " ;
}
output.Add(s);
// 如果不进位
if (currentSelect[last] < totalCount - 1 )
currentSelect[last] ++ ;
else
{
// 进位部分
int position = last;
while (position > 0 && currentSelect[position - 1 ] == currentSelect[position] - 1 )
position -- ;
if (position == 0 )
break ;
currentSelect[position - 1 ] ++ ;
for ( int i = position; i < selectCount; i ++ )
currentSelect[i] = currentSelect[i - 1 ] + 1 ;
}
}
return output;
}
#endregion
#region 组合算法3
static List < string > GetCombinationF3( string [] data, int count)
{
Dictionary < string , int > dic = new Dictionary < string , int > ();
List < string > output = new List < string > ();
for ( int i = 0 ; i < data.Length; i ++ )
{
dic.Add(data[i], i);
}
SelectN(dic, data, count, 1 , ref output);
return output;
}
static void SelectN(Dictionary < string , int > dd, string [] data, int count, int times, ref List < string > output)
{
// 当前字典中的key与原始数据中值大于自身的每个key组合,比如第一轮递归中,01与02-33这些数组合,02与03-33这些数组合。递归五次,即可从33个数中选出6个。
Dictionary < string , int > dic = new Dictionary < string , int > ();
foreach (KeyValuePair < string , int > kv in dd)
{
for ( int i = kv.Value + 1 ; i < data.Length; i ++ )
{
if (times < count - 1 )
{
dic.Add(kv.Key + " \t " + data[i], i);
}
else
{
output.Add(kv.Key + " \t " + data[i]); // 不考虑输出,将此句注释掉
}
}
}
times ++ ;
if (dic.Count > 0 ) SelectN(dic, data, count, times, ref output);
}
#endregion
#region 组合算法4
static List < string > GetCombinationF4( string [] data, int count)
{
List < string > output = new List < string > ();
int len = data.Length;
string start = " 1 " .PadRight(count, ' 1 ' ).PadRight(len, ' 0 ' );
string s;
while (start != string .Empty)
{
s = "" ;
for ( int i = 0 ; i < len; i ++ )
if (start[i] == ' 1 ' ) s += data[i] + " \t " ;
output.Add(s);
start = GetNext(start);
}
return output;
}
static string GetNext( string str)
{
string next = string .Empty;
int pos = str.IndexOf( " 10 " );
if (pos < 0 ) return next;
else if (pos == 0 ) return " 01 " + str.Substring( 2 );
else
{
int len = str.Length;
next = str.Substring( 0 , pos).Replace( " 0 " , "" ).PadRight(pos, ' 0 ' ) + " 01 " ;
if (pos < len - 2 ) next += str.Substring(pos + 2 );
}
return next;
}
#endregion
#endregion