对于我的离线签名验证项目,我使用欧拉数作为拓扑特征。
我浏览了这个link,我发现了一个伪代码,我的c#实现如下:
public void eulers(bool[][] t)
{
int w2 = 0;
int wc = 0;
int eulers_number = 0;
int x = 2;
int y = 2;
while (y <= t.Length)
{
while (x <= t.Length)
{
bool p1 = t[x][y];
bool p2 = t[x - 1][y];
bool p3 = t[x][y - 1];
bool p4 = t[x - 1][y - 1];
if (p4 == true)
{
x++;
}
else if (p2 == false)
{
labelA:
if (p3 == true)
{
x = x + 2;
}
else if (p1 == false)
{
x++;
if (x <= t.Length)
{
goto labelA;
break;
}
}
else
{
w2++;
x++;
if (x <= t.Length)
{
goto labelB;
break;
}
}
}
else
{
labelB:
if (p3 == true)
{
wc++;
x = x + 2;
}
else if (p1 == false)
{
x++;
if (x <= t.Length)
{
goto labelA;
break;
}
}
else
{
x++;
if (x <= t.Length)
{
goto labelB;
break;
}
}
}
}
eulers_number = w2 - wc;
MessageBox.Show(eulers_number.ToString());
}
在编译时,labelA
和labelB
超出了范围。我知道不可能以这种风格使用,所以我试图修改代码,但我被困在这里。如何使此代码正常工作?
答案 0 :(得分:0)
以下是我认为您尝试翻译论文的伪代码的工作版本:
static int eulers(bool[,] pixel)
{
int w2 = 0;
int wc = 0;
int x = 1;
int y = 1;
int M = pixel.GetLength(0), N = pixel.GetLength(1);
while (y < N)
{
while (x < M)
{
if (pixel[x - 1, y - 1])
{
x++;
}
else
{
bool labelA = !pixel[x - 1, y];
while (true)
{
if (pixel[x, y - 1])
{
if (!labelA)
{
wc++;
}
x = x + 2;
}
else if (!pixel[x, y])
{
x++;
if (x < N)
{
labelA = true;
continue;
}
}
else
{
if (labelA)
{
w2++;
}
x++;
if (x < N)
{
labelA = false;
continue;
}
}
break;
}
}
}
y++;
}
return w2 - wc;
}
在解决goto
语句方面,我通过创建一个小型状态机(具有单个切换状态,由labelA
变量表示)并使用while
来删除它们而是循环以允许执行流程返回到块的开头。此步骤的一个重要部分是认识到labelA:
和labelB:
代码块几乎完全相同,但wc
和w2
变量是否已更新为那个有效的迭代只是一个循环。
现在,那就是说,你的代码还有其他几个关键缺陷:
x
和y
值,伪代码假设像素坐标值范围从1到M,1到N,包括在内。但是C#数组是从0开始的,因此需要相应地调整x
和y
值。它们需要从1开始而不是2开始,并且不需要允许它们达到M和N,而是限制为小于这些值。t.Length
而不是t[x].Length
) 。对于这种类型的算法,锯齿状数组效率低下并且难以使用,因此我继续将其更改为普通的二维数组。x
和y
值的四个像素的值存储起来。但是,更改x
值后,您无法更新这些值。因此,goto
实现的循环的后续迭代将使用错误的像素值。我删除了局部变量,并将代码更改为只需在需要时使用当前x
和y
值直接检索像素值。实际上,在这个版本的代码中,每个特定的像素在代码中只有一个位置被检索到,因此局部变量无论如何都不会添加任何东西,即使以这种方式存储值是正确的。 y
值。我还清理了一些代码,删除了多余的break
语句(在goto
语句之后删除了它们),删除了bool
比较,而不是仅使用{直接{1}}表达式值,并更改方法以返回最终值而不是尝试显示它(调用者可以这样做......像这样的数学助手函数也不应该负责提供用户交互)。
如果没有您的样本数据和预期输出,我无法确认翻译是否正确。我可以保证的是,这个版本比你开始时更接近纸张的正确翻译,当然是有效的,可编译的C#代码。 :)