2014-07-13 67 views
0

这是一个问题:迭代通过串并计数出现

  • 编写一个程序,按字母顺序从控制台打印读取字符串从输入字符串中的所有字母和多少次他们中的每一个发生在字符串中。

起初它似乎很有趣,并不太复杂,但我无法解决它。

public static void Letters() 
{ 
     string input; 
     Console.Write("Enter a string: "); 
     input = Console.ReadLine(); 

     var chars = new List<char>(); 

     //To populate characters with the letters of the input but without repetition 
     for(int index = 0; index < input.Length; index++) 
     { 
      if(!characters.Contains(input[index])) 
       characters.Add(input[index]); 
     } 

     //To increment the counter corresponding to the character index 
     int[] counter = new int[characters.Count]; 


     //Now what ?! 

    } 

我的想法是:

我创建一个集合容纳输入字符串中的字母,没有任何重复。

然后,我使用一个相同大小的int数组,以便每个int都保存输入字符串中相应字母出现的次数。

我不仅不知道如何实现这一点,但我有一种感觉,它不是一个理想的解决方案 的问题。可能有一个查询或lambda表达式可以使这个简单的 实现和阅读。

注意:接下来的问题具有相同的性质。不同的是,它要求 用单个“aaabbbccc”替换为“abc”的重复字母。

如果描述逻辑,我将不胜感激。我会尝试自己实现它, 只是指向我的逻辑。

编辑:

这是我的答案使用字典

public static void Letters() 
{ 
     string input; 
     Console.Write("Enter a string: "); 
     input = Console.ReadLine(); 

     var dict = new Dictionary<char, int>(); 

     for(int index = 0; index < input.Length; index++) 
     { 
      char theKey = input[index]; //just for clarity 

      if(!dict.ContainsKey(theKey)) 
       dict.Add(theKey, 1); 
      else 
       dict[input[index]]++; 
     } 

     foreach(var key in dict.Keys) 
     { 
      Console.WriteLine("{0}\t{1}", key, dict[key]); 
     } 
+3

这是作业吗? – matcheek

+0

在哪个公司面试中你被要求写这个程序? –

+0

不是它不是一个家庭作业,也不是一个采访,它是在这个真棒网站“www.introprogramming.info/english-intro-csharp-book/read-online/chapter-13-strings-and-text-processing/#_Toc362296495 ”。该网站的设计有点杂乱,但它的练习是像我这样的初学者非常好:)。这个特殊的问题是数字22 – Mustafa

回答

2
Dictionnary<String, int> 

重点=字符串=字母IE A,B,C,d,E,F ..... 诠释是occurence数

做这个所以开始:

Dictionnary.add(a,0) 
... 
Dictionnary.add(z,0); 

,然后读取字符串,并为此

Dictionnary[letterFound ] += 1; 

有一个更好的办法知道什么是每个字母给init dictionnary的ASCi比的价值,但我不认为是强制性这样exercice。

好运

+0

Excellen这工作。唯一的区别是我的字典是。检查我的更新。非常感谢 – Mustafa

1

对于简单和可读的解决方案使用LINQ,的GroupBy和匿名类型

string input = Console.ReadLine(); 

var groupedLettersOrdered = input.GroupBy(x => x, (character, charCollection) => 
    new {Character = character, Count = charCollection.Count()}) 
    .OrderBy(x => x.Character); 
foreach(var letterGroup in groupedLettersOrdered) 
    Console.WriteLine("Character {0}, Count: {1}", letterGroup.Character, letterGroup.Count); 

然而Dictionary<char, int>解决方案将是(应该是)大型字符串

+0

谢谢。我喜欢这种类型的LINQ和匿名类型解决方案,但由于我没有正式开始研究这个部分,它总是忽略我的头:)。 – Mustafa

2
var myString = "Hello"; 

var dict = new Dictionary<char, int>(); 

foreach(var c in myString) 
{ 
    if(!dict.ContainsKey(c)) 
     dict.Add(c, 1); 
    else 
     dict[c]++; 
} 

var orderedDict = dict.OrderBy(x => x.Key); 

foreach(var kvp in orderedDict) 
{ 
    Console.WriteLine("Letter: {0}, Times: {1}", kvp.Key, kvp.Value); 
} 
+0

+1谢谢。很好地按字母顺序排列字母。 – Mustafa

0
更快更好

首先考虑一个字符与标量值一样具有二进制表示(1和0的序列)。还要考虑到对于像英语这样的拉丁字母,它们的等效字母顺序和数字顺序相对应。

所以...你可以做这样的事情:

  1. 定义尺寸大到足以容纳所有可能的字符值(任意的整数数组,我们可以做到256为UTF-8串)。
  2. 迭代字符串中的每个字符;对于每个字符,将字符转换为其等效整数,将其用作数组中的索引并将该索引处的值增加。
  3. 遍历阵列和用于每个非零元素,打印出的字符等效阵列索引和所述元件(字符数)的内容

    string myString = "the quick brown fox jumps over the lazy dog"; 
        byte[] bytes = Encoding.UTF8.GetBytes(myString); 
        int[] counts = new int[256]; 
        foreach (var b in bytes) 
        { 
         counts[(int)b]++; 
        } 
        for (int i = 0; i < 256; i++) 
        { 
         if (counts[i] > 0) 
         { 
          Console.WriteLine("{0} - {1}", (char)(byte)i, counts[i]); 
         } 
        } 
    

将上述溶液可以很容易地通过在myString.ToUpper()上执行GetBytes来推广以忽略大小写。推广到Unicode将是一个更多的工作,因为你必须按正确的排序顺序配对字节。