一个拼图游戏bug清除的历程

一个拼图问题:

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中初始化数组即可解决问题,有时候,一个小小的疏忽会造成极大的错误,这个错误往往不容易被发现,因此养成良好的编程习惯非常重要。

 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值