0

如何在字符串中找到每个不同的字符并将其显示在新行中,例如:

string ex = "aabbbbchhhhaaaacc";

变成:

a: aaaaaa
b: bbbb
c: ccc
h: hhhh

我知道我必须使用新的 distinctn 字符串并遍历字符串中的每个字符,但不知道如何继续。

string answer = new String(input.Distinct().ToArray());
                foreach (char c in answer)
                {
                   //what code goes here?
                }
4

7 回答 7

8
void Main()
{
    string ex = "aabbbbchhhhaaaacc";
    var chars = ex.ToCharArray().Distinct();
    foreach (var c in chars)
    {
        Debug.WriteLine("{0}: {1}", c, new String(c, ex.Where(ch => ch == c).Count()));
    }
}

输出:

a: aaaaaa
b: bbbb
c: ccc
h: hhhh
于 2013-07-08T14:30:58.653 回答
5

You can use a regular expression:

void Main()
{
    string ex = "aabbbbchhhhaaaacc";
    var re = new Regex(@"(.)\1*");
    var sequences =
        from Match ma in re.Matches(ex)
        let value = ma.Value
        group value by value[0] into g
        select g.Aggregate((s1, s2) => s1 + s2);

    foreach (var sequence in sequences)
        Debug.WriteLine(sequence);
}

You can test this in LINQPad and it'll output exactly what you want.

Here's an explanation of the expression:

(.)\1*
^-^^-^
 |  |
 |  +- says "0 or more times of the exact same character as in group 1"
 +- first group

The LINQ query will do this:

  1. Find each distinct occurence of the characters
  2. Pick out the first (possibly the only) character of this sequence
  3. Group all the occurances by their first character (so that all sequences of "a"'s is in one group)
  4. Aggregate each group together to get each complete sequence

Now, the above solution works though there are other ways to do this. If the patterns to detect was a bit more complicated than just "the same character N times", then a regular expression might be the best way.

However, what you can do is exploit that fact, that it's the same character:

void Main()
{
    string ex = "aabbbbchhhhaaaacc";
    var groups = ex
        .ToCharArray()
        .GroupBy(c => c);

    foreach (var group in groups)
        Debug.WriteLine(new string(group.Key, group.Count()));
}

This will simply create groups containing all occurences of each character, where group.Key is the character and group.Count() is the length, and then we can simply construct new strings from each group.

于 2013-07-08T14:26:40.733 回答
2

另外的选择:

string ex = "aabbbbchhhh";
var answer = ex.GroupBy(r => r);
foreach (var z in answer)
{
  Console.WriteLine("{0}: {1}",z.Key,new String(z.Key,z.Count()));
}
Console.ReadKey();
于 2013-07-08T14:37:49.867 回答
1
string ex = "aabbbbchhhhaaaacc";
var result = ex.Distinct().ToDictionary(k => k, v => new string(v, ex.Count(c => c == v)));
foreach (var item in result)
{
    Console.WriteLine(item.Key + ": " + item.Value);
}
于 2013-07-08T14:38:01.983 回答
0

类似于 Ahmed KRAIEM,但这应该更快,因为它不会对每个字符执行不同的计数。(当然,除非你有长度为兆字节的字符串,否则这并不重要:))

string ex = "aabbbbchhhhaaaacc";
foreach (var kvPair in ex.GroupBy(x => x).Select(g => new { Key = g.Key, Val = new string(g.Key, g.Count()) })) {
    Console.WriteLine(kvPair.Key + ": " + kvPair.Val);
}
于 2013-07-08T14:47:41.463 回答
0

这是我对这个问题的看法:

void Main()
{
    string input = "aabbbbchhhhaaaacc";
    var dic = new Dictionary<char, int>();
    foreach (char c in input)
    {
        if (dic.ContainsKey(c))
        {
            dic[c]++;
        }
        else
        {
            dic[c] = 1;
        }
    }
    foreach (var item in dic)
    {
        Console.WriteLine("{0}: {1}", item.Key, new string(item.Key, item.Value));
    }
}

在这里,我存储了您在字典中看到每个字符的次数,然后使用字典来构建输出。

注意1:这种方法也有对字符串进行单次传递的出现,使用 Distinct 和 stuff 的方法将对字符串进行两次或更多次传递,从而使整个过程变慢。

注2:另外,这种方法不需要Linq,事实上,它可以在.Net 2.0 上运行。

注 3:在 LinqPad 上编译和测试。

于 2013-07-08T14:32:27.540 回答
-1

您可以在字符串本身上使用 distinct 。

        string ex = "aabbbbchhhhaaaacc";
        ex.GroupBy(c => c).ToList().ForEach(group => Console.WriteLine( group.Key + " : " + group.Count()));
于 2013-07-08T14:32:02.333 回答