首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现GOTO语句

实现GOTO语句
EN

Stack Overflow用户
提问于 2016-08-22 05:45:15
回答 1查看 66关注 0票数 0

对于我的离线签名验证项目,我使用欧拉数作为拓扑特征。

我检查这个link,发现其中有一个伪代码,我的c#实现如下所示:

代码语言:javascript
复制
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());
    }

编译时说labelAlabelB超出了范围。我知道在这种风格下使用是不可能的,所以我试着修改代码,但我被困在这里了。我怎样才能让这段代码工作呢?

EN

回答 1

Stack Overflow用户

发布于 2016-08-22 07:56:37

以下是我认为是您尝试翻译论文伪代码的工作版本:

代码语言:javascript
复制
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:代码块几乎完全相同,只是在wcw2变量是否针对有效的循环迭代进行了更新方面有所不同。

现在,也就是说,您的代码中有其他几个关键缺陷:

  • 伪代码假定xy值的像素坐标值分别为1到M和1到N。但是C#数组是从0开始的,因此需要相应地调整xy的值。它们需要从1开始,而不是从2开始,并且不允许它们达到M和N,而是限制为小于这些值。
  • 您的代码使用了"jagged array"。这本身并不是错误的,只是您也未能正确地确定Y坐标的实际边界,而是使用与X坐标相同的值(即,您使用t.Length而不是t[x].Length)。对于这种类型的算法,锯齿数组的效率很低,使用起来也很笨拙,所以我继续将其更改为普通的二维数组。
  • 在代码中,您将当前xy值的四个像素的值存储在局部变量中。但是,在更改x值之后,您无法更新这些值。因此,goto-implemented循环的后续迭代将使用错误的像素值。我删除了本地变量,并更改了代码,以便在需要时使用当前的xy值直接检索像素值。实际上,在这个版本的代码中,每个特定的像素在代码中只有一个位置,所以本地变量根本不会添加任何东西,即使以这种方式存储值是正确的。
  • 您在离开内部循环后无法递增y值。

我还对代码进行了一些清理,删除了多余的break语句(在goto语句之后有它们),删除了bool比较,而不是直接使用bool表达式值,并更改方法以返回最终值,而不是尝试显示它(调用者可以执行…像这样的数学助手函数不应该也负责提供用户交互)。

如果没有来自您的样本数据和预期输出,我无法确认翻译是否正确。我可以保证的是,这个版本比您开始时更接近论文的正确翻译,而且当然是有效的、可编译的C#代码。:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39069132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档