您的位置:首页 > 其它

笔试题:05_回溯字符串

2015-08-06 00:16 483 查看
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//这道题目有问题

/*
本程序用回溯算法来产生0或1组成的2^m个二进位串,使该串满足以下要求:视串为首尾相连的环,则由m位二进制数字组成的2^m个子序列,
每个可能的子序列都互不相同。例如,如果m=3,在串11101000首尾相连构成的环中,由3位二进制数字组成的每个可能的子序列都在环中恰好出现一次,
它们一次是:111,110,101,010,100,000,001,011,如图所示
		1
	0		1
0				1
	0		0
		1
*/

#define N 1024
#define M 10
int b[N+M-1];//坑爹 N+M-1 = 1024 + 10 -1 = 1033,糊弄你的

//equal(1,0,3),k是用来计数当前有多少个数字,返回1,表示从1开始处相等
int equal(int k,int j,int m)
{
	int i;
	for(i = 0 ; i < m ; i++)//i<3,连续比较3次吗
	{
		//if(b[k+i]!=b[k+j])//?,b[1+0]=b[1]!=b[1],b[1+1]!=b[1+0],b[2]!=b[1](b[2]=0,b[1]=0,b[3]=0,b[1]=0,两者不等为假,不返回)
		if(b[k+i] != b[j+i])
		{
			return 0;
		}
	}
	return 1;
}

//k=1,m=3,v=1
int exchange(int k,int m,int v)
{
	//while(b[k+m-1]==v)//b[1+3-1]=b[3](0)==1不成立,因此不进入循环
	while(b[k+m-1]!=v)
	{
		//b[k+m-1] = !v;//这个意思是:如果v非0(其实就是1),那么令b[k+m-1] = 1;如果v为0 那么令b[k+m-1] = 1
		//k++;//?做循环用,如果返回k,k应该发生变化,这里应该是关于k的
		if(b[k+m-1]==v)
		{
			b[k+m-1] = !v;
			k--;
		}
		b[k+m-1] = v;//?最后一次不为v的时候要赋值为v吗,令b[3] = 1
		return k;//k=1
	}
}

//全部初始化为0
void init(int v)
{
	int k;
	for(k = 0 ; k < N+M-1 ; k++)
	{
		b[k] = v;//初始化全部赋值,
	}
}

int main()
{
	int m,v,k,n,j;
	printf("Enter m(1 < m < 10),v(v=0,v=1)\n");
	scanf("%d %d",&m,&v);
	n=0x01<<m;//获取共有2^m位的数字,例如m=3,此时n=8
	printf("n=%d\n",n);
	init(!v);//如果你输入1,他就暂时把他初始化为0;如果你输入0,他就把他初始化为1
	k = 0;
	//while(k < n)//?计数:0~7,0<7进入循环,1<8 ,你这样k一直没有变化,而且是++k,先让k+1进入到for循环,如果k++?
	while(++k < n)
	{
		for(j = 0 ; j < k ; j++)//刚开始不走这个循环
		{
			if(equal(k,j,m))//如果相等了,交换k,j怎么办,equal(1,0,3),第一次相等,元素值均为0,然后交换
			{
				k = exchange(k,m,v);//k=1,m=3,v=1,此时k仍为1
				//j = k + 1;//?j = k+1,从下一次k走过的位置开始吗?
				j = -1;
			}
		}
		for(k = 0 ; k < n ; k++)//到这一步时,全部是不相等的子串,所以进行输出,输出第一个数0,k=1
		{
			printf("%d\n",b[k]);
		}
	}
	system("pause");
	getchar();
	return 0;
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: