C++调试问题,求教!
我这里是用A*算法求迷宫最短路径,
先定义一个机构如下:
typedef struct {
int gn;
int fn;
int flag; //1——in open; 2——in close
}GFN;
map <int ,GFN*> gmap; 定义一个map来存储gn,fn的信息
让后定义两个表open、和close
list <int> open;
list <int> close;
在这三个结构中,整型元素都是n,像数据库中一样来索引。通过open,close中的元素在gmap中查找到n的信息。
open表是一个有序表,是按照gmap表中的fn的增排序,在对open表排序时自己写了一个函数来实现,
如下:
bool opensort(int n1,int n2)
{
map <int,GFN*> ::iterator pos1,pos2;
pos1 = gmap.find(n1);
pos2 = gmap.find(n2);
return pos1-> second-> fn < pos2-> second-> fn;
}
在排序时:sort(open.begin(),open.end(),opensort);
编译时总出现错误,
如:
c:\program files\microsoft visual studio\vc98\include\algorithm(592) : error C2784: '_D __cdecl std::operator -(const class std::reverse_iterator <_RI,_Ty,_Rt,_Pt,_D> &,const class std::reverse_iterator <_RI,_Ty,_Rt,_Pt,_D> &) ' : could not deduce temp
late argument for 'const class std::reverse_iterator <_RI,_Ty,_Rt,_Pt,_D> & ' from 'class std::list <int,class std::allocator <int> > ::iterator '
c:\program files\microsoft visual studio\vc98\include\algorithm(589) : see reference to function template instantiation 'void __cdecl std::_Sort_0(class std::list <int,class std::allocator <int> > ::iterator,class std::list <int,class std::alloc
ator <int> > ::iterator,bool (__cdecl *)(int,int),int *) ' being compiled
/***********************************************************/
//源程序如下:
#include <iostream>
#include <strstream>
#include <list>
#include <map>
#include <algorithm>
using namespace std;
#defineMAZE_ROW 9
#define MAZE_COL 7
char maze[MAZE_ROW][MAZE_COL]={
' ', ' ', ' ', '# ', '# ', '# ', '# ',
'# ', '# ', ' ', '# ', '# ', '# ', '# ',
' ', '# ', ' ', '# ', '# ', '# ', '# ',
' ', '# ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', '# ', '# ', '# ', '# ', ' ',
'# ', ' ', ' ', ' ', ' ', '# ', ' ',
'# ', '# ', ' ', '# ', ' ', '# ', ' ',
' ', ' ', ' ', ' ', '# ', '# ', ' ',
' ', ' ', '# ', ' ', ' ', '# ', ' ',
};
typedef struct {
int gn;
intfn;
int flag; //1——in open; 2——in close
}GFN;
map <int ,GFN*> gmap; //g值
int Bi=0, Bj=0;
intEi=6, Ej=6;
bool opensort(int n1,int n2)
{
map <int,GFN*> ::iterator pos1,pos2;
pos1 = gmap.find(n1);
pos2 = gmap.find(n2);
return pos1-> second-> fn < pos2-> second-> fn;
}
void getway(int i,int j,int gn); //输出路径
void printmaze();
void printway();
bool isok(int i,int j);//判断n1位置为迷宫中可以走的位置
int main()
{
list <int> open;
list <int> close;
map <int,GFN*> ::iterator pos;
list <int> ::iterator it;
int n,gn,fn;
int n1,gn1,fn1;
int ci,cj;
int ni,nj;
GFN* pgf = NULL;
ci = Bi;
cj = Bj;
n = ci*MAZE_COL + cj;
gn = 0;
fn = abs(Ei-ci+Ej-cj);
pgf=new GFN;
pgf-> gn = 0;
pgf-> fn = fn;
pgf-> flag = 1;
gmap[n] = pgf;
open.push_back(n);
while(!open.empty()){
n = open.front();//pop front from open
open.pop_front();
ci = n/MAZE_COL; //the corren sit
cj = n%MAZE_COL;
pos = gmap.find(n);//find the sit
gn = pos-> second-> gn;
fn = pos-> second-> fn;
pos-> second-> flag = 2;
close.push_back(n);//push n into close
if(ci==Ei && cj==Ej)
{
cout < < "找到最短路径,长度为: " < <gn < <endl;
//getway(Ei,Ej,gn-1);
//printway();
return 1;
}
gn1 = gn+1;
for(int d=0; d <4; ++d){
ni = ci;
nj = cj;
switch(d){
case 0 ://left derect
nj = cj-1;
break;
case 1 ://up derect
ni = ci-1;
break;
case 2 ://right derect
nj = cj+1;
break;
case 3 ://down derect
ni = ci+1;
break;
}//end_switch
if(isok(ni,nj)){
n1 = ni*MAZE_COL+nj;
fn1 = abs(Ei-ni+Ej-nj)+gn1;
pos = gmap.find(n1);
if(pos!=gmap.end()){//n1 is old
if(pos-> second-> fn <fn1){
pos-> second-> fn = fn1;
pos-> second-> gn = gn1;
if(pos-> second-> flag==2){
it = find(close.begin(),close.end(),n1);
close.erase(it);
open.push_back(n1);
}
sort(open.begin(),open.end(),opensort );
}
}
else{//
pgf = new GFN;
pgf-> gn = gn1;
pgf-> fn = fn1;
pgf-> flag = 1;
gmap[n1] = pgf;
open.push_back(n1);
sort(open.begin(),open.end(),opensort );
}//end_else
}//end_if
}//end_for
}//end_while
cout < < "没有路径可以到达出口!\n\n\n " < <endl;
return 1;
}
/***********************************************************/
[解决办法]
Map是一个通过key(键)来获得value(值)的模板类。另一个问题是你希望在map中使用自己的类而不是已有的数据类型,比如现在已经用过的int。建立一个“为模板准备的(template-ready)”类,你必须确保在该类中包含一些成员函数和重载操作符。下面的一些成员是必须的:
•缺省的构造函数(通常为空)
•拷贝构造函数
•重载的”=”运算符
你应该重载尽可能多的运算符来满足特定模板的需要,比如,如果你想定义一个类作为 map中的键(key),你必须重载相关的运算符。但在这里不对重载运算符做过多讨论了。
//程序:映射自定义的类。
//目的:说明在map中怎样使用自定义的类。
#include <string>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
class CStudent
{
public:
int nStudentID;
int nAge;
public:
CStudent(){}//缺省构造函数——通常为空
//完整的构造函数
CStudent(int nSID, int nA){ nStudentID=nSID; nAge=nA;}
//拷贝构造函数
CStudent(const CStudent& ob){ nStudentID=ob.nStudentID; nAge=ob.nAge;}
// 重载“=”
void operator = (const CStudent& ob){nStudentID=ob.nStudentID; nAge=ob.nAge;}
};
int main(int argc, char* argv[])
{
map <string, CStudent> mapStudent;
mapStudent[ "Joe Lennon "] = CStudent(103547, 22);
mapStudent[ "Phil McCartney "] = CStudent(100723, 22);
mapStudent[ "Raoul Starr "] = CStudent(107350, 24);
mapStudent[ "Gordon Hamilton "] = CStudent(102330, 22);
// 通过姓名来访问Cstudent类中的成员
cout < < "The Student number for Joe Lennon is " < <
(mapStudent[ "Joe Lennon "].nStudentID) < < endl;
return 0;
}