吉林大学超星高级语言程序设计 实验08 结构化程序设计(二)Debruijn问题(2020级)

(以下答案均由本人自己编写,欢迎大家一起交流)
建议在完成本次实验前对DFS算法有一定了解。
题目编号:Exp08-Enhance02,GJBook3-12-17

题目名称:Debruijn问题

题目描述:

如图所示由2^3 个二进制数字0和1组成一个环。使 2^3 个 3 位的二进制数正好在环中各出现一次。图中目前所示顺序是:0、1、2、5、3、7、6、4。设计生成这样环的程序,环由 2^n 个二进制数字组成,恰好包含 2^n 个互不相同的n位二进制数。

在这里插入图片描述

输入:n(n<=4)

输出:按照字典序输出符合的答案(当出现多组本质不同的解时,仅输出字典序中最小的那个序列);每行数字间以一个西文空格间隔,行末有一个换行符。

样例1:

输入:
3
输出:
0 0 0 1 0 1 1 1
思路:
这里我们仍采用dfs算法。
我的思路是先生成所有的n位二进制数,以n=3举例有000,001,010,011,100,101,110,111.我们从头开始排这些二进制数,显然,由于输出的是字典序中最小的那个序列,所以开头我们可以先填入000,然后在剩下的数中寻找前两项是00的二进制数,如001,那我们将1填入序列。再寻找开头为01的二进制数,如010,011,
以上是递归思路
以下是递归出口的设置
仍以n=3举例,当我们填入了7个数时,我们已经把二进制数填完了(000开头就已被填入,所以只需填剩下的七个数)但这时候序列中有十个数,因为要构成环,所以结尾的两个数要与开头的两个数相同,如若相同,则满足提议,我们就找出了一个Debruijn序列。
代码:

#include<stdio.h>
int a[20][5],n,b[5],p=0,d[200],book[20]={0}/*用来标记数是否被使用过*/,e[200][200],p1=0;
int cmp(int t,int w);//判断该数的前n-1项是否与序列的后n-1项相同
void dfs(int w){
	int j,i;
	if(w==p){//递归出口
		for(j=0;j<n;j++){
			if(d[j]!=d[j+p])return;
		}
		for(j=0;j<p;j++){
			e[p1][j]=d[j];//将满足条件的序列填入e中
		}
		p1++;
		return;
	}
	for(i=0;i<p;i++){
		if(book[i]==0&&cmp(i,w)){
			d[w+n-1]=a[i][n-1];
			book[i]=1;//标记该数已使用
			dfs(w+1);//走一步
			book[i]=0;//这是最重要的一步!一定要将尝试的数收回,才能尝试下一步
		}
	}
    
}
int cmp(int t,int w){
	int i;
	for(i=0;i<n-1;i++){
		if(a[t][i]!=d[w+i])return 0;
	}
	return 1;
}
void put(void){
	int i;
	for(i=0;i<n;i++){
		a[p][i]=b[i];//将生成的二进制数填入a中
	}
	p++;
}
void exh(int m){//生成二进制数
	int i;
	if(m==n){
		put();
	}
	else if(m<n){
		for(i=0;i<=1;i++){
			b[m]=i;
			exh(m+1);
		}
	}
}
int main(void){
	int i;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		d[i]=0;
	}
	book[0]=1;
	exh(0); 
	dfs(1);
	for(int j=0;j<p;j++){

		printf("%d",e[0][j]);//e中的第一个序列就是字典序最小的序列
		if(j!=p-1){
			printf(" ");
		}
		else printf("\n");
	}
}

欢迎大家在评论区交流

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值