1

我在 Win7 x64 上的 4.7.2 上使用 MinGW GCC

这是练习:

http://postimg.org/image/v4xnpcxc3/

这是我未完成的代码(没有有效的退出循环条件)不起作用(字母永远不会出现在一行或一列中。我尝试调试程序并且在调试器代码中工作??!!):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

int main(void)
{
    char array[10][10];
    int direction = 0;
    int i = 0, j = 0, cnt = 1;
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
            array[i][j] = '*';
        }
    }
    int z = 200;
    array[i][j] = 'A';
    while(z-- > 0)
    {
        srand((unsigned)time(NULL));
        direction = rand() % 4;
        switch(direction)
        {
            case 0:
                if(i != 0)
                    i--; 
                break;
            case 1:
                if(j != 9)
                    j++; 
                break;
            case 2:
                if(i != 9)
                    i++;
                break;
            case 3:
                if(j != 0)
                    j--;
                break;
        }
        if(array[i][j] == '*')
        {
            array[i][j] = 'A' + cnt;
            cnt++;
        }       
        if(cnt == 26)
            break;
    } 
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
           printf("%c ", array[i][j]);
        }
        printf("\n");
    }
}
4

3 回答 3

2

第一的

  array[i][j] = 'A';

实际上与以下相同 array[0][0] = 'A';

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

for(int j = 0; j < 10; j++)

隐藏ij以前的声明:

int i = 0, j = 0, cnt = 1;

其次,在循环中调用srand之前rand是不好的。在程序开始时只调用srand一次。

于 2013-07-27T20:32:57.573 回答
1

出于好奇,我试图用 C++ 代码解决这个问题。我想我也可以分担努力。

我选择了

  • 取消多维数组(这使得 IMO 更容易)
  • 通过显示发生的回溯使事物可调试

请注意,我对 lambdas 的使用“隐藏”了我的方法中受 OO 启发的性质。

  • apply()rollback()作用于history(pos, pending)状态
  • select()尝试从当前生成一个有效的、未经尝试的移动,如果成功则(pos, board)返回true

其余的都是内联记录的。

住在科利鲁

#include <functional>
#include <random>
#include <array>
#include <iostream>
#include <set>
#include <deque>

typedef int pos_t;
static const char Empty = '.';

enum direction : int { N = -10, S = 10, E = 1, W = -1, None = 0 };

std::ostream& operator<<(std::ostream& os, direction d);

direction random_direction()
{
    static const std::array<direction, 4> steps { { N, S, E, W } };
    static auto gen = std::bind(std::uniform_int_distribution<int>(0,steps.size()), std::mt19937(time(NULL)));
    return steps[gen()];
}

struct move
{
    direction           taken = None;
    std::set<direction> tried;
};

int main()
{
    std::vector<char> board(100, Empty);

    pos_t pos    = 0;
    char station = 'A';
    board[pos]   = station++;

    // generate moves
    std::deque<move> history {}; // start with an empty move
    move pending {};

    auto select = [&] () -> bool
    { 
        auto& taken = pending.taken;
        auto& tried = pending.tried;

        pos_t nw;

        do
        {
            // random untried direction
            do    taken        = random_direction();
            while (end(tried) != tried.find(taken));

            // calculate new position
            nw = pos + taken;

            // validate new position
            bool valid = 
                (nw>=0) && (nw<(int)board.size()) && // within bounds?
                board[nw]==Empty &&                  // unvisited?
                // detect moving across the edge using invariant: 
                // INV: only col/row allowed to change
                ((pos%10 == nw%10) != (pos/10 == nw/10));

            // mark tried
            tried.insert(taken);

            // return if valid/no candidates
            if (valid || 4 == tried.size())
                return valid;

        } while (true); // try another direction
    };

    auto display = [&] {
        for(auto row = begin(board); row<end(board); row+=10)
            std::cout << std::string(row, row+10) << "\n";
    };

    auto apply = [&] () mutable {
        std::cout << pending.taken;

        pos        += pending.taken;
        board[pos]  = station++;

        history.emplace_back();
        std::swap(pending, history.back());
        //display();
    };

    auto backtrack = [&] () mutable {
        std::swap(pending, history.back());
        history.pop_back();
        std::cout << "[-" << pending.taken << "]";

        board[pos]  = (--station, Empty);
        pos        -= pending.taken;
        //display();
    };

    // game loop
    std::cout << "\nGenerating: ";

    while (station<='Z')
        select()? apply() : backtrack();

    std::cout << "\nResulting board: \n";

    display();
}

std::ostream& operator<<(std::ostream& os, direction d)
{
    switch(d) {
        case N : return os << 'N';
        case S : return os << 'S';
        case E : return os << 'E';
        case W : return os << 'W';
        default: break;
    };
    return os << "?";
}

示例运行:

Generating: ESW[-W]EN[-N]SSSENENWNEESSSWSEESESE
Resulting board: 
AB........
.CDMNO....
..ELKP....
..FIJQ....
..GHSR....
....TUV...
......WX..
.......YZ.
..........
..........
Generating: SENESEENW[-W]EESSWWWSESSESWWSS
Resulting board: 
ADE.IJK...
BCFGH.L...
...PONM...
...QR.....
....S.....
....TU....
...XWV....
...Y......
...Z......
..........
于 2013-07-27T23:00:57.283 回答
0

调试器通常会清除数据,即将变量设置为零。如果您检查例如NULL指针,但忘记初始化您检查的变量,那么它将在调试器中工作,但当您在调试器之外运行程序时不会。

于 2013-07-27T20:32:45.213 回答