一个拼图问题:
8 | 2 | 3 |
1 | 6 | 4 |
7 | 5 |
8 | 3 | 4 |
1 | 2 | 5 |
7 | 6 |
|
C++代码实现:
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
bool history[999999999] = { 0 };//存放历史记录 ,close表
unsigned long int Result;
struct Node
{
unsigned long int hash;
int depth;
};//结构体将hash值和层数打包
queue<Node>QUE;
int s[10] = { 0 };
void swap(int *p1, int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}//交换函数
void chaifen(unsigned long int temp)//把一个九位数拆分放到数组 s[]中
{
int i = 9;
while (temp != 0)
{
s[i] = temp % 10;
temp = temp / 10;
i--;
}
}
unsigned long int hebing()//将数组合并为九位数
{
int j = 0;
unsigned long int temp = 0;
while (j < 9)
{
temp += pow(10, j)*s[9 - j];
j++;
}
return temp;
}
void bfs()
{
while (!QUE.empty())
{
int i;
unsigned long int temp;
chaifen(QUE.front().hash);
//以下为分类讨论
i = 0;
while (s[++i] != 0);//寻找为 0 的元素的下标,下同
if (i != 1 && i != 4 && i != 7)//0 元素与它左边元素交换,下面类似
{
swap(&s[i], &s[i - 1]);
temp = hebing();
if (history[temp] == 0)
{
if (temp == Result)
{
cout << QUE.front().depth + 1 << endl;
break;
}
history[temp] = 1;
Node Temp;
Temp.hash = temp;
Temp.depth = QUE.front().depth + 1;
QUE.push(Temp);
}
swap(&s[i], &s[i - 1]);
}
i = 0;
while (s[++i] != 0);
if (i != 3 && i != 6 && i != 9)
{
swap(&s[i], &s[i + 1]);
int j = 0;
temp = hebing();
if (history[temp] == 0)
{
if (temp == Result)
{
cout << QUE.front().depth + 1 << endl;
break;
}
history[temp] = 1;
Node Temp;
Temp.hash = temp;
Temp.depth = QUE.front().depth + 1;
QUE.push(Temp);
}
swap(&s[i], &s[i + 1]);
}
i = 0;
while (s[++i] != 0);
if (i - 3 >= 1)
{
swap(&s[i], &s[i - 3]);
temp = hebing();
if (history[temp] == 0)
{
if (temp == Result)
{
cout << QUE.front().depth + 1 << endl;
break;
}
history[temp] = 1;
Node Temp;
Temp.hash = temp;
Temp.depth = QUE.front().depth + 1;
QUE.push(Temp);
}
swap(&s[i], &s[i - 3]);
}
i = 0;
while (s[++i] != 0);
if (i + 3 <= 9)
{
swap(&s[i], &s[i + 3]);
temp = hebing();
if (history[temp] == 0)
{
if (temp == Result)
{
cout << QUE.front().depth + 1 << endl;
break;
}
history[temp] = 1;
Node Temp;
Temp.hash = temp;
Temp.depth = QUE.front().depth + 1;
QUE.push(Temp);
}
swap(&s[i], &s[i + 3]);
}
QUE.pop();
}
}
int main()
{
Node head;
head.hash = 823164705;
history[head.hash] = 1;
head.depth = 0;
QUE.push(head);
Result = 834125760;
bfs();
return 0;
}
运行后报错
我百度了一下 ,debug assertion failed.deque iterator not dereferencable.错误有如下可能:
第一:访问某一个不存在的位置。第二:在多线程编程里面,这种问题也出现的比较多。然后我的也不知道哪个问题。我感觉都不是。
首先这个队列必定存在,应该不是队列的问题,然后这个也不是多线程编程,因此,错误应该在其他地方。
点击 错误框的重试按钮后触发了一个断点
此时可以看一下各个变量的取值
发现了一丝蛛丝马迹,变量temp中应该存放经过一次变换处理后的值,但这个值却不存在零,意味着数组已经越界;因为在执行如下语句:
i = 0;
while (s[++i] != 0);
无法在数组s[1]--s[9]中找到 0 而temp又是数组的体现;
因此i已经越界,所以如下语句<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">涉及了对内存的非法区域进行操作,造成内存泄漏,导致严重后果;</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="cpp">swap(&s[i], &s[i + 1]);
究其原因,在函数void chaifen(unsigned long int temp)中未为初始化,当temp为8位数时,s[9]未被覆盖,本应该是 0 ,实际上可能为非0值 ,在这个实例里为8;
因此只需在<pre name="code" class="cpp">void chaifen中初始化数组即可解决问题,有时候,一个小小的疏忽会造成极大的错误,这个错误往往不容易被发现,因此养成良好的编程习惯非常重要。