7

スペースで区切られた単語の文字列があります。単語の長さに基づいて文字列を単語のリストに分割するにはどうすればよいですか?

入力:

" aa aaa aaaa bb bbb bbbb cc ccc cccc cccc bbb bb aa "

出力:

List 1 = { aa, bb, cc}
List 2 = { aaa, bbb, ccc}
List 3 = { aaaa, bbbb, cccc}
4

5 に答える 5

10

Where述語に一致する要素(この場合は正しい長さ)を見つけるために使用できます。

string[] words = input.Split();

List<string> twos = words.Where(s => s.Length == 2).ToList();
List<string> threes = words.Where(s => s.Length == 3).ToList();
List<string> fours = words.Where(s => s.Length == 4).ToList();

GroupByまたは、を使用してすべてのグループを一度に検索することもできます。

var groups = words.GroupBy(s => s.Length);

を使用ToLookupして、特定の長さのすべての単語を簡単にインデックスに登録して検索することもできます。

var lookup = words.ToLookup(s => s.Length);
foreach (var word in lookup[3])
{
    Console.WriteLine(word);
}

結果:

aaa
bbb
ccc

オンラインで動作することを確認してください:ideone


アップデートでは、空の文字列と重複した単語を削除したいようです。StringSplitOptions.RemoveEmptyEntries前者はを使用して、後者はを使用して実行できますDistinct

var words = input.Split((char[])null, StringSplitOptions.RemoveEmptyEntries)
                 .Distinct();
var lookup = words.ToLookup(s => s.Length);

出力:

aa, bb, cc
aaa, bbb, ccc
aaaa, bbbb, cccc

オンラインで動作することを確認してください:ideone

于 2012-07-07T20:21:53.113 に答える
6

編集:私の元の答えがOPが彼らの問題を解決するのを助けてくれてうれしいです。しかし、問題を少し考えた後、私はそれを適応させました(そして、私は投稿の最後に残した以前の解決策に反対することを強くお勧めします)。

シンプルなアプローチ

string input = " aa aaa aaaa bb bbb bbbb cc ccc cccc cccc bbb bb aa ";
var words = input.Trim().Split().Distinct();
var lookup = words.ToLookup(word => word.Length);

説明

まず、入力をトリミングして、外部スペースからの空の要素を回避します。次に、文字列を配列に分割します。単語の間に複数のスペースが含まれている場合は、 Markの回答のStringSplitOptionsように使用する必要があります。

各単語を1回だけ含めるように呼び出した後、から にDistinct変換します。ここで、単語の長さはキーで表され、単語自体は値に格納されます。wordsIEnumerable<string>Lookup<int, string>(int)(string)

ちょっと待ってください、それはどうして可能ですか?キーごとに複数の単語がありませんか?もちろんですが、それこそがLookupクラスの目的です。

Lookup<TKey, TElement>それぞれが1つ以上の値にマップされたキーのコレクションを表します。はにLookup<TKey, TElement>似ていDictionary<TKey, TValue>ます。違いは、ディクショナリがキーを単一の値にマップするのに対し、ルックアップはキーを値のコレクションにマップすることです。

を実装するオブジェクトをLookup呼び出すことにより、のインスタンスを作成できます。ToLookupIEnumerable<T>



ルックアップの新しいインスタンスを作成するためのパブリックコンストラクターはありません。さらに、ルックアップオブジェクトは不変です。つまり、ルックアップの作成後に要素やキーを追加したり、ルックアップから削除したりすることはできません。

word => word.LengthKeySelectorラムダです。これはLookup、単語の長さでインデックスを作成する(またはグループ化する)ことを定義します。

使用法

コンソールにすべての単語を書きます

(質問の最初に要求された出力と同様)

foreach (var grouping in lookup)
{
    Console.WriteLine("{0}: {1}", grouping.Key, string.Join(", ", grouping));
}

出力

2: aa, bb, cc
3: aaa, bbb, ccc
4: aaaa, bbbb, cccc

特定の長さのすべての単語をList

List<String> list3 = lookup[3].ToList();

キーで注文する

(これらは返さIOrderedEnumerable<T>れるため、キーによるアクセスはできなくなります)

var orderedAscending = lookup.OrderBy(grouping => grouping.Key);
var orderedDescending = lookup.OrderByDescending(grouping => grouping.Key);

元の答え-これを行わないでください(パフォーマンスの低下、コードの乱雑さ):

string input = " aa aaa aaaa bb bbb bbbb cc ccc cccc cccc bbb bb aa ";
Dictionary<int, string[]> results = new Dictionary<int, string[]>();
var grouped = input.Trim().Split().Distinct().GroupBy(s => s.Length)
    .OrderBy(g => g.Key); // or: OrderByDescending(g => g.Key);
foreach (var grouping in grouped)
{
    results.Add(grouping.Key, grouping.ToArray());
}
于 2012-07-07T21:11:29.537 に答える
3

まず、単語のリストだけでなく長さも保持できるクラスを宣言しましょう

public class WordList
{
    public int WordLength { get; set; }
    public List<string> Words { get; set; }
}

これで、単語リストのリストを作成できます。

string input = " aa aaa aaaa bb bbb bbbb cc ccc cccc ";
string[] words = input.Trim().Split();
List<WordList> list = words
    .GroupBy(w => w.Length)
    .OrderBy(group => group.Key)
    .Select(group => new WordList { 
        WordLength = group.Key, 
        Words = group.Distinct().OrderBy(s => s).ToList() 
    })
    .ToList();

リストは、それぞれ長さおよび無意味にソートされています。


結果

ここに画像の説明を入力してください

例えば

list[2].WordLength ==> 4
list[2].Words[1] ==> "bbbb"

アップデート

必要に応じて、結果をデータ構造に入れる代わりに、すぐに処理できます

string input = " aa aaa aaaa bb bbb bbbb cc ccc cccc ";

var query = input
    .Trim()
    .Split()
    .GroupBy(w => w.Length)
    .OrderBy(group => group.Key);

// Process the result here
foreach (var group in query) {
    // group.Key ==> length of words
    foreach (string word in group.Distinct().OrderBy(w => w)) {
       ...
    }
}
于 2012-07-07T20:40:44.497 に答える
1

LinqGroupByを使用できます

編集 ここで、Linqを適用して、出力に必要な文字列リストを生成しました。

edit2 は、編集された質問のように、複数の入力、単一の出力を適用しました。これは、Linqでの明確な呼び出しです。

string input = " aa aaa aaaa bb bbb bbbb cc ccc cccc ";

var list = input.Split(' ');

var grouped = list.GroupBy(s => s.Length);

foreach (var elem in grouped)
{
    string header = "List " + elem.Key + ": ";
    // var line = elem.Aggregate((workingSentence, next) => next + ", " + workingSentence);

    // if you want single items, use this
    var line = elem.Distinct().Aggregate((workingSentence, next) => next + ", " + workingSentence);
    string full = header + " " + line;
    Console.WriteLine(full);
}


// output: please note the last blank in the input string! this generates the 0 list
List 0:  ,
List 2:  cc, bb, aa
List 3:  ccc, bbb, aaa
List 4:  cccc, bbbb, aaaa
于 2012-07-07T20:42:48.657 に答える
0

少し長い解決策ですが、辞書で結果を取得します

class Program
    {
        public static void Main()
        {
            Print();
            Console.ReadKey();
        }

        private static void Print()
        {
            GetListOfWordsByLength();

            foreach (var list in WordSortedDictionary)
            {
                list.Value.ForEach(i => { Console.Write(i + ","); });
                Console.WriteLine();
            }
        }

        private static void GetListOfWordsByLength()
        {
            string input = " aa aaa aaaa bb bbb bbbb cc ccc cccc ";

            string[] inputSplitted = input.Split(' ');

            inputSplitted.ToList().ForEach(AddToList);
        }

        static readonly SortedDictionary<int, List<string>> WordSortedDictionary = new SortedDictionary<int, List<string>>();

        private static void AddToList(string s)
        {
            if (s.Length > 0)
            {
                if (WordSortedDictionary.ContainsKey(s.Length))
                {
                    List<string> list = WordSortedDictionary[s.Length];
                    list.Add(s);
                }
                else
                {
                    WordSortedDictionary.Add(s.Length, new List<string> {s});
                }
            }
        }
    }
于 2012-07-07T21:13:39.733 に答える