1

それぞれ可変長の文字列のリストがあります。長さが 5 に等しい元のリストから文字列を連結したリストからサブセットを射影したいのですが、集計関数を使用していますが、目的の結果が得られません。このプロジェクションに適した LINQ クエリはどれですか? 助けていただけますか?

コード:

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items = new List<string> {"abc", "ab", "abcd", "abcde", "abcdef", "a", "ab", "cde"};

        //All combinations of concatenations equal to length 5.
        //Only need to process an item once and need to concatenate 2 items and no more

        var filteredList = items.Where(x => x.Length < 5)
                                .Aggregate(Execute).ToList();

        foreach (var f in filteredList)
        {
            //Should out put : abc+ab = abcab
            //Should out put : abcde
            //Should out put : abcd+a = abcda
            //Should out put : ab+cde = abcde
            Console.WriteLine(f);
        }
    }

    private static string Execute(string a, string b)
    {
        if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b))
            return null;

        if ((a.Length + b.Length) == 5)
            return a + b;

        return null;
    }
}

ポイントのカップル:

  • アイテムが処理されると、組み合わせのためにそのアイテムを再度考慮する必要はありません

  • リストで同じアイテムが再び見つかるまで、上記は当てはまります。見つかったら、以前の連結で使用されなかった別のアイテムと連結する必要があります。

  • LINQ である必要はありません。解決策を探しているだけです。

  • 出力は 3 つ以上の文字列で構成できませんか? (a + bc + de) は必要ありません。

  • 項目は、それ自体と連結する必要はありません。

  • 質問の一部として出力について言及しました。

: .NET 3.5 を使用しています (ただし、可能であれば .NET 4.0 にもショートカットを表示したいと考えています)。

4

6 に答える 6

1

あなたが私に尋ねたら、私は言う:「怠惰にならないでください」.

    private static List<string> ValidCombinationsFind(List<string> iSource)
    {
        List<string> lstResult = new List<string>();

        //Use and explicit mask to remember indexes in iSource which were used.
        bool[] ablnUsageMask = new bool[iSource.Count];

        int intCurrentIndex = 0;

        //Examine the source list one by one.
        while (intCurrentIndex < iSource.Count - 1)
        {
            //If the next item is not already used then go on.
            if (!ablnUsageMask[intCurrentIndex])
            {
                string strCurrentItem = iSource[intCurrentIndex];

                //If the item is ok then check every remaining item for a match.
                if (!string.IsNullOrEmpty(strCurrentItem))
                {
                    //Check if an item fits on its own.
                    if (strCurrentItem.Length == 5)
                    {
                        ablnUsageMask[intCurrentIndex] = true;
                        lstResult.Add(strCurrentItem);
                    }
                    else
                    {
                        for (int intNextItemIndex = intCurrentIndex + 1; intNextItemIndex < iSource.Count; intNextItemIndex++)
                        {
                            //If the next item is not already used then go on.
                            if (!ablnUsageMask[intNextItemIndex])
                            {
                                string strNextItem = iSource[intNextItemIndex];

                                if (!string.IsNullOrEmpty(strNextItem))
                                {
                                    if ((strCurrentItem.Length + strNextItem.Length) == 5)
                                    {
                                        ablnUsageMask[intCurrentIndex] = true;
                                        ablnUsageMask[intNextItemIndex] = true;
                                        lstResult.Add(strCurrentItem + strNextItem);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            intCurrentIndex++;
        }

        return lstResult;
    }
于 2013-10-15T17:14:05.817 に答える
0
void Main()
{
    var items = new List<string> {"abc", "ab", "abcd", "abcde", "abcdef", "a", "ab", "cde"};
    bool[] flag=new bool[items.Count()];
    var output=items.SelectMany((x,i)=>items.Select((y,j)=>concat(flag,items,i,j)))
                    .Where(x=>x!="");
}

public string concat(bool[] flag,List<string> items,int i,int j)
{
if(flag[i]==false && flag[j]==false && (items[i].Length==5||(items[i]+items[j]).Length==5))
{
      flag[i]=true;
      flag[j]=true;

      if(i==j)return items[i];
      else return items[i]+","+items[j];
}
else return "";
}

出力:

abc,ab 
abcd,a 
abcde 
ab,cde 
于 2013-10-15T16:59:47.080 に答える
0

私はこれがあなたが望むことをすると信じています:

  var filteredList = items.Where(x => x.Length < 5)
    .SelectMany(x => items, (y, z) => { return Execute(y, z); })
    .Where(x => x != null).Distinct().ToList();
于 2013-10-15T17:00:02.177 に答える