#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; }