2011-08-29 81 views
12

所以,想象一下這串:在同一時間閱讀的字符串,3x3的字符

_ _  _ _ _ _ _ 
    | _| _||_||_ |_ ||_||_| 
    ||_ _| | _||_| ||_| _| 

什麼是分裂的最簡單/最好的方法此字符串,這樣每個號碼可以通過它自身來處理?

我喜歡

public string[] SplitIntoNumbers(string input) 

思考的一些地方,結果會是這樣

["  | |", " _ _||_ ", " _ _| _|", ...] 

任何想法?

編輯
對於古都想一些更多的信息 - 的問題來自於BankOCR -kata了在CodingDojo。我意識到,'完成工作'有多種方式 - 解決方案,但我覺得必須有一種'更加奇特'的解決方法。類似clojure的東西。

+0

你必須使用字符串輸入,也可以使用字符的NX3陣列,然後分出各組在一個3x3的字符結構?字符串的理由是什麼(他們真的是用一維字符串來處理每個字符代表一個字符)。 – ssube

+2

(輸入)參數是什麼樣子?你能寫一個例子嗎? – Tigran

+0

另請參閱http://en.m.wikipedia.org/wiki/Seven-segment_display –

回答

1

我會用正則表達式來建立匹配列表與此類似

(.{3}) 

的模式,這將打破輸入到3X1匹配塊,並根據你有多少場比賽都將確定數字。例如

_ _  _ _ _ _ _ 
    | _| _||_||_ |_ ||_||_| 
    ||_ _| | _||_| ||_| _| 

將產生3×1段的27場比賽,並且由於每個數爲3行高可以只取27/3 = 9個單獨的數字。然後你只需要遍歷正則表達式匹配,並將它們組合到你想要的輸出中。

void Main() 
{ 
    string input = " _ _  _ _ _ _ _ \r\n | _| _||_||_ |_ ||_||_|\r\n ||_ _| | _||_| ||_| _|"; 

    string[] result = SplitIntoNumbers(input); 
} 

public string[] SplitIntoNumbers(string input) 
{ 
    List<string> results = new List<string>(); 

    Regex rx = new Regex("(.{3})"); 
    MatchCollection matches = rx.Matches(input); 
    int totalNumbers = matches.Count/3; 

    for(int i = 0; i < totalNumbers; i++) 
    { 
     string s = string.Concat(matches[i].Value, matches[i + totalNumbers].Value, matches[i + (totalNumbers * 2)].Value); 

     results.Add(s); 
    } 

    return results.ToArray(); 
} 
+0

創意,我想它會工作,但我真的很想玩老'['現在你有兩個問題']( http://regex.info/blog/2006-09-15/247)-card on this one :-) – Vegar

2

單刀直入:

public static string[] SplitIntoNumbers(string input) 
    { 
     List<string> result = new List<string>(); 
     string[] subStrs = input.Split(new char[] { '\r', '\n' }, 3, StringSplitOptions.RemoveEmptyEntries); 
     for (int it = 0; it < subStrs[0].Length; it += 3) 
     { 
      result.Add(subStrs[0].Substring(it, 3) 
       + subStrs[1].Substring(it, 3) 
       + subStrs[2].Substring(it, 3)); 
     } 
     return result.ToArray(); 
    } 

(EDIT)我所使用的字符串是這樣的:

static string str = 
@" 
    _ _  _ _ _ _ _ 
    | _| _||_||_ |_ ||_||_| 
    ||_ _| | _||_| ||_| _|"; 
+0

我得到了'IndexOutOfRangeException' - 將你使用的輸入字符串添加到你的問題中。 – Zabba

0

假設你想保持字符串數組輸入,我們可以很簡單地通過一次拉三個字符的線來循環。

var numbers = new[] 
        { 
         " _ _  _ _ _ _ _ ", 
         " | _| _||_||_ |_ ||_||_|", 
         " ||_ _| | _||_| ||_| _|" 
        }; 

      // just in case length is off on one, don't want to crash 
    var length = numbers.Min(line => line.Length); 
    var results = new List<string>(); 

      // go by groups of three 
    for (int i = 0; i < length; i += 3) 
    { 
     var builder = new StringBuilder(); 
     for (int j = 0; j < numbers.Length; j++) 
     { 
      builder.Append(numbers[j].Substring(i, 3)); 
     } 

     results.Add(builder.ToString()); 
    } 

      // print the results 
    foreach (var digit in results) 
    { 
     Console.WriteLine(digit); 
    } 
4

你問:

什麼是分裂的最簡單/最好的方法此字符串,這樣每個號碼可以通過它自身來處理?

...我想你可能會從一個小太多的面向對象的角度接近這一點。你所談論的實際上是一種「字體」,而不是一系列字符。我會坦率地將邏輯包裝到一個類中,並且完全按照您對這篇文章的描述來定義字符數據。很容易看到,編輯和維護。

如果你的最終目標只是渲染,或者它是解析,我從你原來的帖子不明白。反正我不能僅僅停留在僅數;)

static void Main() 
    { 
     LineBuffers lb = new LineBuffers(80/3); 
     lb.Write(0, "-_ 1234567890"); 
     Console.WriteLine(String.Join(Environment.NewLine, lb.Lines.ToArray())); 
     Console.WriteLine(); 
     Console.WriteLine(lb.ReadLine()); 

     lb.Clear(); 
     lb.Write(0, "abcdefghijklm"); 
     Console.WriteLine(String.Join(Environment.NewLine, lb.Lines.ToArray())); 
     Console.WriteLine(); 
     Console.WriteLine(lb.ReadLine()); 

     lb.Clear(); 
     lb.Write(0, "nopqrstuvwxyz"); 
     Console.WriteLine(String.Join(Environment.NewLine, lb.Lines.ToArray())); 
     Console.WriteLine(); 
     Console.WriteLine(lb.ReadLine()); 

     lb = new LineBuffers(" _  _ _ _ ", "|_| _ | |_ |_|", @"|\ |_||_-|_ |\ "); 
     Console.WriteLine(lb.ReadLine()); 

    } 

    public class LineBuffers 
    { 
     private static string Characters = " -_abcdefghijklmnopqrstuvwxyz"; 
     private static readonly string[] Format = 
      (
      @". . . _ . . _ . _ . . _ . _ . _ . _ . _ . . _ . . _ . . _ . _ . _ . . _ . _. . . . . . _ . _ . _ . _ .___. . . . . .__ ." + "\n" + 
      @". . _ .| |. |. _|. _|.|_|.|_ .|_ . |.|_|.|_|. .|_|.|_ .| . _|.|_ .|_ .| .|_|. | . |.|/ .| .|\|.|\|. _ .|_|.|_|.|_|./_ . | .| |.| |.|||. \/. \/./." + "\n" + 
      @". . .|_|. |.|_ . _|. |. _|.|_|. |.|_|. _|.___.| |.|_|.|_ .|_|.|_ .| .|_-.| |. | . _|.|\ .|_ .|||.| |.|_|.| . |.|\ . _/. | .|_|.|/ .|/|. /\. | ./_ ." 
      ).Split('\n'); 

     private readonly char[][] _lines; 

     public LineBuffers(int charWidth) 
     { 
      _lines = new char[3][] {new char[charWidth*3], new char[charWidth*3], new char[charWidth*3]}; 
      Clear(); 
     } 

     public LineBuffers(string line1, string line2, string line3) 
      : this(line1.ToCharArray(), line2.ToCharArray(), line3.ToCharArray()) { } 

     public LineBuffers(char[] line1, char[] line2, char[] line3) 
     { 
      if (line1 == null || line2 == null || line3 == null 
       || line1.Length != line2.Length || line2.Length != line3.Length) 
       throw new ArgumentException(); 

      _lines = new char[3][] { 
       line1, line2, line3 
      }; 
     } 

     public int Count { get { return _lines[0].Length/3; } } 
     public IEnumerable<string> Lines { get { return _lines.Select(chars => new String(chars)); } } 

     public void Clear() 
     { 
      for (int i = 0; i < Count; i++) 
       Write(i, ' '); 
     } 

     public void Write(int position, IEnumerable<Char> character) 
     { foreach (char ch in character) Write(position++, ch); } 

     public void Write(int position, Char character) 
     { 
      int charIx = Characters.IndexOf(Char.ToLower(character)); 
      if (charIx < 0) 
       throw new ArgumentOutOfRangeException("character"); 
      if (position >= Count) 
       throw new ArgumentOutOfRangeException("position"); 

      int offset = charIx*4 + 1; 
      for(int line=0; line <3; line++) 
       Array.Copy(Format[line].ToCharArray(offset, 3), 0, _lines[line], position * 3, 3); 
     } 

     public Char Read(int position) 
     { 
      if (position >= Count) 
       throw new ArgumentOutOfRangeException("position"); 

      IEnumerable<int> found = Find(Format[0], _lines[0], position*3) 
       .Intersect(Find(Format[1], _lines[1], position*3)) 
       .Intersect(Find(Format[2], _lines[2], position*3)); 

      int[] result = found.ToArray(); 
      if (result.Length != 1) 
       throw new FormatException(); 
      return Characters[result[0]]; 
     } 

     IEnumerable<int> Find(string findIn, char[] text, int charIx) 
     { 
      for(int i=1; i < findIn.Length; i += 4) 
      { 
       if (findIn[i] == text[charIx] && findIn[i + 1] == text[charIx + 1] && findIn[i + 2] == text[charIx + 2]) 
        yield return i/4; 
      } 
     } 

     public string ReadLine() 
     { 
      char[] text = new char[Count]; 
      for (int ix = 0; ix < Count; ix++) 
       text[ix] = Read(ix); 
      return new String(text); 
     } 
    } 

見前程序輸出以下文字:

   _ _  _ _ _ _ _ _ 
_   | _| _||_||_ |_ ||_||_|| | 
    ___  ||_ _| | _||_| ||_| _||_| 

-_ 1234567890 
_  _  _ _ _  _ _ 
|_||_ | _||_ |_ | |_| | ||/ | |\| 
| ||_||_ |_||_ | |_-| | | _||\ |_ ||| 

abcdefghijklm 
     _ _ _ _ ___    __ 
|\| _ |_||_||_|/_ | | || |||| \/ \//
| ||_|| ||\ _/ | |_||/ |/| /\ | /_ 

nopqrstuvwxyz 
0

如何擴展方法:

public static string[] SplitIntoNumbers(this string str) 
    { 
     var lines = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); 
     var columns = lines 
      .Select(x => x.InSetsOf(3).Select(y => new string(y.ToArray())).ToList()) 
      .ToList(); 
     var numbers = Enumerable.Range(0, columns[0].Count) 
      .Select(x => columns[0][x] + columns[1][x] + columns[2][x]) 
      .ToArray(); 
     return numbers; 
    } 

假設a compatible implementation of InSetsOf()被可用。

用法:

 var result = input.SplitIntoNumbers();