C语言 全排列(包含错误代码及分析,memset简单介绍及举例)
创始人
2024-05-11 21:51:14

正确代码:

#include 
#include 
#include int n;//表示位数
int a[10];
int hash_tabel[10];void print()
{for(int i=n;i>0;i--)printf("%d",a[i]);printf("\n");
}
void core(int d)
{if(d==0)//排序完成{print();return ;}for(int i=1;i<=n;i++){if(!hash_tabel[i]){a[d]=i;hash_tabel[i]=1;core(d-1);hash_tabel[i]=0;}}
}int main()
{int num;scanf("%d",&n);core(n);return 0;
}

题目来源:

河北大学数据结构与算法第四版教科书P21 题目2。

代码分析:

没有用书上的方法,交换啥的,没想明白,这个代码的基本方法是置入。

基本思路是递归,从1到n依次尝试填入目标位置,在解决当前位置后继续解决下一位置,直到最后一个位置也填好数据,即解决了一种情况,注意在子问题解决后要将 hash_tabel[i]置零还原。

错误代码:

#include 
#include 
#include int n;//表示位数
int a[10];
int hash_tabel[10];void init_hash()
{memset(hash_tabel,0,sizeof(hash_tabel) );
}void print()
{for(int i=n;i>0;i--)printf("%d",a[i]);printf("\n");
}void core(int d)
{if(d==0)//排序完成{print();init_hash();//错误点1return ;}for(int i=1;i<=n;i++){if(!hash_tabel[i]){a[d]=i;hash_tabel[i]=1;core(d-1);//错误点2}}
}int main()
{int num;scanf("%d",&n);core(n);return 0;
}

错误代码分析:

这个是我一开始写出来的代码,主要问题是在解决子问题后没有还原散列,先上错误运行结果:

可以看出一个数值多次出现,一开始我还以为是散列的问题,没有正确初始化,修改了之后还是有问题,后来才想到是子问题解决后没有正确进入下一状态,看如下运行模拟:

输入值 3进入core函数 当前位置 3 状态1
i=1 a[3]=1 hash[1]=1 递归调用core进入core函数 当前位置 2 状态2
i=1 无法置入(hash[1]=1)
i=2  a[2]=2 hash[2]=1 递归调用core进入core函数 当前位置 1 状态3
i=1 无法置入
i=2 无法置入
i=3  a[1]=3 hash[3]=1 递归调用core进入core函数 当前位置 0 状态4
重置hash为0 退出core 打印 1 2 3此时回退到 状态3
i=4 退出core回退到 状态2
i=3 a[2]=3 hash[3]=1 递归调用core进入core函数 当前位置 1 状态5
i=1  a[1]=1 hash[1]=1 递归调用core进入core函数 当前位置 0 状态6
重置hash为0 退出core 打印 1 3 1

可以看出问题出在hash的处理上,在最后输出时初始化hash导致在某一状态的子问题解决后处理下一状态时hash是完全错的,正确处理方式应该是当回退到某一状态后同时将hash状态也回退,即正确代码第29行。

另memset用法简记:

头文件:

#include

用途:

将数组存储位置以字节为单位进行赋值

函数原型:

void*memset(void*dest,intc,size_tcount);

参数:

Parameters
dest
Pointer to destination
c
Character to set
count
Number of characters

用法:

我比较常用的是将int数组内容置0,也可以直接置-1,下面举例:

int hash_tabel[10];
memset(hash_tabel,0,sizeof(hash_tabel) );        //写法1
memset(hash_tabel,0,sizeof(hash_tabel[0])*10 );  //写法2

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...