2015-08-28 26 views
1

我怎样才能得到用棍棒编码的ascii艺术的数字?如何从文本文件像ASCII码艺术与C#Tryparse数字?

的numberss是一个txt文件UND它包含此: Txt file source

我得被淹死用棍子nubmers。

第一步是获得4行,而不是用字母来控制它。

我得到的文本字符串中的[]

string[] lines = File.ReadAllLines("SourceFile.txt"); 

String from File

第一4线均达到线[3]。 我怎样才能控制不同的线在同一个位置? 它就像一个二维数组或我必须做其他事情?

+0

每个数字都有其独特的模式不是?你可以计算行数[0]中有多少个空格,并且看到第一行中有多少个数字。接下来的0到4行来形成数字,然后再计数5 – SamY

+0

,因为你知道有多少数字,你可以检查每个模式 – SamY

+0

@SamY是的,每个数字都有其独特的模式。我如何在Code中做你的logik? (要计算和控制模式?) –

回答

1

首先,您需要一个存储符号的模式和指标的对象(在您的案例中是数字)。也此对象具有对于给定的阵列中识别它的图案的方法:

public class AsciiNumber 
{ 
    private readonly char[][] _data; 

    public AsciiNumber(char character, char[][] data) 
    { 
     this._data = data; 
     this.Character = character; 
    } 

    public char Character 
    { 
     get; 
     private set; 
    } 

    public int Width 
    { 
     get 
     { 
      return this._data[0].Length; 
     } 
    } 

    public int Height 
    { 
     get 
     { 
      return this._data.Length; 
     } 
    } 

    public bool Match(string[] source, int startRow, int startColumn) 
    { 
     if (startRow + this.Height > source.Length) 
     { 
      return false; 
     } 

     for (var i = startRow; i < startRow + this.Height; i++) 
     { 
      var row = source[i]; 
      if (startColumn + this.Width > row.Length) 
      { 
       return false; 
      } 

      for (var j = startColumn; j < startColumn + this.Width; j++) 
      { 
       if (this._data[i - startRow][j - startColumn] != row[j]) 
       { 
        return false; 
       } 
      } 
     } 

     return true; 
    } 
} 

然后可以创建你处理类似字母(I只用数字1和3):

public static class Alphabet 
{ 
    private static readonly AsciiNumber Number1 = new AsciiNumber('1', new[]{ 
     new []{'|'}, 
     new []{'|'}, 
     new []{'|'}, 
     new []{'|'}, 
    }); 

    private static readonly AsciiNumber Number3 = new AsciiNumber('3', new[]{ 
     new []{'-','-','-'}, 
     new []{' ',' ','/'}, 
     new []{' ',' ','\\'}, 
     new []{'-','-','-'}, 
    }); 

    public static readonly IEnumerable<AsciiNumber> All = new[] { Number1, Number3 }; 
} 

假设在你的源文件编号已permament和平等的高度,你可以尝试这样的代码:

 string[] lines = File.ReadAllLines("SourceFile.txt"); 
     var lineHeight = 4; 

     var text = new StringBuilder(); 
     for (var i = 0; i < lines.Length; i += lineHeight) 
     { 
      var j = 0; 
      while (j < lines[i].Length) 
      { 
       var match = Alphabet.All.FirstOrDefault(character => character.Match(lines, i, j)); 
       if (match != null) 
       { 
        text.Append(match.Character); 
        j += match.Width; 
       } 
       else 
       { 
        j++; 
       } 
      } 
     } 
     Console.WriteLine("Recognized numbers: {0}", text.ToString()); 

NB如果行高改变了文件,你必须改进上面的代码。

+0

不知何故,我只能得到1的代码 –

+0

你有没有在字母表中加入其他数字?你是否理解我的代码的作用?虽然它与我的测试输入完全一致,但它可能会因输入而失败。使用调试器来了解错误。 –

0

让我们假设我们有这样的文字,我们希望它来解析数字:

---  ---  | | |  ----- 
/  _|  | |__|  |___  
\  |  |  |   | 
--  ---  |  |  ____| 

首先,我们应该去掉任何不必要的空格(或制表符,如果存在的话),并把一个分离器字符(如$)的数字之间,获得类似这样的东西:

$---$---$|$| |$-----$ 
$/$ _|$|$|__|$|___ $ 
$ \ $| $|$ |$ |$ 
$-- $---$|$ |$____|$ 

现在我们应该调用Split功能上的文本的每一行,使用$作为分隔符,然后比较resul与字母表。

让我们看看如何用代码来做到这一点。鉴于解析string[] lines文本,我们将创建一个扩展方法来去除不必要的空格,把一个separator字符/字符串,而不是:

public static class StringHelperClass 
{ 
    // Extension method to remove any unnecessary white-space and put a separator char instead. 
    public static string[] ReplaceSpacesWithSeparator(this string[] text, string separator) 
    { 
     // Create an array of StringBuilder, one for every line in the text. 
     StringBuilder[] stringBuilders = new StringBuilder[text.Length]; 

     // Initialize stringBuilders. 
     for (int n = 0; n < text.Length; n++) 
      stringBuilders[n] = new StringBuilder().Append(separator); 

     // Get shortest line in the text, in order to avoid Out Of Range Exception. 
     int shorterstLine = text.Min(line => line.Length); 

     // Temporary variables. 
     int lastSeparatorIndex = 0; 
     bool previousCharWasSpace = false; 

     // Start processing the text, char after char. 
     for (int n = 0; n < shorterstLine; ++n) 
     { 
      // Look for white-spaces on the same position on 
      // all the lines of the text. 
      if (text.All(line => line[n] == ' ')) 
      { 
       // Go to next char if previous char was also a white-space, 
       // or if this is the first white-space char of the text. 
       if (previousCharWasSpace || n == 0) 
       { 
        previousCharWasSpace = true; 
        lastSeparatorIndex = n + 1; 
        continue; 
       } 
       previousCharWasSpace = true; 

       // Append non white-space chars to the StringBuilder 
       // of each line, for later use. 
       for (int i = lastSeparatorIndex; i < n; ++i) 
       { 
        for (int j = 0; j < text.Length; j++) 
         stringBuilders[j].Append(text[j][i]); 
       } 

       // Append separator char. 
       for (int j = 0; j < text.Length; j++) 
        stringBuilders[j].Append(separator); 

       lastSeparatorIndex = n + 1; 
      } 
      else 
       previousCharWasSpace = false; 
     } 

     for (int j = 0; j < text.Length; j++) 
      text[j] = stringBuilders[j].ToString(); 

     // Return formatted text. 
     return text; 
    } 
} 

然后,在Main方法,我们将使用:

lines = lines.ReplaceSpacesWithSeparator("$"); 

ASCIINumbersParser parser = new ASCIINumbersParser(lines, "$"); 

其中ASCIINumbersParser是这个类:

public class ASCIINumbersParser 
{ 
    // Will store a list of all the possible numbers 
    // found in the text. 
    public List<string[]> CandidatesList { get; } 

    public ASCIINumbersParser(string[] text, string separator) 
    { 
     CandidatesList = new List<string[]>(); 

     string[][] candidates = new string[text.Length][]; 

     for (int n = 0; n < text.Length; ++n) 
     { 
      // Split each line in the text, using the separator char/string. 
      candidates[n] = 
       text[n].Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries); 
     } 

     // Put the strings in such a way that each CandidateList item 
     // contains only one possible number found in the text. 
     for (int i = 0; i < candidates[0].Length; ++i) 
      CandidatesList.Add(candidates.Select(c => c[i]).ToArray()); 
    } 
} 

在这一点上,我们将使用下面的类来生成一些数字的ASCII艺术表现,并与我们的原始字符串比较的结果(在Main):

public static class ASCIINumberHelper 
{ 
    // Get an ASCII art representation of a number. 
    public static string[] GetASCIIRepresentationForNumber(int number) 
    { 
     switch (number) 
     { 
      case 1: 
       return new[] 
       { 
        "|", 
        "|", 
        "|", 
        "|" 
       }; 
      case 2: 
       return new[] 
       { 
        "---", 
        " _|", 
        "| ", 
        "---" 
       }; 
      case 3: 
       return new[] 
       { 
        "---", 
        "/", 
        @" \ ", 
        "-- " 
       }; 
      case 4: 
       return new[] 
       { 
        "| |", 
        "|__|", 
        " |", 
        " |" 
       }; 
      case 5: 
       return new[] 
       { 
        "-----", 
        "|___ ", 
        " |", 
        "____|" 
       }; 
      default: 
       return null; 
     } 
    } 

    // See if two numbers represented as ASCII art are equal. 
    public static bool ASCIIRepresentationMatch(string[] number1, string[] number2) 
    { 
     // Return false if the any of the two numbers is null 
     // or their lenght is different. 

     // if (number1 == null || number2 == null) 
     //  return false; 
     // if (number1.Length != number2.Length) 
     //  return false; 

     if (number1?.Length != number2?.Length) 
      return false; 

     try 
     { 
      for (int n = 0; n < number1.Length; ++n) 
      { 
       if (number1[n].CompareTo(number2[n]) != 0) 
        return false; 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Error: " + ex); 
      return false; 
     } 

     return true; 
    } 
} 

最后,该Main功能看起来就像这样:

static void Main() 
    { 
     string ASCIIString = @" 
      ---  ---  | | |  ----- 
      /  _|  | |__|  |___  
      \  |  |  |   | 
      --  ---  |  |  ____| "; 

     string[] lines = 
      ASCIIString.Split(new[] {"\n","\r\n"}, StringSplitOptions.RemoveEmptyEntries); 

     lines = lines.ReplaceSpacesWithSeparator("$"); 

     ASCIINumbersParser parser = new ASCIINumbersParser(lines, "$"); 

     // Try to find all numbers contained in the ASCII string 
     foreach (string[] candidate in parser.CandidatesList) 
     { 
      for (int i = 1; i < 10; ++i) 
      { 
       string[] num = ASCIINumberHelper.GetASCIIRepresentationForNumber(i); 
       if (ASCIINumberHelper.ASCIIRepresentationMatch(num, candidate)) 
        Console.WriteLine("Number {0} was found in the string.", i); 
      } 
     } 
    } 

    // Expected output: 
    // Number 3 was found in the string. 
    // Number 2 was found in the string. 
    // Number 1 was found in the string. 
    // Number 4 was found in the string. 
    // Number 5 was found in the string. 

Here你可以找到完整的代码。