zoukankan      html  css  js  c++  java
  • 迷宫问题&MakeFile

    先看一个有意思的问题, 我们定义一个二维数组表示迷宫。

    它表示一个迷宫, 其中的1表示墙壁,0表示可以走的路, 只能横着走或竖着走,不能斜着走,

    我们要编程序找出从左上角到右下角的路线。其实这个问题可以用深度优先搜索的方法搞定的了。

    这个算法中涉及到了几个知识:

    1. 一个是栈,每走过一个点会把这个点会把这个点压入栈中。

    2. 用一个新的数据结构保存走迷宫的路线,每个走过的点都有一个前趋(Predecessor)的点,表示是从哪儿走到

    当前点的,比如predecessor[4][4]是座标为(3, 4)的点,就表示从(3, 4)走到了(4, 4),一开始predecessor的各元素

    初始化为无效座标(-1, -1)。在迷宫中探索路线的同时就把路线保存在predecessor数组中。

    3. 已经走过的点在maze数组中记为2防止重复走。 算法的伪代码如下 :

    分为几个文件来分开实现 :

    /* main.c */

    /***********************************************************/
    /* Copyright (C) SA14226214, USTC, 2014-2015               */
    /*                                                         */
    /*  FILE NAME             :  main.c                   */
    /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
    /*  SUBSYSTEM NAME        :  MakFile                       */
    /*  MODULE NAME           :  makefile                      */
    /*  LANGUAGE              :  C                             */
    /*  TARGET ENVIRONMENT    :  ANY                           */
    /*  DATE OF FIRST RELEASE :  2015/04/05                    */
    /*  DESCRIPTION           :  This is a makefile program    */
    /***********************************************************/
    
    /*
     *Revision log:
     *
     *Ceated by GaoZhipeng, 2015/04/05
     *     
     */
    
    
    #include<stdio.h>
    #include"main.h"
    #include"stack.h"
    #include"maze.h"
    
    struct point predecessor[MAX_ROW][MAX_COL] = {
        {{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
        {{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
        {{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
        {{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
        {{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
    };
    
    
    void visit(int row, int col, struct point pre)
    {
        struct point visit_point = {row, col};
        maze[row][col] = 2;
        predecessor[row][col] = pre;
        push(visit_point);
    }
    
    int main(void)
    {
        struct point p = { 0, 0 };
        maze[p.row][p.col] = 2;
        push(p);
        while (!is_empty()) {
            p = pop();
            if (p.row == MAX_ROW - 1 /* goal */
                    && p.col == MAX_COL - 1)
                break;
            if (p.col+1 < MAX_COL
                    /* right */
                    && maze[p.row][p.col+1] == 0)
                visit(p.row, p.col+1, p);
            if (p.row+1 < MAX_ROW
                    /* down */
                    && maze[p.row+1][p.col] == 0)
                visit(p.row+1, p.col, p);
            if (p.col-1 >= 0
                    /* left */
                    && maze[p.row][p.col-1] == 0)
                visit(p.row, p.col-1, p);
            if (p.row-1 >= 0
                    /* up */
                    && maze[p.row-1][p.col] == 0)
                visit(p.row-1, p.col, p);
            print_maze();
        }
        if (p.row == MAX_ROW - 1 && p.col == MAX_COL - 1) {
            printf("(%d, %d)
    ", p.row, p.col);
            while (predecessor[p.row][p.col].row != -1) {
                p = predecessor[p.row][p.col];
                printf("(%d, %d)
    ", p.row, p.col);
            }
        } else
            printf("No path!
    ");
        return 0;
    }
    View Code

    /* main.h */

    /***********************************************************/
    /* Copyright (C) SA14226214, USTC, 2014-2015               */
    /*                                                         */
    /*  FILE NAME             :  main.h                   */
    /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
    /*  SUBSYSTEM NAME        :  MakFile                       */
    /*  MODULE NAME           :  makefile                      */
    /*  LANGUAGE              :  C                             */
    /*  TARGET ENVIRONMENT    :  ANY                           */
    /*  DATE OF FIRST RELEASE :  2015/04/05                    */
    /*  DESCRIPTION           :  This is a makefile program    */
    /***********************************************************/
    
    /*
     *Revision log:
     *
     *Ceated by GaoZhipeng, 2015/04/05
     *     
     */
    
    
    #ifndef MAIN_H
    #define MAIN_H
    
    typedef struct point{
        int row, col;
    } item_t;
    
    #define MAX_ROW 5
    #define MAX_COL 5
    
    #endif
    View Code

    /* maze.c */

    /***********************************************************/
    /* Copyright (C) SA14226214, USTC, 2014-2015               */
    /*                                                         */
    /*  FILE NAME             :  maze.c                   */
    /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
    /*  SUBSYSTEM NAME        :  MakFile                       */
    /*  MODULE NAME           :  makefile                      */
    /*  LANGUAGE              :  C                             */
    /*  TARGET ENVIRONMENT    :  ANY                           */
    /*  DATE OF FIRST RELEASE :  2015/04/05                    */
    /*  DESCRIPTION           :  This is a makefile program    */
    /***********************************************************/
    
    /*
     *Revision log:
     *
     *Ceated by GaoZhipeng, 2015/04/05
     *     
     */
    
    #include<stdio.h>
    #include"maze.h"
    
    int maze[MAX_ROW][MAX_COL] = {
        0, 1, 0, 0, 0,
        0, 1, 0, 1, 0,
        0, 0, 0, 0, 0,
        0, 1, 1, 1, 0,
        0, 0, 0, 1, 0,
    };
    
    void print_maze(void)
    {
        int i, j;
        for(i=0; i<MAX_ROW; i++)
        {
            for(j=0; j<MAX_COL; j++)
            {
                printf("%d ", maze[i][j]);
            }
            putchar('
    ');
        }
    
        printf("*********
    ");
    }
    View Code

    /* maze.h */

    /***********************************************************/
    /* Copyright (C) SA14226214, USTC, 2014-2015               */
    /*                                                         */
    /*  FILE NAME             :  maze.h                   */
    /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
    /*  SUBSYSTEM NAME        :  MakFile                       */
    /*  MODULE NAME           :  makefile                      */
    /*  LANGUAGE              :  C                             */
    /*  TARGET ENVIRONMENT    :  ANY                           */
    /*  DATE OF FIRST RELEASE :  2015/04/05                    */
    /*  DESCRIPTION           :  This is a makefile program    */
    /***********************************************************/
    
    /*
     *Revision log:
     *
     *Ceated by GaoZhipeng, 2015/04/05
     *     
     */
    
    
    #ifndef MAZE_H
    #define MAZE_H
    
    
    #include"main.h"
    
    
    
    extern int maze[MAX_ROW][MAX_COL];
    void print_maze(void);
    
    
    #endif
    View Code

    /* stack.c */

    /***********************************************************/
    /* Copyright (C) SA14226214, USTC, 2014-2015               */
    /*                                                         */
    /*  FILE NAME             :  stack.c                       */
    /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
    /*  SUBSYSTEM NAME        :  MakFile                       */
    /*  MODULE NAME           :  makefile                      */
    /*  LANGUAGE              :  C                             */
    /*  TARGET ENVIRONMENT    :  ANY                           */
    /*  DATE OF FIRST RELEASE :  2015/04/05                    */
    /*  DESCRIPTION           :  This is a makefile program    */
    /***********************************************************/
    
    /*
     *Revision log:
     *
     *Ceated by GaoZhipeng, 2015/04/05
     *     
     */
    
    #include"stack.h"
    
    static item_t stack[512];
    static int top = 0;
    
    
    void push(item_t p)
    {
        stack[top++] = p;
    }
    
    
    item_t pop(void)
    {
        return stack[--top];
    }
    
    int is_empty(void)
    {
        return top == 0;
    }
    View Code

    /* stack.h */

    /***********************************************************/
    /* Copyright (C) SA14226214, USTC, 2014-2015               */
    /*                                                         */
    /*  FILE NAME             :  stack.h                       */
    /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
    /*  SUBSYSTEM NAME        :  MakFile                       */
    /*  MODULE NAME           :  makefile                      */
    /*  LANGUAGE              :  C                             */
    /*  TARGET ENVIRONMENT    :  ANY                           */
    /*  DATE OF FIRST RELEASE :  2015/04/05                    */
    /*  DESCRIPTION           :  This is a makefile program    */
    /***********************************************************/
    
    /*
     *Revision log:
     *
     *Ceated by GaoZhipeng, 2015/04/05
     *     
     */
    
    
    #ifndef STACK_H
    #define STACK_H
    
    
    #include "main.h"
    
    extern void push(item_t);
    extern item_t pop(void);
    extern int is_empty(void);
    
    
    #endif
    View Code

     然后我们要做的就是在Linux下对上述程序进行编译和运行。

     对于程序的编译命令, 最原始的编译指令可以这样写:  $ gcc main.c stack.c maze.c -o main

     不过还有一个更加简便的操作, 那就是写一个Makefile文件和源代码放在同一个目录下面。下面是一个写好的Makefile

    # This is an simple makefile
    
    
    main : main.o stack.o maze.o
           gcc main.o stack.o maze.o -o main
        
    main.o : main.c main.h stack.h maze.h
             gcc -c main.c -o main.o
    
    stack.o : stack.c stack.h main.h
              gcc -c stack.c -o stack.o
    
    maze.o : maze.c maze.h main.h
             gcc -c maze.c -o maze.o
             
    clean : 
            @echo "cleanning the project"
            -rm main *.o
            @echo "cleanning completed"
    
    .PHONY : clean

     make 命令会自动读取当前目录下的Makefile 文件, 完成相应的编译步骤。Makefile由一组规则(Rule)组成,每条规则的格式是:

     例如 :  main: main.o stack.o maze.o
          gcc main.o stack.o maze.o -o main

    main 是这条规则的目标(Target),main.o、stack.o 和maze.o是这条规则的条件(Prerequisite)。目标和条件之间的关系是:欲更新目标,

    必须首先更新它的所有条件;所有条件中只要有一个条件被更新了,目标也必须随之被更新。所谓“更新”就是执行一遍规则中的命令列表,

    命令列表中的每条命令必须以一个Tab开头,注意不能是空格,Makefile的格式不像C语言的缩进那么随意,对于Makefile中的每个以Tab

    开头的命令,make 会创建一个Shell进程去执行它。

    Makefile中有一些常用的特殊变量 :

    • $@ ,表示规则中的目标。
    • $< ,表示规则中的第一个条件。
    • $?,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。
    • $^ ,表示规则中的所有条件,组成一个列表,以空格分隔。

    那么我们可以把Makefile进一步化简, 写成如下的形式:

    #this is a makefile
    
    all : main
    
    main : main.o stack.o maze.o
        gcc $^ -o $@
    
    main.o : main.h stack.h maze.h
    stack.o : stack.h main.h
    maze.o : maze.h main.h
    
    clean :
        -rm main *.o
    
    .PHONY: clean

    把命令 gcc main.o stack.o maze.o -o main 改写成 gcc $^ -o $@。

    这样即使以后又往条件里添加了新的目标文件,编译命令也不需要修改,减少了出错的可能。

  • 相关阅读:
    [转]读取并修改App.config文件
    [转]线程和进程的概念
    实习日志(3)
    实习日志2
    实习小感,回学校啦~~~~
    请教LUA高手一段代码,希望帮忙谢谢!
    实习的日子
    vs显示 error LNK2019: 无法解析的外部符号 _main解决办法
    创建一个新窗口进程并返回进程ID号和进程的主线程ID号
    显示基本图形界面第一天
  • 原文地址:https://www.cnblogs.com/beyond-Acm/p/4403085.html
Copyright © 2011-2022 走看看