-1

我需要实现一个模块,它将具有拆分字符串值的列表转换为可能的值集。

例如

考虑该列表包含以下值

1
1,2
3
4
5

该模块应将上述列表转换为可能的值集列表

1,2,3,4,5
1,1,3,4,5

提前致谢

4

2 回答 2

2

这将做到这一点,尽管它会以相反的顺序返回您的示例:

static IEnumerable<string> Permutations(
    IEnumerable<string> input,
    char separator)
{
    var sepAsString = separator.ToString();

    var enumerators = input
       .Select(s => s.Split(separator).GetEnumerator())
        .ToArray();
    if (!enumerators.All(e => e.MoveNext())) yield break;

    while (true)
    {
        yield return String.Join(sepAsString, enumerators.Select(e => e.Current));
        if (enumerators.Reverse().All(e => {
                bool finished = !e.MoveNext();
                if (finished)
                {
                    e.Reset();
                    e.MoveNext();
                }
                return finished;
            }))
            yield break;
    }
}

用法:

var list = new[] { "1", "1,2", "3", "4", "5" }.ToList();
var perms = Permutations(list, ',').ToList();
于 2013-02-25T15:49:58.320 回答
1

罗林的回答非常可靠,但我觉得它不容易阅读和理解。这是另一种方式,使用较少的 Linq。

    private List<string> Process(IEnumerable<string> input)
    {
        List<string> data = new List<string>();
        int preExpandCount = 0, offset = 0;
        foreach (string inputItem in input)
        {
            List<string> splitItems = inputItem.Split(',').ToList();
            if (data.Count > 0)
                preExpandCount = ExpandList(data, splitItems.Count - 1);

            offset = 0;
            foreach (string splitItem in splitItems)
            {
                if (preExpandCount == 0)
                    data.Add(splitItem);
                else
                {
                    for (int i = 0; i < preExpandCount; i++)
                        data[i + offset] = String.Format("{0},{1}", data[i + offset], splitItem);
                    offset += preExpandCount;
                }
            }
        }

        return data.OrderBy(e => e).ToList();
    }

    private int ExpandList(List<string> existing, int count)
    {
        int existingCount = existing.Count;
        for (int i = 0; i < count; i++)
            existing.AddRange(existing.Take(existingCount).ToList());
        return existingCount;
    }
于 2013-02-25T17:09:56.347 回答