繁体   English   中英

扫雷程序,意外 output

[英]Minesweeper Program, unexpected output

我正在做一个来自 Steven Skiena(编程挑战)的问题(扫雷)。 在那里你必须 output 与那个广场相邻的地雷数量。

#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>m>>n;
char a[m][n];
for(int i=0;i<m;i++)
{
    for (int j = 0; j < n; j++)
    {
        cin>>a[i][j];
    }
}

for (int i = 0; i < m; i++)
{
    for (int j = 0; j < n; j++)
    {
        if(a[i][j]!='*')
        {
            int no=0;
            if(a[i-1][j-1]=='*')
            no++;
            else if(a[i][j-1]=='*')
            no++;
            else if(a[i+1][j-1]=='*')
            no++;
            else if(a[i+1][j]=='*')
            no++;
            else if(a[i+1][j+1]=='*')
            no++;
            else if(a[i][j+1]=='*')
            no++;
            else if(a[i-1][j+1]=='*')
            no++;
            else if(a[i-1][j]=='*')
            no++;
            a[i][j]=(char)no;
        }
    }

}


for(int i=0;i<m;i++)
{
    for (int j=0; j<n; j++)
    {
        cout<<a[i][j];
    }
    cout<<endl;
}


return 0;
}

当我尝试运行这个程序时,没有放置地雷的数组是空白的。 是不是跟integer选角色有关?

一个错误是这样的:

a[i][j]=(char)no;

这不是将一位数 integer 转换为char表示的方式。

正确的方法是在 integer 上加'0'

a[i][j] = no + '0';

这样做的原因是数字的字符表示与实际数字值不同。 例如,ASCII 整理序列使用 48 作为字符'0' ,49 作为'1' ,50 作为'2' ,等等。

因此添加'0' ,即 48,将为您提供数字的字符表示。

你可以像这样改变你的程序:

我将您的数组更改为 int 数组,所有地雷都是-1 因此,您不必在一个数组中混合使用 int 值和 char 值。 有了这个,你必须用 if 条件在 output 中处理这个。

#include<iostream>
using namespace std;

int main()
{
    int n,m;
    cin>>m>>n;
    char a[m][n];

    for(int i=0;i<m;i++)
    {
        for (int j = 0; j < n; j++)
        {
            char in;
            cin>>in;
            if(in == '*') {
                a[i][j] = -1;
            } else {
                a[i][j] = 0;
            }
        }
    }

    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if(a[i][j]!=-1)
            {
                int no=0;
                if(a[i-1][j-1]==-1)
                no++;
                else if(a[i][j-1]==-1)
                no++;
                else if(a[i+1][j-1]==-1)
                no++;
                else if(a[i+1][j]==-1)
                no++;
                else if(a[i+1][j+1]==-1)
                no++;
                else if(a[i][j+1]==-1)
                no++;
                else if(a[i-1][j+1]==-1)
                no++;
                else if(a[i-1][j]==-1)
                no++;
                a[i][j]=no;
            }
        }

    }


    for(int i=0;i<m;i++)
    {
        for (int j=0; j<n; j++)
        {
            if(a[i][j] == -1) {
                cout<<" * ";
            } else {
                cout<<" "<<a[i][j]<<" ";
            }
        }
        cout<<endl;
    }

    return 0;
}

既然看起来人们在给男人送鱼,我看不出有什么理由不这样做。 在计算上改变一个很好的解决方案的 no 启动方式。

    char no='0';

我在这里看到一些单独的问题,它们共同导致了您遇到的问题。

首先,如上所述,一旦您计算了与每个地雷相邻的地雷数量,您当前存储结果的方式将不会按照您期望的方式打印。 这里的其他答案建议了几种不同的方法可以做到这一点。

其次,您计算相邻地雷的方法(稍微)不正确。 让我们看看这段代码:

if(a[i-1][j-1]==-1)
   no++;
else if(a[i][j-1]==-1)
   no++;
else if(a[i+1][j-1]==-1)
   no++;
else if(a[i+1][j]==-1)
   no++;
else if(a[i+1][j+1]==-1)
   no++;
else if(a[i][j+1]==-1)
   no++;
else if(a[i-1][j+1]==-1)
   no++;
else if(a[i-1][j]==-1)
   no++;

您在此处使用的模式if / else if / else if /... 意味着最多将执行其中一个分支。 也就是说,一旦此代码找到地雷,它就会停止查看单元格周围的其他位置以查找其他地雷。 解决此问题的一种方法是使它不是if / else if的链,而只是if的常规链:

if(a[i-1][j-1]==-1)
   no++;
if(a[i][j-1]==-1)
   no++;
if(a[i+1][j-1]==-1)
   no++;
if(a[i+1][j]==-1)
   no++;
if(a[i+1][j+1]==-1)
   no++;
if(a[i][j+1]==-1)
   no++;
if(a[i-1][j+1]==-1)
   no++;
if(a[i-1][j]==-1)
   no++;

您甚至可能想考虑更改您的结构,这样您就可以使用双重嵌套的 for 循环来枚举距离您一步之遥的所有位置,而不是使用一长串if语句。 这将压缩代码并使其更清楚地匹配“对于每个相邻位置,如果它是地雷,则将其算作地雷”的模式。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM