学习心得:数据结构与算法之回朔(一个“框架”)

原创 2007年09月15日 18:34:00
一、回溯算法简单说就是“一直向前走,碰壁就会头”。一个经典的例子是走迷宫,一直向前走,碰壁就回头。下面就看看这个“框架”(vc6.0下编译):
/////////////////////////
// Application.h

#ifndef APPLICATION_H
#define APPLICATION_H

#include 
"iostream.h"
#include 
"Position.h"

class Application
{
protected:
    friend ostream
& operator << (ostream& stream, Application& app);

public:
    Position generateInitialState();
    
bool valid (const Position &pos);
    
bool done (const Position &pos);
    
void record (const Position &pos);
    
void undo (const Position &pos);

    
class Iterator
    
{
    
protected:
        
void* fieldPtr;

    
public:
        Iterator ();
        Iterator (
const Position& pos);
        Position 
operator ++ (int);
        
bool atEnd (); 
    }
;
}
;


#endif 
///////////////////////////////////////
//  BACKTRACK_H
#ifndef BACKTRACK_H
#define BACKTRACK_H

#include 
"Application.h"
#include 
"Position.h"

class BackTrack
{
public:
    BackTrack (Application 
&app);
    
bool tryToSolve (Position& pos);
protected:
    Application app;
}
;
    
#endif

 

//////////////////////
//BrackTrack.cpp
#include "BackTrack.h"

BackTrack::BackTrack (Application 
&app)
{
    
this->app = app;
}


bool BackTrack::tryToSolve (Position &pos)
{
    
bool success = false;

    Application::Iterator itr(pos);
    
while (!success && !itr.atEnd())
    
{
        pos 
= itr++;
        
if (app.valid(pos))
        
{
            app.record(pos);
            
if (app.done(pos))
                success 
= true;
            
else
            
{
                success 
= tryToSolve(pos);
                
if (!success)
                    app.undo(pos);
            }

        }

    }

    
return success;
}

 

/////////////////////////////
//main,cpp
#include "iostream.h"
#include 
"string.h"
#include 
"BackTrack.h"
#include 
"Application.h"
#include 
"Position.h"

int main()
{
    Application app;
    BackTrack b(app);

    Position pStart 
= app.generateInitialState();
    
//cout<<app;
    
    
if (!app.valid(pStart))
        cout 
<< "there is no solution:" << endl;
    
else
    
{
        app.record (pStart);
        
if (app.done (pStart) || b.tryToSolve(pStart))
            cout 
<< "success" << endl;
        
else
        
{
            app.undo(pStart);
            cout 
<< "there is no solution" << endl;
        }

    }

    
return 0;
}

 

二、下面就以迷宫为例子用这个“框架”

 

/////////////////////////////////////////
// POSITION_H

#ifndef POSITION_H
#define POSITION_H

class Position
{
protected:
    
int nRow;
    
int nColumn;

public:
    Position();
    Position(
int nRow, int nColumn);
    
void SetPosition(int nRow, int nColumn);
    
int GetRow() const;
    
int GetColumn() const;
}
;

#endif
//////////////////////////////////
//  Position.cpp
#include "Position.h"

Position::Position()
{
    nRow 
= 0;
    nColumn 
= 0;
}


Position::Position(
int nRow, int nColumn)
{
    
this->nRow = nRow;
    
this->nColumn = nColumn;
}


void Position::SetPosition(int nRow, int nColumn)
{
    
this->nRow = nRow;
    
this->nColumn = nColumn;
}


int Position::GetRow() const
{
    
return nRow;
}


int Position::GetColumn() const
{
    
return nColumn;
}
///////////////////////////////////
//Application.cpp

#include 
"iostream.h"
#include 
"Application.h"
#include 
"Position.h"

const short WALL = 0;
const short CORRIDOR = 1;
const short PATH = 9;
const short TRIED = 2;
const short ROWS = 8;
const short COLUMNS = 13;

short grid[ROWS][COLUMNS] = 
{
    
{1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1},
    
{1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 1},
    
{1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1},
    
{1 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1},
    
{1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1},
    
{1 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1},
    
{1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1},
    
{1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1},
}
;

Position posStart;
Position posFinish;



Position Application::generateInitialState()
{
    
int nRow;
    
int nColumn;

    cout 
<< "Please enter the start row and start column:";
    cin 
>> nRow >> nColumn;
    posStart.SetPosition(nRow, nColumn);
    cout 
<< endl;
    cout 
<< "Please enter the finish row and finish column:";
    cin 
>> nRow >> nColumn;
    cout 
<< endl;
    posFinish.SetPosition (nRow, nColumn);
    
return posStart;
}


bool Application::valid(const Position& pos) 
{
    
if (pos.GetRow() >= 0 && pos.GetRow() < ROWS &&
        pos.GetColumn() 
>= 0 && pos.GetColumn() < COLUMNS &&
        grid[pos.GetRow()][pos.GetColumn()] 
== CORRIDOR)
    
{
        
return true;
    }

    
return false;
}


void Application::record(const Position &pos)
{
    grid[pos.GetRow()][pos.GetColumn()] 
= PATH;   //标识该点为已经在路径中
}


bool Application::done(const Position &pos)
{
    
return posFinish.GetRow() == pos.GetRow() &&
        posFinish.GetColumn() 
== pos.GetColumn();
}


void Application::undo(const Position &pos)
{
    grid[pos.GetRow()][pos.GetColumn()] 
= TRIED;  //此路不通
}


ostream
& operator << (ostream& stream, Application* app)
{
    
for (int nRow = 0 ; nRow < ROWS ; nRow++)
    
{
        
for (int nColumn = 0 ; nColumn < COLUMNS ; nColumn)
            cout 
<< grid[nRow][nColumn] << " ";
        cout 
<< endl;
    }

    
return stream;
}



// Iterztor
typedef struct _tagItrFields
{
    
int nRow;
    
int nColumn;
    
int nDirection;
}
ITRFIELDS, *LPITRFIELDS;

Application::Iterator::Iterator(
const Position &pos)
{
    LPITRFIELDS itrPtr 
= new ITRFIELDS;
    itrPtr
->nColumn = pos.GetColumn();
    itrPtr
->nRow = pos.GetRow();
    itrPtr
->nDirection = 0;
    fieldPtr 
= itrPtr;
}


Position Application::Iterator::
operator ++ (int)
{
    LPITRFIELDS itrPtr 
= (LPITRFIELDS)fieldPtr;
    
int nRow = itrPtr->nRow;
    
int nColumn = itrPtr->nColumn;

    
switch(itrPtr->nDirection++)
    
{
    
case '0':
        nRow
--;
        
break;
    
case '1':
        nColumn
++;
        
break;
    
case '2':
        nRow
++;
        
break;
    
case '3':
        nColumn
--;
        
break;
    
default:
        
break;
    }

    Position next(nRow, nColumn);
    
return next;
}


bool Application::Iterator::atEnd()
{
    
return ((LPITRFIELDS)fieldPtr)->nDirection >= 3;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

数据结构学习心得总结

开篇经过近一个月的学习,终于将郝斌老师讲的数据结构视频看完了~学习完成后,受益良多,也非常喜悦,非常开心,好像终于打了一场胜仗一样!我打算将这一个月的学习心得做一个汇总,记录下来。 希望能给初学者带...

数据结构学习心得

很多同学都说,数据结构不好学。个人认为,学习的难易程度很大程度上决定于个人的兴趣。把一件事情当做任务去做会很痛苦,当做兴趣去做会很快乐。如果想让自己在学习数据结构的过程中更轻松一些,请先培养对这门学科...

数据结构---《大话数据结构》学习心得,定期更新---阿冬专栏!!!

最近给自己拟定了长期学习计划,也就是自己的学习主线: 数据结构       Java C语言 SQL Server数据库(中型数据库) 设计模式23种 操作系统---进程、线程、死锁、解锁、、、、...

[心得]算法与数据结构学习笔记

引言想来算法与数据结构方面的书我读了好几本了。是时候真正动手写功能了,因此关于算法和数据结构系列博客也算是收个尾巴。干货Kurt Mehlhorn和Peter Sanders这本书200来页,涵盖那么...

关于对于一个新框架的学习心得

我们学一个东西,通常两个目的: 为了解决现有的问题为了解决将来可能会有的问题 所以,在学这些东西之前,先必须了解,它们是用来解决什么问题的。 Angular,React,Vue,这三...

[心得]算法和数据结构Ellis Horowitz大神知识整理

主要取材自两本书: 计算机算法C++语言描述 第2版 Ellis Horowitz et al著 数据结构基础C语言版第2版 Ellis Horowitz et al著这个作者的写书风格很符合我这...

【数据结构与算法】Project 1: Linear List // 测试心得

Project 1: Linear List   (4H) Goal: Practice the implementation andapplication of stack. Task:利用栈完成算...

shiro框架学习心得

  • 2016-06-27 08:53
  • 20KB
  • 下载

shiro框架学习心得

  • 2013-09-06 10:01
  • 23KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)