求集合的幂集

/* 求集合的幂集 */
#include <stdio.h>
#include <stdlib.h>

#define SET_LEN 5

typedef struct {
        char *elem;
        int card;
} set;

typedef struct {
        int *stat;
        int n;
} fsm;

double fac(int n) {
        if (n == 0 || n == 1)
                return 1;
        return n * fac(n-1);
}

double comb(int n, int k) {
        return fac(n)/(fac(k)*fac(n-k));
}

void init_set(set *s, char *elem, int card) {
        s->elem = elem;
        s->card = card;
}

void init_fsm(fsm *s, int n) {
        s->stat = (int *)malloc(sizeof(int)*n);
        s->n = n;
        for (int i = 0; i < n; i++)
                s->stat[i] = i;
}

void print_stat(set *s, fsm *m) {
        for (int i = 0; i < m->n; i++)
                printf("%c", s->elem[m->stat[i]]);
        puts("");
}

void mv(fsm *m) {
        int *r = &(m->stat[m->n-1]);
        (*r)++;
}

int update_which(set *s, fsm *m) {
        int t = s->card - 1;
        for (int i = m->n-1; i >= 0; i--) {
                if (m->stat[i] != t)
                        return i;
                t--;
        }
        return 0;
}

void update(set *s, fsm *m) {
        int t = update_which(s, m);
        int *u = &(m->stat[t]);
        (*u)++;
        for (int i = *u+1, j = t+1; j < m->n; i++, j++)
                m->stat[j] = i;
}

void trans_stat(set *s, fsm *m) {
        int *r = &(m->stat[m->n-1]);
        int t = s->card - 1;

        if (*r != t)
                mv(m);
        else
                update(s, m);
}

void print_subset(set *s, fsm *m) {
        for (int i = 0; i < comb(s->card, m->n); i++) {
                print_stat(s, m);
                trans_stat(s, m);
        }
}

void print_powset(set *s) {
        puts("{}");
        for (int i = 1; i <= s->card; i++) {
                fsm *m = (fsm *)malloc(sizeof(fsm));
                init_fsm(m, i);
                print_subset(s, m);
                free(m);
        }
}

int main() {
	char e[] = "abcde";
	set *s = (set *)malloc(sizeof(set));


	init_set(s, e, SET_LEN);
	print_powset(s);
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值