0

.NET LINQ (C# 推奨) で次のアルゴリズムを実装したいと思います。

  1. 入力は任意の文字列です。文字列の最初の文字は母音であることが保証されています。例えば"alkjihgefdcb"

  2. 文字列を母音で区切られたチャンクに分割します。例"alkj", "ihg","efdcb"

  3. 各チャンクをアルファベット順に並べ替えます。例"ajkl", "ghi","bcdef"

  4. 出力文字列を生成するために、チャンクを再び結合します。例えば"ajklghibcdef"

これを行うエレガントな(つまり、純粋に機能的な)方法はありますか?ステップ 3 と 4 は簡単ですが、ステップ 2 には困惑しています。ありがとう。

編集:正規表現ソリューションには感謝していますが、純粋に LINQ ベースのアプローチを探しています。私の実際のアプリケーションでは、文字列はドメイン オブジェクトのリストであるため、正規表現は簡単には適用できません。

4

3 に答える 3

2

もちろん。

Regex.Split(input, @"(?=[aeiou])").Where(s => !string.IsNullOrWhiteSpace(s))
     .OrderBy(n => n).Aggregate((a, b) => a + b);

正規表現を使用したくない場合は、拡張メソッドが必要になります。

public static IEnumerable<IEnumerable<T>> SplitOn<T>(this IEnumerable<T> source, params T[] splitObjs)
{
    //appropriate error checking, check for null etc
    if (!source.Any() || !splitObjs.Any()) return new[]{source};
    List<T> buffer = new List<T>()
    foreach (T item in source)
    {
        if (splitObjs.Contains(item) && buffer.Any())
        {
            yield return buffer;
            buffer.Clear();
        }
        buffer.Add(item);
    }
    if (buffer.Any()) yield return buffer;
}

そして、次のように簡単にする必要があります。

input.SplitOn('a', 'b', 'c', 'd', 'e').Select(s => new string(s.ToArray()))
     .OrderBy(n => n).Aggregate((a, b) => a + b);
于 2013-07-01T23:05:26.367 に答える
1

Linq と正規表現を使用できます。

string.Join(
    string.Empty, 
    Regex.Matches("alkjihgefdcb", "[aeiou][^aeiou]+")
         .Cast<Match>()
         .Select(m => string.Join(string.Empty, m.Value.OrderBy(c => c))));
// ajklghibcdef

またはさらに良い:

string.Join(
    string.Empty, 
    Regex.Split("alkjihgefdcb", "(?=[aeiou])")
         .Select(m => string.Join(string.Empty, m.OrderBy(c => c))));
// ajklghibcdef

純粋なLinqを使用:

var i = 0;
string.Join(
    string.Empty,
    "alkjihgefdcb".GroupBy(c => "aeiou".IndexOf(c) == -1 ? i : ++i)
                  .SelectMany(g => g.OrderBy(c => c)));
// ajklghibcdef

メソッドの副作用によって更新されることに依存しているため、これを真に機能的と呼ぶのはためらっていますが。iGroupBy

于 2013-07-01T23:01:27.560 に答える
0

これは、LINQ (Pure Functional way) を使用した 1 つのライナー ソリューションです。アイデアは、すべての母音を置き換えて# から分割することです#

string input = "alkjihgefdcb";

input = input
 .Replace("a","#a")
 .Replace("e","#e")
 .Replace("i","#i")
 .Replace("o","#u")
 .Replace("u","#u")
 .Split(new char[]{'#'},StringSplitOptions.RemoveEmptyEntries)
 .Select (i => new string(i.ToCharArray().OrderBy (x => x).ToArray()))
 .Aggregate ((a,b) => a + b);
于 2013-07-02T18:10:50.537 に答える