【问题标题】:Wall destroying破坏墙
【发布时间】:2017-11-20 06:14:41
【问题描述】:

有一堵墙是用数字建造的。 0 表示有一个洞,方块不能坐在洞上。有人有一把特殊的枪,可以一次发射所有带有数字的方块。
所以我有一个叫墙的矩阵,必须写一把枪。我编写了程序,但我有一个问题,我不明白为什么会这样。在我的代码中

#include <iostream>
#include <cstdio>

using namespace std;

int createWall( int &height, int &length, int wall[][ 100 ], int shots )
{
    int i;
    int j;
    cin >> height;
    cin >> length;
    cin >> shots;
    for ( i = 0; i < height; i++ )
    {
        for ( j = 0; j < length; j++ )
        {
            cin >> wall[ i ][ j ];
        }
    }
    return shots;
}


void wallNow( int height, int length, int wall[][ 100 ] )
{
    int i;
    int j;
    for ( i = 0; i < height; i++ )
    {
        for ( j = 0; j < length; j++ )
        {
            cout << wall[ i ][ j ] << " ";
        }
        cout << "\n";
    }
}

void destroyWall( int height, int length, int wall[][100], int shots )
{
    int i;
    int j;
    int k;
    int x;
    int aimedBlocks;//number to be "destroyed"
    //set all aimedBlocks to 0
    for ( x = 0; x < shots; x++ )
    {
        cin >> aimedBlocks;
        for ( i = 0; i < height; i++ )
        {
            for ( k = 0; k < length; k++ )
            {
                if ( wall[ i ][ k ] == aimedBlocks )
                {
                    wall[ i ][ k ] = 0;
                }
            }
        }
    }

    int counter;//I use this variable because at some point I have a 0 followed only by 0's
    for ( i = 0; i < length; i++ )
    {
        j = height - 1;
        counter = 0;
        //if I find a 0 then I move all elements higher that it one step down
        while ( counter < height )
        {
            if ( wall[ j ][ i ] == 0 ) 
            {
                for ( k = j; k > 0; k-- )
                {
                    wall[ k ][ i ] = wall[ k - 1 ][ i ];
                }
                wall[ height - j - 1 ][ i ] = 0;
            }
            else
                j--;//I don't always go up ene step because the "block" droped in place of 0 may be 0
            counter++;
        }
    }
}

int main()
{
    int height;
    int length;
    int wall[ 100 ][ 100 ];
    int shots = 0;
    shots = createWall( height, length, wall, shots );
    destroyWall( height, length, wall, shots );
    wallNow( height, length, wall );
}

我真的不明白为什么wall[ height - j - 1 ][ i ] = 0; 行适用于以下示例中的前 4 列,而它不适用于最后一列。

格式输入:

height length shots
wall_0_0 ... wall_0_length
... ... ...
wall_height  ... wall_height_length
shot_0 ... shot_shots

输入:

4 5 3
3 5 4 5 1 
2 1 1 5 3 
1 1 5 5 1 
5 5 1 4 3
1 5 1

删除与151 匹配的所有值。墙体残骸必须沉入底部。

输出:

0 0 0 0 0 
0 0 0 0 0 
3 0 0 0 0 
2 0 4 4 3

预期:

0 0 0 0 0 
0 0 0 0 0 
3 0 0 0 3 
2 0 4 4 3

请帮我解决这个问题。我找不到它调试代码。

【问题讨论】:

  • 听起来你需要使用调试器。
  • @JamesRoot 我使用了调试器

标签: c++ matrix multidimensional-array


【解决方案1】:

你的算法很奇怪,我不明白你想做什么。

实现目标的一种简单方法是从墙的左到右进行迭代,然后从底部到顶部进行迭代。每次获得0 时,您都会在顶部搜索一个非零值,如果找到则交换它们。

示例(非常基本的可以改进):

for (size_t i = 0; i < length; i++) { // i is for iterate from left(0) to right(length - 1)
  size_t j = height; // j is for iterate from bot(height - 1) to top(0)
  while (j-- > 0) {
    if (wall[j][i] == 0) {
      size_t k = j; // k is for found a non zero value from j - 1 to the top(0)
      while (k-- > 0) {
        if (wall[k][i] != 0) {
          wall[j][i] = wall[k][i];
          wall[k][i] = 0;
          break;
        }
      }
    }
  }
}

注意:

  1. 我使用size_t,因为这是索引的类型。
  2. 我建议您切换到std::vector 并在 C++ 中对其使用迭代器。

【讨论】:

  • 我正在学习这就是我编写奇怪算法的原因。谢谢!为什么size_t 是索引的类型?
  • @Timʘtei en.cppreference.com/w/cpp/types/size_t。请记住,这种类型是无符号的。对于初学者来说操作起来可能很奇怪。但是你应该学习如何使用它。 stackoverflow.com/a/22587575/7076153
  • 我从第二个链接了解到的是不要使用无符号循环。
  • @Timʘtei 是的,这是我的观点,我不想影响你。有些人不同意使用无符号类型。我不希望你认为你必须使用size_t,因为有些人会不同意。顺便说一句,就像你用 C++ 编写代码一样,这个问题应该会消失,因为你应该使用 std::vectoriterator 这将为你隐藏它。
  • size_t 恰好是所有 stl 容器 size() 的返回类型,当然也用于索引。尽管如此,有符号索引在错误检测方面仍有一些优势,并且具有可用于表示未初始化的负值。大多数时候,我更喜欢自己将索引存储为已签名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
  • 2011-06-23
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多