生成订单重要的列表的幂集

时间:2019-06-16 04:47:31

标签: c#

我一直在寻找一种方法来创建字母的幂集,以基本上生成任何可能的字母组合,但是要使顺序如此重要,因此ab!= ba。我遇到了一个很卑鄙的偷窃代码here。这是我的整个程序:

using System;
using System.Collections.Generic;
using System.Linq;

namespace PermutationsHelper
{
    static class Program
    {
        static void Main()
        {
            var ps = GetPowerSet(new List<string>() { "a", "b" });
            foreach (var item in ps)
            {
                string[] resultArr = item.ToArray();
                string result = string.Join("", resultArr);
                Console.WriteLine(result);
            }
            Console.ReadLine();
        }
        static IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list)
        {
            return from m in Enumerable.Range(0, 1 << list.Count)
               select
                   from i in Enumerable.Range(0, list.Count)
                   where (m & (1 << i)) != 0
                   select list[i];
        }
    }
}

输出为:

[empty]
a
b
ab

但是我要寻找的是:

[empty]
a
b
ab
ba

关于如何最好地做到这一点的任何建议? TIA

2 个答案:

答案 0 :(得分:0)

给Progman打电话,这是我的解决方案:

class Program
{
    static List<string> biggestList = new List<string>();

    static void Main(string[] args)
    {
        string str = "abc";
        char[] arr = str.ToCharArray();
        GetPer(arr);
        Console.WriteLine("Complete List:");
        for (int i = 0; i < biggestList.Count; i++)
            Console.WriteLine(biggestList[i]);
        Console.ReadKey();
    }
    private static void Swap(ref char a, ref char b)
    {
        if (a == b) return;

        a ^= b;
        b ^= a;
        a ^= b;
    }

    public static void GetPer(char[] list)
    {
        int x = list.Length - 1;
        GetPer(list, 0, x);
    }

    private static void GetPer(char[] list, int k, int m)
    {
        if (k == m)
        {
            string result = string.Join("", list.ToArray());
            for (int i = 0; i < result.Length; i++)
            {
                if(!biggestList.Contains(result.Substring(0, i + 1)))
                    biggestList.Add(result.Substring(0, i+1));
            }
        }
        else
        {
            for (int i = k; i <= m; i++)
            {
                Swap(ref list[k], ref list[i]);
                GetPer(list, k + 1, m);
                Swap(ref list[k], ref list[i]);
            }
        }
    }
}

答案 1 :(得分:0)

您可以使用答案Listing all permutations of a string/integer中的递归方法来获得所有可能的组合和排列,包括不同的顺序。您定义了类似public static ISet<string> CombinationsAndPermutations(string input)的方法,其工作方式如下:

  • 当输入为空时,返回一个空列表。 (无所事事)
  • 当输入为长度为1的字符串时,返回带有值Set和输入字符串的string.Empty(递归基础案例)

对于所有其他情况,您遍历字符串的所有字符并找到该特定字符或字符串位置的解决方案。您将所有子解决方案收集在总结果列表中,并将其返回。伪代码将如下所示:

for all positions in the string:
    get the character at position "i"
    get the remaining string without the character at position "i"
    get the solution for the remaining string (recursive call)

    add the solution to a total list of solutions
    add the solution to a total list of solutions, but add the extracted character from position "i" at the front

return the total list

话虽如此,解决方案将如下所示:

public static ISet<string> CombinationsAndPermutations(string input) {
    if (string.IsNullOrWhiteSpace(input)) {
        return new HashSet<string>();
    }
    if (input.Length == 1) {
        return new HashSet<string> { string.Empty, input };
    }

    ISet<string> result = new HashSet<string>();
    for (int i=0; i<input.Length; i++) {
        char letter = input[i];
        string remainingBefore = input.Substring(0, i);
        string remainingAfter = input.Substring(i+1);
        string remaining = remainingBefore + remainingAfter;

        ISet<string> subResult = CombinationsAndPermutations(remaining);

        foreach (string subStr in subResult) {
            result.Add(subStr);
            result.Add(letter + subStr);
        }
    }

    return result;
}

对于示例输入“ abc”,这将生成带有以下条目的Set

(, a, b, ab, c, ac, bc, abc, cb, acb, ba, bac, ca, bca, cab, cba)