穷举一个数组的所有可能的组合

一枚大帅哥 2014-08-14 05:51:04
求大神解决问题
有一个字符串string str="a,c,d,b"
我要列出所有的组合
一位的有:a,b,c,d
2位的有:ab,ac,ad,bc,bd,cd
3位的有:abc,abd,acd,bcd
四位的有:abcd
我这个字符串str里边的字符数量不是固定的,有可能是“a,b,c”也有可能是“a,b,c,d,e”
求能适用于所有情况的算法
自己写了一个,如下,只能适用于str里边只有5组字符的。看有没启发

List<string> strlist = new List<string>();
List<string> strs = "a,c,b,e,d".Split(',').OrderBy(t=>t).ToList();
string temp = "";
//5位
for (int i = 0; i<strs.Count; i++)
{
temp += strs[i] + ",";
}
strlist.Add(temp);
//4位数
for (int i = 0; i < strs.Count - 3; i++)
{
for (int j = i + 1; j < strs.Count - 2; j++)
{
for (int k = j + 1; k < strs.Count - 1; k++)
{
for (int n = k + 1; n < strs.Count; n++)
{
temp = strs[i] + "," + strs[j] + "," + strs[k] + "," + strs[n];
strlist.Add(temp);
}
}
}
}
//3位数

for (int j = 0; j < strs.Count - 2; j++)
{
for (int k = j + 1; k < strs.Count - 1; k++)
{
for (int n = k + 1; n < strs.Count; n++)
{
temp = strs[j] + "," + strs[k] + "," + strs[n];
strlist.Add(temp);
}
}
}
//2位
for (int k = 0; k < strs.Count - 1; k++)
{
for (int n = k + 1; n < strs.Count; n++)
{
temp = strs[k] + "," + strs[n];
strlist.Add(temp);
}
}
//1位
for (int n = 0; n < strs.Count; n++)
{
temp = strs[n];
strlist.Add(temp);
}

return strlist.OrderBy(t=>t).ToList();

输出结果如下:
...全文
2541 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_26685277 2017-03-02
  • 打赏
  • 举报
回复
int size; void getstr(char str[]) { size = 0; for (int i = 0; i < strlen(str); i++) { if (strrchr(a, str[i]) == NULL) { a[size++] = str[i]; } } } char ans[16]; int book[16]; int first(int s) { int j; for (j = 0; j < size; j++) { if (ans[s-1] == a[j]) return j; } return s; } void dfs(int step,int allstep) { if (step == allstep) { for (int i = 0; i < step; i++) { printf("%c", ans[i]); } printf("\n"); return; } for (int i = first(step); i < size; i++) { if (book[i] == 0) { book[i] = 1; ans[step] = a[i]; dfs(step + 1, allstep); book[i] = 0; } } } int main() { int T; char str[16]; while (scanf_s("%d", &T) != EOF) { while (T--) { memset(str, 0, 16); scanf_s("%s", str, 16); getstr(str); for (int i = 1; i <= size; i++) { dfs(0, i); } } } return 0; }
threenewbee 2014-08-15
  • 打赏
  • 举报
回复
引用 10 楼 lyj224170707 的回复:
[quote=引用 2 楼 caozhy 的回复:] 写个不用递归的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
        }

        static IEnumerable<string> foo(string metachars, int i)
        {
            var query = metachars.Select(x => x.ToString().AsEnumerable());
            while (query.First().Count() < i)
                query = query.SelectMany(x => metachars.Where(y => y > x.Last()).Select(y => x.Concat(y.ToString().AsEnumerable())));
            return query.Select(x => string.Join(",", x));
        }
    }
}
a b c d e a,b a,c a,d a,e b,c b,d b,e c,d c,e d,e a,b,c a,b,d a,b,e a,c,d a,c,e a,d,e b,c,d b,c,e b,d,e c,d,e a,b,c,d a,b,c,e a,b,d,e a,c,d,e b,c,d,e a,b,c,d,e 请按任意键继续. . .
看似简短。。很难理解。。我看了15分钟才懂。。


 static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
            Console.ReadKey();
        }

        static IEnumerable<string> foo(string metachars, int place)
        {
            IEnumerable<string> list = metachars.Select(x => x.ToString());
            List<IEnumerable<string>> source = new List<IEnumerable<string>>();
            IEnumerable<string> result = new List<string>();
            int index = 0;
            do
            {
                source.Clear();
                for (int i = 0; i < place; i++)
                {
                    source.Add(list.Skip(index + i).Take(1));
                }
                source.Add(list.Skip(place + index));
                var a = source.Aggregate((thisCurrent, nextCurrent) => (thisCurrent.SelectMany(x => nextCurrent.Select(y => x + y))));
                result = result.Concat(a);
                index++;
            }
            while (list.Count() - place > index);
            return result;
        }

感觉我这个好懂点。。也好读[/quote] 好懂是相对的。 你让一个根本不会写程序的人看你觉得好懂的程序,他花1个小时未必能懂。 相反,这次你花15分钟看懂了,下次15秒钟就够了。
游离失所 2014-08-15
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
写个不用递归的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
        }

        static IEnumerable<string> foo(string metachars, int i)
        {
            var query = metachars.Select(x => x.ToString().AsEnumerable());
            while (query.First().Count() < i)
                query = query.SelectMany(x => metachars.Where(y => y > x.Last()).Select(y => x.Concat(y.ToString().AsEnumerable())));
            return query.Select(x => string.Join(",", x));
        }
    }
}
a b c d e a,b a,c a,d a,e b,c b,d b,e c,d c,e d,e a,b,c a,b,d a,b,e a,c,d a,c,e a,d,e b,c,d b,c,e b,d,e c,d,e a,b,c,d a,b,c,e a,b,d,e a,c,d,e b,c,d,e a,b,c,d,e 请按任意键继续. . .
看似简短。。很难理解。。我看了15分钟才懂。。


 static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
            Console.ReadKey();
        }

        static IEnumerable<string> foo(string metachars, int place)
        {
            IEnumerable<string> list = metachars.Select(x => x.ToString());
            List<IEnumerable<string>> source = new List<IEnumerable<string>>();
            IEnumerable<string> result = new List<string>();
            int index = 0;
            do
            {
                source.Clear();
                for (int i = 0; i < place; i++)
                {
                    source.Add(list.Skip(index + i).Take(1));
                }
                source.Add(list.Skip(place + index));
                var a = source.Aggregate((thisCurrent, nextCurrent) => (thisCurrent.SelectMany(x => nextCurrent.Select(y => x + y))));
                result = result.Concat(a);
                index++;
            }
            while (list.Count() - place > index);
            return result;
        }

感觉我这个好懂点。。也好读
threenewbee 2014-08-14
  • 打赏
  • 举报
回复
引用 5 楼 wuyajungogo 的回复:
[quote=引用 2 楼 caozhy 的回复:] 写个不用递归的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
        }

        static IEnumerable<string> foo(string metachars, int i)
        {
            var query = metachars.Select(x => x.ToString().AsEnumerable());
            while (query.First().Count() < i)
                query = query.SelectMany(x => metachars.Where(y => y > x.Last()).Select(y => x.Concat(y.ToString().AsEnumerable())));
            return query.Select(x => string.Join(",", x));
        }
    }
}
a b c d e a,b a,c a,d a,e b,c b,d b,e c,d c,e d,e a,b,c a,b,d a,b,e a,c,d a,c,e a,d,e b,c,d b,c,e b,d,e c,d,e a,b,c,d a,b,c,e a,b,d,e a,c,d,e b,c,d,e a,b,c,d,e 请按任意键继续. . .
啊,大神,你太牛了, 可是我的字符串是以","号分割的,如“a,b,c,d,e”你这个我都不会改啊。能不能帮改下[/quote] string metachars = "abcde"; -> string metachars = "a,b,c,d,e".Replace(",", "");
mnxm 2014-08-14
  • 打赏
  • 举报
回复

        static List<string> GetChildCollections2(string strTemp)
        {
            List<string> lstTemp = strTemp.Split(',').ToList();
            return Enumerable.Range(0, 1 << lstTemp.Count).Select(x => Enumerable.Range(0, lstTemp.Count).Select(y => (x & (1 << y)) != 0 ? lstTemp[y] : null).Where(z => z != null)).Select(x => string.Join(",", x)).ToList();
        }
  • 打赏
  • 举报
回复
先学习 linq 基本概念。 否则让别人“打注释”,只会是浪费。
一枚大帅哥 2014-08-14
  • 打赏
  • 举报
回复
引用 4 楼 wzn721721 的回复:
        static List<string> GetChildCollections(string strTemp)
        {
            List<string> lstTemp = strTemp.Split(',').ToList();
            var subsets = from m in Enumerable.Range(0, 1 << lstTemp.Count)
                          select (from i in Enumerable.Range(0, lstTemp.Count)
                               where (m & (1 << i)) != 0
                               select lstTemp[i]).ToArray();
            return subsets.Select(x => string.Join(",", x)).ToList();
        }
大神。真的可以诶 可是我实在看不明白你的代码,头都晕了,能帮忙打点注释么?
一枚大帅哥 2014-08-14
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
写个不用递归的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
        }

        static IEnumerable<string> foo(string metachars, int i)
        {
            var query = metachars.Select(x => x.ToString().AsEnumerable());
            while (query.First().Count() < i)
                query = query.SelectMany(x => metachars.Where(y => y > x.Last()).Select(y => x.Concat(y.ToString().AsEnumerable())));
            return query.Select(x => string.Join(",", x));
        }
    }
}
a b c d e a,b a,c a,d a,e b,c b,d b,e c,d c,e d,e a,b,c a,b,d a,b,e a,c,d a,c,e a,d,e b,c,d b,c,e b,d,e c,d,e a,b,c,d a,b,c,e a,b,d,e a,c,d,e b,c,d,e a,b,c,d,e 请按任意键继续. . .
啊,大神,你太牛了, 可是我的字符串是以","号分割的,如“a,b,c,d,e”你这个我都不会改啊。能不能帮改下
mnxm 2014-08-14
  • 打赏
  • 举报
回复
        static List<string> GetChildCollections(string strTemp)
        {
            List<string> lstTemp = strTemp.Split(',').ToList();
            var subsets = from m in Enumerable.Range(0, 1 << lstTemp.Count)
                          select (from i in Enumerable.Range(0, lstTemp.Count)
                               where (m & (1 << i)) != 0
                               select lstTemp[i]).ToArray();
            return subsets.Select(x => string.Join(",", x)).ToList();
        }
mnxm 2014-08-14
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390770707 我曾经问过类似的问题 且看二楼回答
threenewbee 2014-08-14
  • 打赏
  • 举报
回复
写个不用递归的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string metachars = "abcde";
            for (int i = 1; i <= metachars.Length; i++)
            {
                foreach (string s in foo(metachars, i))
                {
                    Console.WriteLine(s);
                }
            }
        }

        static IEnumerable<string> foo(string metachars, int i)
        {
            var query = metachars.Select(x => x.ToString().AsEnumerable());
            while (query.First().Count() < i)
                query = query.SelectMany(x => metachars.Where(y => y > x.Last()).Select(y => x.Concat(y.ToString().AsEnumerable())));
            return query.Select(x => string.Join(",", x));
        }
    }
}
a b c d e a,b a,c a,d a,e b,c b,d b,e c,d c,e d,e a,b,c a,b,d a,b,e a,c,d a,c,e a,d,e b,c,d b,c,e b,d,e c,d,e a,b,c,d a,b,c,e a,b,d,e a,c,d,e b,c,d,e a,b,c,d,e 请按任意键继续. . .
rtdb 2014-08-14
  • 打赏
  • 举报
回复
用递归,任意长度都可以

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧