如何使用c#从文本文件(如ascii艺术)中提取数字?
我怎样才能得到用棍子编码的ascii码 数字在txt文件中,包含以下内容: 我必须让那些被棍子淹死的裸体人 第一步是得到4行,然后用字母表控制它 我以字符串形式获取文本[]如何使用c#从文本文件(如ascii艺术)中提取数字?,c#,winforms,ascii-art,C#,Winforms,Ascii Art,我怎样才能得到用棍子编码的ascii码 数字在txt文件中,包含以下内容: 我必须让那些被棍子淹死的裸体人 第一步是得到4行,然后用字母表控制它 我以字符串形式获取文本[] string[] lines = File.ReadAllLines("SourceFile.txt"); 前4行最多为行[3]。 如何控制同一位置的不同线路? 它就像一个2d数组,或者我必须做其他事情?首先,您需要一个对象来存储符号的模式和度量(在您的情况下是数字)。此外,该对象还有一种识别其在给定阵列中模式的方法:
string[] lines = File.ReadAllLines("SourceFile.txt");
前4行最多为行[3]。
如何控制同一位置的不同线路?
它就像一个2d数组,或者我必须做其他事情?首先,您需要一个对象来存储符号的模式和度量(在您的情况下是数字)。此外,该对象还有一种识别其在给定阵列中模式的方法:
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;
}
}
公共类AsciiNumber
{
私有只读字符[][].\u数据;
公共AsciiNumber(字符,字符[][]数据)
{
这个。_data=数据;
这个。字符=字符;
}
公共字符
{
得到;
私人设置;
}
公共整数宽度
{
得到
{
返回此。\u数据[0]。长度;
}
}
公共内部高度
{
得到
{
返回此值。_data.Length;
}
}
公共布尔匹配(字符串[]源,int startRow,int startColumn)
{
if(startRow+this.Height>source.Length)
{
返回false;
}
对于(var i=startRow;irow.Length)
{
返回false;
}
对于(var j=startColumn;j
然后,您可以创建类似于您所处理的字母表的内容(我只使用了数字1和3):
公共静态类字母表
{
私有静态只读AsciiNumber Number1=新AsciiNumber('1',新[]{
新[]{'|'},
新[]{'|'},
新[]{'|'},
新[]{'|'},
});
私有静态只读AsciiNumber Number3=新AsciiNumber('3',新[]{
新[]{'-','-','-'},
新[]{','''/'},
新[]{',''''\'},
新[]{'-','-','-'},
});
public static readonly IEnumerable All=new[]{Number1,Number3};
}
假设源文件中的数字具有永久性和相等高度,您可以尝试以下代码:
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());
string[]lines=File.ReadAllLines(“SourceFile.txt”);
var-lineHeight=4;
var text=新的StringBuilder();
对于(变量i=0;icharacter.match(lines,i,j));
如果(匹配!=null)
{
text.Append(match.Character);
j+=匹配宽度;
}
其他的
{
j++;
}
}
}
WriteLine(“识别的数字:{0}”,text.ToString());
注意:如果文件的行高发生变化,您必须改进上面的代码。假设我们有这个文本,我们想解析其中的数字:
--- --- | | | -----
/ _| | |__| |___
\ | | | |
-- --- | | ____|
首先,我们应该删除任何不必要的空白(或制表符,如果有的话),并在数字之间放置分隔符char(例如,$
),获得类似的结果:
$---$---$|$| |$-----$
$ / $ _|$|$|__|$|___ $
$ \ $| $|$ |$ |$
$-- $---$|$ |$____|$
现在我们应该在文本的每一行调用Split
函数,使用$
作为分隔符,然后将结果与字母表进行比较
让我们看看如何使用代码来实现这一点。给定要分析的文本string[]行
,我们将创建一个扩展方法来删除不必要的空格,并放置一个分隔符
char/string:
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;
}
}
及
其中ascinumbersparser
是此类:
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());
}
}
最后,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.
static void Main()
{
字符串ascistring=@”
--- --- | | | -----
/ _| | |__| |___
\ | | | |
-- --- | | ____| ";
字符串[]行=
ascistring.Split(新[]{“\n”,“\r\n”},StringSplitOptions.RemoveEmptyEntries);
lines=lines.ReplaceSpacesWithSeparator($);
ASCIINumbersParser=新的ASCIINumbersParser(行“$”);
//尝试查找ASCII字符串中包含的所有数字
foreach(parser.CandidatesList中的字符串[]候选)
{
对于(int i=1;i<10;++i)
{
字符串[]num=ASCIINumberHelper.GetASCIIRepresentationForNumber(i);
if(ASCIINumberHelper.ASCIIRepresentationMatch(num,候选者))
WriteLine(“在字符串中找到了编号{0}。”,i);
}
}
}
//预期产出:
//在字符串中找到了数字3。
//在字符串中找到了数字2。
//在字符串中找到了数字1。
//在字符串中找到了数字4。
//在字符串中找到了数字5。
您可以找到完整的代码
ASCIINumbersParser parser = new ASCIINumbersParser(lines, "$");
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());
}
}
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;
}
}
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.