2014-07-13 64 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將是一個更多的工作,因爲你必須按正確的排序順序配對字節。