您的位置:首页 > 其它

识别被挤压的数字图像(蛮有趣)

2008-02-24 21:18 183 查看
给定一个仅包括加法运算的算式,请计算出结果。

算式以类似下面的形式给出:

@ @@@ @@@ @ @ @@@ @ @@@ @@@ @@@ @@@ @@@

@ @ @ @ @ @ @ @ @ @ @ @ @ @ @

@ @@@ @@@ @@@ @@@ @@@ @@@ @ @@@ @@@ @ @

@ @ @ @ @ @ @ @ @ @ @ @ @ @

@ @@@ @@@ @ @@@ @ @@@ @ @@@ @@@ @@@

数字和+号的位置大小比例以及笔画长短粗细间距都是可变的。例如上面的算式也可以是这样:

@@@@

@@ @@@ @@@@ @@@ @@@ @@@ @@@ @@@@@

@@ @@@ @@ @ @@@ @ @ @ @ @ @@@@@

@@ @ @@@@ @ @ @ @ @ @ @ @ @ @ @@ @@

@@ @@@ @@@@ @@@ @@@ @@@ @@@ @ @@@ @@@ @@@@@

@@ @ @@ @ @ @ @ @ @ @ @ @ @@@@@

@@ @@@ @@@@ @ @@@ @ @@@ @ @@@ @@@

@@@@ @

@

但是保证不会发生笔画的缺损断裂歪斜扭曲等情况,所有字符在外形上都是可以辨识的,不会与其他字符发生混淆。相邻两个字符之间至少使用一列空格符分隔。

输入文件expression.in中包含了一个算式,文件总行数不超过100,每行不超过100个字符。运算的最终结果不超过10000000。算式只由@组成。

在expression.out中输出单独一行一个整数表示最终的运算结果。

输入样例:

@

@ @

@@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@ @@@

@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @ @ @

@@@@@@@@@@@@@@ @ @@@ @

@ @

@@@

@

@@@

输出样例:33

上面是挤压的:7+11+15

这题思想不难,写起来有点烦~~过程如下

1.先通过一次扫描将每个数字的下标和所占的宽度记录到sign[]数组中

2.然后依次横向压缩放入compressStr1

3.再将comperessStr1纵向压缩放入comperssStr2

这里的压缩就是如果上一行(列)与下一行相同则取出上一行(列)

-------b.txt--

@

@ @

@@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@ @@@

@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @

@@@@@@@@@@@@@@@ @ @ @

@@@@@@@@@@@@@@ @ @@@ @

@ @

@@@

@

@@@

--------------

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

namespace ConsoleApplication2

{

//记录分割的起始地址下标和宽度

class Sign

{

public int idx = 0;

public int len = 0;

public Sign(int i, int l)

{

idx = i; len = l;

}

}

class Program

{

int adjust()

{

//结束施放

using (

StreamReader sr = new StreamReader(new FileStream(Environment.CurrentDirectory + "//b.txt"

, FileMode.Open, FileAccess.Read)))

{

//存储算式

string[] str1 = new string[100];

//行数

int maxRows = 0;

int maxCols=0;

//载入

while (!sr.EndOfStream)

{

str1[maxRows++] = sr.ReadLine();

}

//打印

print(str1,maxRows);

int tmp=0;

//获取maxCols的值

for (int row = 0; row < maxRows; row++)

{

tmp = str1[row].Length;

if (maxCols < tmp)

maxCols = tmp;

}

//该列的空格数

int[] spaceCount=new int[maxCols];

//找到全空列

for (int row = 0; row < maxRows; row++)

{

for (int col = 0; col <str1[row].Length ; col++)

{

//出现@则修改spacCount

if (str1[row][col].ToString() == "@")

spaceCount[col]=1;

}

}

//分割的下标位置

int[] partitionIndex = new int[maxCols/2];

//精确标识下标及其长度

List<Sign> signIndex = new List<Sign>();

//获取不空列的下标

int pIdx = 0;

//取出所有字符所有在列的下标及其长度 singIndex

for(int col=0;col<maxCols;col++)

{

//当前列是有数字的的

if (spaceCount[col] == 1)

{

//连续len++

if (pIdx > 0 && (signIndex[signIndex.Count-1].idx == col -

signIndex[signIndex.Count-1].len))

{

signIndex[signIndex.Count - 1].len++;

}

else

{

signIndex.Add(new Sign(col, 1));

}

pIdx++;

}

}

//总字符数

int maxLetter = signIndex.Count;

//StringBuilder curSb = new StringBuilder();

//被压缩的字符

List<string>[] compressStr = new List<string>[maxLetter];

for (int idx = 0; idx < maxLetter;idx++ )

{

compressStr[idx] = new List<string>();

}

//逐个纵向字母压缩

for (int letter = 0; letter < maxLetter; letter++)//行扫描

{

//行数

for (int row = 0; row < maxRows; row++)

{

StringBuilder curRowSb = new StringBuilder();

//获取当前 当前row 中的字符串

for (int col = signIndex[letter].idx; col < signIndex[letter].idx+signIndex[letter].len;

col++)

{

if (col >= str1[row].Length)

{

curRowSb.Append(" ");

}

else

curRowSb.Append(str1[row][col]);

}

string emptys = EmptyString(signIndex[letter].len);

//空 或者与上一行相等

//压缩

if (curRowSb.ToString() == emptys || (compressStr[letter].Count > 0

&& compressStr[letter][compressStr[letter].Count - 1] == curRowSb.ToString()))

{

continue;//next row

}

else

{

compressStr[letter].Add(curRowSb.ToString());

}

//清空

curRowSb = null;

}

}

//第二次压缩

List<string>[] compressStr2 = new List<string>[maxLetter];

for (int idx = 0; idx < maxLetter; idx++)

{

compressStr2[idx] = new List<string>();

}

//横向压缩

for (int letter = 0; letter < maxLetter; letter++)

{

for (int col = 0; col < signIndex[letter].len; col++)

{

StringBuilder comp1ColSb = new StringBuilder();

for (int row=0;row<compressStr[letter].Count; row++)

{

if(col<compressStr[letter][row].Length)

comp1ColSb.Append(compressStr[letter][row][col]);

else

comp1ColSb.Append(" ");

}

//已经加到

StringBuilder comp2ColSb = new StringBuilder();

//压缩

if (compressStr2[letter].Count > 0 )

{

//获取letter的col列

for (int row = 0; row < compressStr2[letter].Count; row++)

{

comp2ColSb.Append(compressStr2[letter][row][compressStr2[letter][row].Length-1]);

}

//相等列

if (comp1ColSb.ToString() == comp2ColSb.ToString())

continue;

else//插入列

{

//count 为行数

for (int row = 0; row < compressStr2[letter].Count; row++)

{

//c2ColSb为当前列

compressStr2[letter][row] += comp1ColSb[row].ToString();

}

}

}

else

{

//建立rows

for (int row = 0; row < comp1ColSb.Length; row++)

{

//c2ColSb为当前列

compressStr2[letter].Add(comp1ColSb[row].ToString());

}

}

}

}

//运算

return compute(compressStr2);

}

}

//计算算式

int compute(List<string>[] cps)

{

StringBuilder cti = new StringBuilder();

for (int i = 0; i < cps.Length; i++)

{

StringBuilder sb = new StringBuilder();

for (int j = 0; j < cps[i].Count; j++)

{

sb.Append(cps[i][j]);

}

cti.Append(changetoint(sb.ToString()));

}

//下标

int index=0;

//结果

int tSum=0,resultSum=0;

//存取数

int tp=0;

while(index<cti.Length)

{

tSum = 0;

while(index<cti.Length&& int.TryParse(cti[index++].ToString(),out tp))

{

tSum = tSum * 10 + tp;

}

resultSum+=tSum;

}

return resultSum;

}

//将图像变成数字

char changetoint(string s)

{

switch (s)

{

case "@": return '1';

case "@@@ @@@@@ @@@": return '2';

case "@@ @@@ @@@": return '3';

case "@ @@@@ @": return '4';

case "@@@@ @@@ @@@@": return '5';

case "@@@@ @@@@ @@@@":return '6';

case "@@ @": return '7';

case "@@@@ @@@@@ @@@@": return '8';

case "@@@@ @@@@ @@@@": return '9';

case "@@@@ @@@@": return '0';

default: return '+';

}

}

string EmptyString(int n)

{

StringBuilder sb = new StringBuilder();

while (n-- > 0)

{

sb.Append(" ");

}

return sb.ToString();

}

void print(string[] str, int idx)

{

for(int i=0;i<idx;i++)

{

Console.WriteLine(str[i]);

}

}

static void Main(string[] args)

{

Program p = new Program();

Console.Write(p.adjust().ToString());

Console.ReadLine();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: