c# - 一次读取一个字符串,3x3 个字符

标签 c# string split

想象一下这个字符串:

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

拆分此字符串以便每个数字都可以由它自己处理的最简单/最好的方法是什么?

我在想类似的东西

public string[] SplitIntoNumbers(string input)

结果会怎样

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

有什么想法吗?

编辑
对于想要更多信息的人 - 问题来自 BankOCR -kata 在 CodingDojo .我意识到有多种方法可以“完成工作”——解决方案,但我觉得必须有一种更“奇特”的方法来解决它。类似 clojure 的东西。

最佳答案

你问:

What would be the easiest / nicest way of splitting this string so that each number could be handled by it self?

...我认为您可能过于从 OO 的角度来处理这个问题。您所说的实际上是一种“字体”,而不是一组字符。坦率地说,我只是将逻辑包装到一个类中,并完全按照您在这篇文章中所做的那样定义字符数据。它易于查看、编辑和维护。

如果您的最终目标只是渲染,还是解析,我从您的原始帖子中无法理解。不管怎样,我不能只停留在数字上;)

    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 = " -0123456789_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

关于c# - 一次读取一个字符串,3x3 个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7235688/

相关文章:

C# 在关闭应用程序后打开文件

c# - 如何在 C# 中终止线程?

Python - 删除字符串的前两行

javascript - 在 Javascript 中用空格拆分数组行

regex - 为 csplit 寻找正确的正则表达式

javascript - ASP.Net Core 3 将 JSON 数组发布到 Controller

c# - Windows 服务中 RuntimeHelpers.PrepareMethod 的缺点

string - Coldfusion:将新行插入字符串

c++ - 使用后缀自动机的最长公共(public)子串

string - Lua:分割字符串并将两个数字作为单独的变量