C语言程序设计现代方法第二版,第八章课后编程题——第9题"生成贯穿10乘10字符组的随机步法"

C语言现代方法:第八章第9题编程题——自己做个笔记

本书的官方源码地址及github地址:

http://knking.com/books/c2/answers/index.html

https://github.com/fordea/c-programming-a-modern-approach

题目描述:

生成一种贯穿10x10字符数组(初始时权威字符点‘.’ )的“随机步法”。程序必须随机地从一个元素“走到”另一个元素,每次都想上、向下、向左或向右移动一个元素。已访问过的元素按访问顺序用字符A到Z进行标记。

上一张原书对此题的描述:

代码如下:

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

#define N 10

int main(void){
    // 棋盘初始化
    char ch[N][N]={'.'};
    
    for(int i =0 ; i < N ; i++){
        for(int j = 0; j < N ;j++){
            ch[i][j]='.';
        }
    }
    
    srand((unsigned int) time(NULL));    // 生成随机数前,先调用 srand 函数
    bool point[N][N]={false};    // 此bool型所有元素,必须先初始化。因为我调试了好久发现,如果不初始化,程序运行后,棋盘有的为true,有的为fale。
    int ptx = 0,pty = 0;        // 数组元素的横纵坐标
    
    ch[0][0] = 'A';            // 给 A 一个初始化,程序总是从ch[0][0] = 'A' 开始打印的
    point[0][0] = 1;

//简单讲个小故事,分析一下代码~~~~~~~~~~~此段可略过
//    现在假设我们站在十字路口——即一个 crossroads[4][3],
//    我们面临4个方向,但是要随机产生一个方向通过,
//    0:表示这个点没有字母,为false。
//    某个位置的字母这样表示 ch[temp_ptx][temp_pty]
//    temp_ptx:以"十字路口"为起点,下一个字母所在位置的temp_ptx值,
//    temp_pty:以"十字路口"为起点,下一个字母所在位置的temp_pty值。
//    所以,我们要全力打造出如下形式的数组,冲鸭!!!
//    int crossroads[4][3] = {
//        {0,temp_ptx,temp_pty},
//        {0,temp_ptx,temp_pty},
//        {0,temp_ptx,temp_pty},
//        {0,temp_ptx,temp_pty}
//    };

    int k = 0;  // 根据k的值,可以判断crossroads数组元素有几个(十字路口的出口个数)
    int m = 0 , n = 0;  // crossroads 下标
    int letusgo = 0;    // 出口方向——冲鸭!!!

    for(int Alphabet = 0; Alphabet < 25; Alphabet++){ //'A'已经有了,剩余那25个在此等候
    
    // crossroads 的 4 种出口情况
        m = 0 ; n = 0 ;    // m ,n 出口下标清零
        k = 0;      //根据 k 的值,计算出口的个数
        int crossroads[4][3];
        int temp_ptx = ptx;  // 每次循环,用临时变量temp_ptx和temp_pty记住上次所在位置,
        int temp_pty = pty; // 要是直接用全局变量ptx和pty,你会迷路的!!!嘿嘿!
//  第一种情况:南下
        if((ptx+1)>0 && (ptx+1)<=9){
            temp_ptx = ptx + 1;
            temp_pty = pty;
            if(!point[temp_ptx][temp_pty]){
                crossroads[m][n] = point[temp_ptx][temp_pty];
                crossroads[m][n+1] = temp_ptx;
                crossroads[m][n+2] = temp_pty;
                k++;
            }
        }
//  第二种情况:右路
        if((pty+1)>0 && (pty+1)<=9){
            
            temp_ptx = ptx;
            temp_pty = pty + 1;
            if(!point[temp_ptx][temp_pty]){
                if(k!=0){    // 在m++前,别忘了判断 k 的值,
                    m++;    //否则程序怎么知道crossroads[0][0] 有没有元素。
                }
                crossroads[m][n] = point[temp_ptx][temp_pty];
                crossroads[m][n+1] = temp_ptx;
                crossroads[m][n+2] = temp_pty;
                k++;
            }
        }
//  第三种情况:北上
        if((ptx-1)>=0 && (ptx-1)<10){
           
            temp_ptx = ptx - 1;
            temp_pty = pty;
            if(!point[temp_ptx][temp_pty]){
                if(k!=0){
                    m++;
                }
                crossroads[m][n] = point[temp_ptx][temp_pty];
                crossroads[m][n+1] = temp_ptx;
                crossroads[m][n+2] = temp_pty;
                k++;
            }
        }
//  第四种情况:左路
        if((pty-1)>=0 && (pty-1)<10){
            
            temp_ptx = ptx;
            temp_pty = pty - 1;
            if(!point[temp_ptx][temp_pty]){
                if(k!=0){
                    m++;
                }
                crossroads[m][n] = point[temp_ptx][temp_pty];
                crossroads[m][n+1] = temp_ptx;
                crossroads[m][n+2] = temp_pty;
                k++;
            }
        }
        
        if(k == 0 ){
            break;
        }else{
            letusgo = (int)(rand() % k );    // 根据k得知有几条路可选,随机选择一条路
            
            temp_ptx = crossroads[letusgo][1];
            temp_pty = crossroads[letusgo][2];
            point[temp_ptx][temp_pty] = 1;  // 确定下一个点,赋值为true,这个点下次就不能再经过了
            ch[temp_ptx][temp_pty] = ch[ptx][pty]+1 ;// 按字母表顺序,确定下一个字母
            ptx = temp_ptx;        // 把上一个点的位置覆盖,然后进入下一个循环
            pty = temp_pty;

        }

    }
    

//**********  打印最终结果  ***************
    for(int i =0 ; i < N ; i++){
        for(int j = 0; j < N ;j++){
            printf("%c ", ch[i][j]);
        }
        printf("\n");
    }
//****************************************
    return 0;
}

 

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值