最近发现论坛上问全组合的问题挺多的,自己之前也在这里问过类似的问题,一直没有找到特别高效的算法。
这两天看到了下面这个帖子,
http://topic.csdn.net/u/20090216/18/9104bda7-6ea3-4899-973c-cb7aae6612d8.html
特意又考虑了一下。终于写出了自己认为效率比较高的算法,拿出来给大家评评看,欢迎大家批评指正: static string[] m_Data = { "A", "B", "C", "D", "E" }; static void Main(string[] args)
{
Dictionary<string, int> dic = new Dictionary<string, int>();
for (int i = 0; i < m_Data.Length; i++)
{
Console.WriteLine(m_Data[i]);//如果不需要打印单元素的组合,将此句注释掉
dic.Add(m_Data[i], i);
}
GetString(dic);
Console.ReadLine();
} static void GetString(Dictionary<string,int> dd)
{
Dictionary<string, int> dic = new Dictionary<string, int>();
foreach (KeyValuePair<string, int> kv in dd)
{
for (int i = kv.Value + 1; i < m_Data.Length; i++)
{
Console.WriteLine(kv.Key + m_Data[i]);
dic.Add(kv.Key + m_Data[i], i);
}
}
if(dic.Count>0) GetString(dic);
}运行结果:
A
B
C
D
E
AB
AC
AD
AE
BC
BD
BE
CD
CE
DE
ABC
ABD
ABE
ACD
ACE
ADE
BCD
BCE
BDE
CDE
ABCD
ABCE
ABDE
ACDE
BCDE
ABCDE
这两天看到了下面这个帖子,
http://topic.csdn.net/u/20090216/18/9104bda7-6ea3-4899-973c-cb7aae6612d8.html
特意又考虑了一下。终于写出了自己认为效率比较高的算法,拿出来给大家评评看,欢迎大家批评指正: static string[] m_Data = { "A", "B", "C", "D", "E" }; static void Main(string[] args)
{
Dictionary<string, int> dic = new Dictionary<string, int>();
for (int i = 0; i < m_Data.Length; i++)
{
Console.WriteLine(m_Data[i]);//如果不需要打印单元素的组合,将此句注释掉
dic.Add(m_Data[i], i);
}
GetString(dic);
Console.ReadLine();
} static void GetString(Dictionary<string,int> dd)
{
Dictionary<string, int> dic = new Dictionary<string, int>();
foreach (KeyValuePair<string, int> kv in dd)
{
for (int i = kv.Value + 1; i < m_Data.Length; i++)
{
Console.WriteLine(kv.Key + m_Data[i]);
dic.Add(kv.Key + m_Data[i], i);
}
}
if(dic.Count>0) GetString(dic);
}运行结果:
A
B
C
D
E
AB
AC
AD
AE
BC
BD
BE
CD
CE
DE
ABC
ABD
ABE
ACD
ACE
ADE
BCD
BCE
BDE
CDE
ABCD
ABCE
ABDE
ACDE
BCDE
ABCDE
解决方案 »
- MEF有多个Export的情况,用foreach出错了
- c#基础问题,请求帮忙!
- C#编程 高效的将文本文件中的数据写入SQL SERVER表中
- xml中动态添加节点的问题
- win中打开的模式窗体的值的回传的问题?
- 百分求助:莫名httpwebrequest超时问题,已经有好几个人问了同样问题,但没见到解决方法
- 我想从一个文件夹 把.wmv的文件的1/2 COPY到别的文件夹中.(这1/2也能看),怎么实现呀?
- 请问使用C#呼叫SharpZipLib如何撰写档案的压缩和解压缩程序(包含中文文件名)
- 关于.JPEG等格式转化为.gif文件格式的问题??
- C#做的桌面程序是怎样实现数据传输的?
- 数据只能比较一个或一个,之后就没反应了,是什么原因?
- 如何隐藏进程?有兴趣的进来看看
像这种String为Key的可以使用System.Collections.Specialized.StringDictionary
{
string[] arr = new[] { "A", "B", "C", "D", "E" };
GetCombination(arr);
} static void GetCombination(string[] nums)
{
double count = Math.Pow(2, nums.Length);
for (int i = 1; i <= count - 1; i++)
{
string str = Convert.ToString(i, 2).PadLeft(nums.Length, '0');
for (int j = 0; j < str.Length; j++)
{
if (str[j] == '1')
{
Console.Write(nums[j]);
}
}
Console.WriteLine();
}
}
/*
输出:
E
D
DE
C
CE
CD
CDE
B
BE
BD
BDE
BC
BCE
BCD
BCDE
A
AE
AD
ADE
AC
ACE
ACD
ACDE
AB
ABE
ABD
ABDE
ABC
ABCE
ABCD
ABCDE
*/
假如当kv的值为<"BC",2>,那么执行下面的for循环, for (int i = kv.Value + 1; i < m_Data.Length; i++)
{
Console.WriteLine(kv.Key + m_Data[i]);
dic.Add(kv.Key + m_Data[i], i);
}
就可以得到:
<"BCD",3>和<"BCE",4>,将这两个值添加到dic中
然后再执行递归。
不知道这样说明白了没有?
using System;
using System.Collections.Generic;
namespace Test
{
class Program
{
static void Main(string[] args)
{
string[] m_Data = { "A", "B", "C", "D", "E" };
List<string> list = new List<string>();
List<string> temp = new List<string>();
List<string> result = new List<string>();
int n = m_Data.Length;
string t;
string sEnd = m_Data[n-1];
int i = 0;
while (i<5)
{
t = m_Data[i];
temp.Add(t);
foreach (string s in list)
{
result.Add(t + s);
temp.Add(t + s);
}
list.AddRange(temp);
temp.Clear();
i++;
}
foreach (string s in result)
{
Console.WriteLine(s);
}
}
}
}
输出:
BA
CA
CB
CBA
DA
DB
DBA
DC
DCA
DCB
DCBA
EA
EB
EBA
EC
ECA
ECB
ECBA
ED
EDA
EDB
EDBA
EDC
EDCA
EDCB
EDCBA
// 算法说明:当n大于2时,n个数的全组合一共有(2^n)-1种。
// 当对n个元素进行全组合的时候,可以用一个n位的二进制数表示取法。
// 1表示在该位取,0表示不取。例如,对ABC三个元素进行全组合,
// 100表示取A,010表示取B,001表示取C,101表示取AC
// 110表示取AB,011表示取BC,111表示取ABC
// 注意到表示取法的二进制数其实就是从1到7的十进制数
// 推广到对n个元素进行全排列,取法就是从1到2^n-1的所有二进制形式
// 要取得2^n,只需将0xFFFFFFFF左移32-n位,再右移回来就可以了。#include <iostream>
using namespace std;
void main()
{
string str[] = { "A", "B", "C", "D", "E" };
unsigned int nCnt = sizeof( str ) / sizeof( str[0] );
int nBit = ( ( 0xFFFFFFFFU << ( 32 - nCnt ) ) >> ( 32 - nCnt ) );
for ( int i = 1; i <= nBit; ++i ) {
for ( unsigned int j = 0; j < nCnt; ++j )
if ( ( i << ( 31 - j ) ) >> 31 ) cout << str[j];
cout << '\n';
}
return;
}
#include <iostream>
void main( void )
{
string str[] = { "A", "B", "C", "D", "E" };
unsigned int nCnt = sizeof( str ) / sizeof( str[0] );
int nBit = ( ( 0xFFFFFFFFU << ( 32 - nCnt ) ) >> ( 32 - nCnt ) );
for ( int i = 1; i <= nBit; ++i ) {
for ( unsigned int j = 0; j < nCnt; ++j )
if ( ( i << ( 31 - j ) ) >> 31 ) std::cout << str[j];
std::cout << '\n';
}
}