数据结构机器人布线c++------(迷宫算法)

本题借鉴迷宫解题思路,迷宫算法见用栈解决迷宫问题(输出所有路径和最短路径)_晴天下的大头娃娃-CSDN博客

题目要求:

布线区域分成的方格阵列。要求确定连接方格s到方格d的最短布线方案。布线的时候,电路只能沿着直线或者直角布线,有障碍的方格做了封锁标记(X),其他线路不允许穿过被封锁的方格。

(1)用文件保存布线区域,用1、0分别表示某个格子是否有障碍;S,D表示起点和终点;

(2)给出最短的布线路径长度;

(3)用文件保存布线路径,用*表示布线的方格;

主要功能:

(1)从文件中读出题目的输入;

(2)向屏幕上打印出题目的计算结果;

运行结果:

data.txt文件存放布局区域,用1、0分别表示某个格子是否有障碍;S,D表示起点和终点;path.txt文件保存布线路径,用*表示布线的方格;

代码如下:

 main.cpp

#include<iostream>
#include <fstream>
#include <stdlib.h>
#include<cstring>
#include<stdio.h>
#include"seqStack.h"
#include"findpath.h"
#include"RWfile.h"
#define MaxSize    100     //栈最多元素个数
using namespace std;

int main()
{
    int row=0,col=0;
    int start_x,start_y,end_x,end_y;
    char line[100][100];
    input(line,row,col);     //读取文件

    cout<<"布线如下"<<endl;
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            cout<<line[i][j]<<" ";
        }
        cout<<endl;
    }

    findpos(line,row,col,start_x,start_y,end_x,end_y);
    //起始点定位

    cout<<endl;
    cout<<"布线所有路径如下:"<<endl;
    mgpath(line,row,col,start_x,start_y,end_x,end_y);
    //寻找可行路径

    cout<<"最短路径如下"<<endl;
    cout<<"长度:  "<<stock[0].length()<<endl;
    cout<<"路径:  "<<endl;
    for(int i=0; i<=num; i++)
    {
        cout<<"P"<<i+1<<":  ";
        stock[i].output();
        stock[i].set(line);
    }
    cout<<endl;

    cout<<"布线如下"<<endl;
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            cout<<line[i][j]<<" ";
        }
        cout<<endl;
    }

    output(stock,line,row,col);
    return 0;
}

seqStack.h:

//----------定义存放最短路径的栈及其子函数----------
#ifndef SEQSTACK_H
#define SEQSTACK_H
#include<iostream>
#include <fstream>
#include <stdlib.h>
#include<cstring>
#include<stdio.h>
#include"seqStack.h"
#define MaxSize    100     //栈最多元素个数
using namespace std;

//定义一个栈用来存储最短路径不唯一时的不同最短路径
class seqStack
{
public:
    seqStack ( int sz=MaxSize) ;
    ~seqStack ( );
    void push(const int& x,const int& y);
    bool pop (int & x,int& y);
    bool IsEmpty ( );
    void getxy(int *x1,int *y1);
    int length();     //路径长度
    void output();                     //输出路径
    void set(char line[100][100]);    //标出最短路径,S****D
    void clear()
    {
        int x,y;
        while(top>-1)
        {
            pop(x,y);
        }
    }
    void setlength(int x)
    {
        top=x;
    }
private:
    int* x;
    int* y;
    int top;
    int maxSize;
};


seqStack:: seqStack( int sz )
{
    top=-1;
    maxSize=sz;
    x=new int[sz];
    y=new int[sz];
}

seqStack:: ~seqStack()
{
    delete []x;
    delete []y;
    top=-1;
}

//入栈
void seqStack ::push ( const int & x1,const int & y1)
{
    if (top == MaxSize-1) throw "溢出";
    top++;
    x[top] = x1;
    y[top] = y1;
}

//出栈
bool seqStack :: pop (int& x1,int& y1)
{
    if (top == -1) throw "空";
    x1 = x[top];
    y1 = y[top];
    top--;
    return true;
}
bool seqStack :: IsEmpty ( )
{
    if(top<0)
        return true;
    return false;
}
int seqStack :: length ( )
{
    return top;
}
void seqStack :: output ()
{
    for(int i=0; i<=top; i++)
    {
        cout<<"("<<x[i]<<","<<y[i]<<") ";
        if((i+1)%15==0)
        {
            cout<<endl;
            cout<<"      ";
        }
    }
    cout<<endl;
}

void seqStack :: set(char line[100][100])
{
    line[x[0]][y[0]]='S';
    for(int i=1; i<top; i++)
    {
        line[x[i]][y[i]]='*';
    }
    line[x[top]][y[top]]='D';

}

void seqStack :: getxy (int *x1,int *y1)
{
    for(int i=0; i<=top; i++)
    {
        x1[i]=x[i];
        y1[i]=y[i];
    }
}
#endif // SEQSTACK_H

findpath.h:

//------------寻找所有可行路径---------------
#ifndef FINDPATH_H
#define FINDPATH_H
#include<iostream>
#include <fstream>
#include <stdlib.h>
#include<cstring>
#include<stdio.h>
#include"seqStack.h"
#define MaxSize    100     //栈最多元素个数
using namespace std;

//定义一个结构体,用来逐个探索每一个节点的可行方向
struct InstallLine
{
    int i;      //路径横坐标
    int j;      //路径纵坐标
    int di;     //方向
} Stack[MaxSize];     //定义栈和存放路径的数组

int header=-1;     //栈顶指针
int count=1;    //路径数计数
int minlen=MaxSize;     //最短路径长度
int num=-1;       //最短路径数
seqStack *stock=new seqStack[MaxSize];   //定义一个栈数组存放最短路径


//寻找可行路径
void mgpath(char mg[100][100],int row,int col,int start_x,int start_y,int end_x,int end_y)       //路径为:(x0,y0)->(x,y)
{
    int i,j,di,find,k;
    header++;
    Stack[header].i=start_x;
    Stack[header].j=start_y;
    Stack[header].di=-1;
    mg[start_x][start_y]=-1;//初始结点进栈
    while(header>-1)       //栈不空时循环
    {
        i=Stack[header].i;
        j=Stack[header].j;
        di=Stack[header].di;
        if(i==end_x && j==end_y)        //找到了出口,输出路径
        {
            cout<<"M"<<count++<<":  ";
            for(k=0; k<=header; k++)
            {
                cout<<"("<<Stack[k].i<<","<<Stack[k].j<<")"<<" ";

                if((k+1)%15==0)      //输出时每15个结点换一行
                {
                    cout<<endl;
                    cout<<"      ";
                }
            }
            cout<<endl;
            cout<<endl;

            if(header<=minlen)        //比较输出最短路径
            {
                if(header==minlen)       //又出现一条最短路径,存入栈中
                {
                    num++;
                }
                else                   //出现一条比之前都短的路径,删除之前存入的路径,保存当前这条路径
                {
                    for(k=0; k<=num; k++)
                    {
                        stock[k].clear();
                    }
                    num=0;
                }
                    for(k=0; k<=header; k++)
                    {
                        stock[num].push(Stack[k].i,Stack[k].j);
                    }
                    stock[num].setlength(header);

                minlen=header;
            }


            mg[Stack[header].i][Stack[header].j]='0';   //让该位置变为其他路径的可走结点
            header--;
            i=Stack[header].i;
            j=Stack[header].j;
            di=Stack[header].di;
        }
        find=0;

        while(di<4 && find==0)      //找下一个可走结点
        {
            di++;
            int remark=0;
            switch(di)
            {
            case 0:
                if(Stack[header].i>0)
                {
                    i=Stack[header].i-1;
                    j=Stack[header].j;
                    remark=1;
                }
                break;   //上面
            case 1:
                if(Stack[header].j<(col-1))
                {
                    i=Stack[header].i;
                    j=Stack[header].j+1;
                    remark=1;
                }
                break;   //右边

            case 2:
                if(Stack[header].i<(row-1))
                {
                    i=Stack[header].i+1;
                    j=Stack[header].j;
                    remark=1;
                }
                break;   //下面
            case 3:

                if(Stack[header].j>0)
                {
                    i=Stack[header].i;
                    j=Stack[header].j-1;
                    remark=1;
                }
                break;   //左边
            }
            if(mg[i][j]=='0'&&remark==1)
                find=1;
        }
        if(find == 1)       //找到了下一个可走结点
        {
            Stack[header].di=di;   //修改原栈顶元素的di值
            header++;      //下一个可走结点进栈
            Stack[header].i=i;
            Stack[header].j=j;
            Stack[header].di=-1;
            mg[i][j]='-1';        //避免重复走到该结点
        }
        else
        {
            if(header!=0)
            {
                mg[Stack[header].i][Stack[header].j]='0';   //让该位置变为其他路径的可走结点
            }
            header--;
        }
    }

    cout<<endl;
}

#endif // FINDPATH_H

RWfile.h:

#ifndef RWFILE_H
#define RWFILE_H
#include<iostream>
#include <fstream>
#include <stdlib.h>
#include<cstring>
#include<stdio.h>
#include"seqStack.h"
#include"findpath.h"
#define MaxSize    100     //栈最多元素个数
using namespace std;

void input(char line[100][100],int &row,int &col)
{
    //读取文件
    char buffer[256];
    ifstream in("data.txt");

    if (! in.is_open())
    {
        cout << "Error opening file";
        exit (1);
    }
    in>>row;
    in>>col;
    int i=0;
    in.getline(buffer,100);
    while (!in.eof() )
    {
        in.getline (buffer,100);
        char *token=strtok(buffer," ");
        int j=0;
        while(token!=NULL)
        {
            line[i][j]=token[0];
            token=strtok(NULL," ");
            j++;
        }
        i++;
    }
    in.close();
    //文件读取结束
}

void findpos(char line[100][100],int row,int col,int &start_x,int &start_y,int &end_x,int &end_y)
{
    //寻找起点S、终点D位置
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            if(line[i][j]=='S')
            {
                start_x=i;
                start_y=j;
                line[i][j]='0';
            }
            else if(line[i][j]=='D')
            {
                end_x=i;
                end_y=j;
                line[i][j]='0';
            }
        }
    }

}

//写入文件
void output(seqStack *stock,char line[100][100],int row,int col)
{
    ofstream out("path.txt");
    if ( ! out)
    {
        cout << "文件不能打开" <<endl;
    }
    else
    {
        out<<"最短路径如下"<<endl;
        out<<"长度:  "<<stock[0].length()<<endl;
        out<<"路径:  "<<endl;
        int x[100],y[100];
        for(int i=0; i<=num; i++)
        {
            stock[i].getxy(x,y);
            out<<"P"<<i+1<<":  ";
            for(int j=0; j<=stock[i].length(); j++)
            {
                out<<"("<<x[j]<<","<<y[j]<<") ";
                if((j+1)%15==0)
                {
                    out<<endl;
                    out<<"      ";
                }
            }
            out<<endl;
        }
        out<<endl;

        out<<"布线如下"<<endl;
        for(int i=0; i<row; i++)
        {
            for(int j=0; j<col; j++)
            {
                out<<line[i][j]<<"  ";
            }
            out<<endl;
        }

        out.close();

    }

}

#endif // RWFILE_H

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值