首页 > 其他 > 详细

八数码问题的SET实现

时间:2019-03-04 20:14:51      阅读:133      评论:0      收藏:0      [点我收藏+]

紫书上称这个方式为路径寻找问题,实际上,这个就是一个BFS和一个节点查找表的结合

 

这里先采用STL中的set来实现查找表。

 

在这道题中学到的东西主要是:

memxxxx等一系列内存管理函数的使用

首先是memxxx(a,b,size)

a是一个地址,b也是一个地址,size就是从这几个地址开始的几个字节

memcmp()函数,当对比成功后,返回0  所以特别的奇葩

memcpy()函数,比一个一个赋值快多了

然后是一个地址+一个常数,这个得看前面这个地址是什么数据类型的地址,最主要可以使用的地方是二维数组

假设有一个数组a[][],那么&a[0][0] + i,就是这个二维数组的第i个元素(从0开始)

另外,当发生内存冲突的时候,一般是发生了数组溢出或者用一个负数当作数组下标去访问数组

这个题目还涉及了使用数组来完成动态分配,这样,入队的时候,就可以只入队数组指针了

下面是实现的代码:

//总体思路就是,将每一个状态保存下来,然后由于每一个状态只有有限的选择,那么可以使用类似回溯法的思路,但是这类问题是没有明显的步骤数的
//其实就是一个bfs
#include<cstdio>
#include<iostream>
#include<queue>
#include<set>
#include<cstring>
using namespace std;
struct state
{
    int board[3][3];
};
const int maxn = 1000000;

state st[maxn];
int fa[maxn];
int dis[maxn];
int cnt = 0;
int start,goal;
set<int>Set;

int newstate()
{
    ++cnt;
    memset(&st[cnt],0,sizeof(st[cnt]));//内存管理函数的参数必须是地址
    if(cnt == 999999)
        printf("越界了!!!");
    return cnt;
}

bool is_valid(int x)
{
    int v = 0;
    for(int i = 0;i < 9;i++)
    {
        //cout<<&st[x].board[0][0]<<endl;
        //cout<<&st[x].board[0][0] + i<<endl;
        v = v * 10 + *(&st[x].board[0][0] + i);
    }
    if(Set.count(v))
        return false;
    else
    {
        Set.insert(v);
        return true;
    }
}
int dc[] = {-1,1,0,0};
int dr[] = {0,0,1,-1};
int BFS()
{
    queue<int>Q;
    Q.push(start);
    while(!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        if(memcmp(&st[u],&st[goal],36) == 0)//这函数怎么这么奇葩啊,不过后面的size参数确实是明白了
        {
            return u;
        }
        int row,col;
        int find = 0;
        for(row = 0;row < 3;row++)
        {
            for(col = 0;col < 3;col++)
            {
                if(st[u].board[row][col] == 0)
                {
                    find = 1;
                    break;
                }
            }
            if(find)
                break;
        }
        for(int i = 0;i < 4;i++)
        {
            int r = row + dr[i];
            int c = col + dc[i];
            if(r < 3 && r >= 0 && c < 3 && c >= 0)
            {
                int v = newstate();
                memcpy(&st[v],&st[u],sizeof(st[u]));
                st[v].board[r][c] = 0;
                st[v].board[row][col] = st[u].board[r][c];
                if(is_valid(v))
                {
                    Q.push(v);
                    fa[v] = u;
                    dis[v] = dis[u] + 1;
                }
            }
        }
    }
    return 0;
}

bool read_input()
{
    start = newstate();
    for(int i = 0;i < 9;i++)
    {
        scanf("%d",&st[start].board[0][0] + i);
    }
    dis[start] = 0;
    goal = newstate();
    for(int i = 0;i < 9;i++)
    {
        scanf("%d",&st[goal].board[0][0] + i);
    }
    return true;
}

int main()
{
freopen("input.txt","r",stdin);
    int ans;
    while(read_input())
    {
        ans = BFS();
    }
    return 0;
}

 

八数码问题的SET实现

原文:https://www.cnblogs.com/TorettoRui/p/10472737.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!