元のコード
#include <iostream>
#include <string>
#include<queue>
using namespace std;
enum {S = 0, A, B, C, D, E, F, G};
//#define CV
#define N 7
#define M 4
#ifndef CV
#define is_empty1() buff.empty()
#endif
// 隣接リスト
int adjacent[N + 1][M] = {
{S},
{B, C, S},
{A, C, D, S},
{A, B, E, S},
{B, E, F, S},
{C, D, G, S},
{D, S},
{E, S},
};
// 経路
typedef struct {
int path[N];
int len;
} Path;
// 現在地点を求める
int top(Path *p)
{
return p->path[p->len - 1];
}
// 経路に頂点が含まれているか
bool visited(Path *p, int x)
{
for (int i = 0; i < p->len; i++) {
if (p->path[i] == x) return true;
}
return false;
}
// 経路の表示
void print_path(Path *p)
{
for (int i = 0; i < p->len; i++){
cout<<(char)('A'+p->path[i]-1);
}
cout<<endl;
}
// キュー
#define Q 64
#ifdef CV
Path buff[Q];
int front, rear;
#else
queue<Path>buff;
#endif
#ifdef CV
// 初期化
void init_queue(int start)
{
buff[0].path[0] = start;
buff[0].len = 1;
rear = 1;
}
#else
void init_queue(int start){
Path p;
buff.push(p);
buff.front().path[0]=start;
buff.front().len=1;
}
#endif
#ifdef CV
// データの取り出し
Path *deq(void)
{
return &buff[front++];
}
#else
//参照のポインタを返してしまっている。
Path *deq(void){
Path *p=&buff.front();
buff.pop();
return p;
}
#endif
#ifdef CV
// データの追加
void enq(Path *p, int x)
{
buff[rear] = *p;
buff[rear].path[p->len] = x;
buff[rear++].len++;
}
#else
void enq(Path*p,int x){
buff.push(*p);
buff.back().path[p->len]=x;
buff.back().len++;
}
#endif
#ifdef CV
// キューは空か
bool is_empty1(void)
{
return front == rear;
}
#endif
// 幅優先探索
void bfs(int start, int goal)
{
init_queue(start);
while (!is_empty1()) {
Path *p = deq();
int x = top(p);
if (x == goal) {
print_path(p);
} else {
for (int i = 0; i < M; i++) {
int y = adjacent[x][i];
if (y == 0) break;
if (!visited(p, y)) enq(p, y);
}
}
}
}
int main(void)
{
bfs(A, G);
return 0;
}
vc++コンパイラのcl.exeではうまくいかないので悩んでいたところ
デバッガで値を追ってみたところ
上記のコードのように参照のポインタを返してしまっていたことが問題だったようです。
そこで下記のコードのようにいったん値をほかの変数に格納してからそのポインタを返すようにしたところうまくいきました。
#include <iostream>
#include <string>
#include<queue>
using namespace std;
enum {S = 0, A, B, C, D, E, F, G};
//#define CV
#define N 7
#define M 4
#ifndef CV
#define is_empty1() buff.empty()
#endif
// 隣接リスト
int adjacent[N + 1][M] = {
{S},
{B, C, S},
{A, C, D, S},
{A, B, E, S},
{B, E, F, S},
{C, D, G, S},
{D, S},
{E, S},
};
// 経路
typedef struct {
int path[N];
int len;
} Path;
// 現在地点を求める
int top(Path *p)
{
return p->path[p->len - 1];
}
// 経路に頂点が含まれているか
bool visited(Path *p, int x)
{
for (int i = 0; i < p->len; i++) {
if (p->path[i] == x) return true;
}
return false;
}
// 経路の表示
void print_path(Path *p)
{
for (int i = 0; i < p->len; i++){
cout<<(char)('A'+p->path[i]-1);
}
cout<<endl;
}
// キュー
#define Q 64
#ifdef CV
Path buff[Q];
int front, rear;
#else
queue<Path>buff;
#endif
#ifdef CV
// 初期化
void init_queue(int start)
{
buff[0].path[0] = start;
buff[0].len = 1;
rear = 1;
}
#else
void init_queue(int start){
Path p;
buff.push(p);
buff.front().path[0]=start;
buff.front().len=1;
}
#endif
#ifdef CV
// データの取り出し
Path *deq(void)
{
return &buff[front++];
}
#else
//値のポインタを返すようにすればよい。
Path deq_p;
Path *deq(void){
deq_p=buff.front();
buff.pop();
return &deq_p;
}
#endif
#ifdef CV
// データの追加
void enq(Path *p, int x)
{
buff[rear] = *p;
buff[rear].path[p->len] = x;
buff[rear++].len++;
}
#else
void enq(Path*p,int x){
buff.push(*p);
buff.back().path[p->len]=x;
buff.back().len++;
}
#endif
#ifdef CV
// キューは空か
bool is_empty1(void)
{
return front == rear;
}
#endif
// 幅優先探索
void bfs(int start, int goal)
{
init_queue(start);
while (!is_empty1()) {
Path *p = deq();
int x = top(p);
if (x == goal) {
print_path(p);
} else {
for (int i = 0; i < M; i++) {
int y = adjacent[x][i];
if (y == 0) break;
if (!visited(p, y)) enq(p, y);
}
}
}
}
int main(void)
{
bfs(A, G);
return 0;
}
これはgccとcl.exeで参照のポインタの扱いが違うということでいいんでしょうか?
gccでうまくいってしまうせいですごく悩むことになりましたが
どなたか知っている方お教えいただけないでしょうか。
あとc言語でのソースを参考に対応させながら書いたのでコードがぐちゃぐちゃでみにくくて
すいません。(;´Д`)