如A,B,C -> D, E
输入:ABC DE
直到End结束
再次输入集合,输出该集合的闭包。
实现: 查询每次都是扫面前面的所有函数依赖,直到一次循环下来闭包不再更新。
使用细节:二进制枚举子集,for(int i = s; i; i = (i-1)&s)
#include <cstdio>
#include <algorithm>
#include <cstring>
#define CLS memset
#define r0 return 0
using ll = long long;
using namespace std;
const int N = 1e4 + 9;
const int M = 30;
char s[N][M], t[N][M], q[M];
int cnt;
ll l[N], r[N];
bool judge[M];
bool End (char a, char b, char c) {
if (a != 'E' && a != 'e') r0;
if (b != 'N' && b != 'n') r0;
if (c != 'D' && c != 'd') r0;
return 1;
}
bool AZ (char a) {return a <= 'Z' && a >= 'A';}
ll trans (char s[]) {
bool vis[M]; CLS(vis, 0, sizeof vis);
for (int i = 0 ; s[i]; i++) vis[s[i] - 'A'] = 1;
ll tmp = 0;
for (int i = 0; i < 26; i++) tmp *= 2, tmp += vis[i];
return tmp;
}
void init (char s[], char t[], int cnt) { l[cnt] = trans(s); r[cnt] = trans(t);}
void out(ll v, char ed = '\n') {
if(v == 0) { printf("NULL%c", ed); return ;}
ll tmp = 1LL<<25;
for (int i = 0; i < 26; i++) {
if((v&tmp) == tmp) printf("%c", 'A' + i);
tmp >>= 1;
} printf("%c", ed);
}
ll solve(ll tmp){
bool vis[N]; for (int i = 0; i < cnt; i++) vis[i] = 0;
int tot = 0, id = 0;
while (tot <= cnt + 1) {
if (!vis[id] && (tmp & l[id]) == l[id]) {
tmp |= r[id]; tot = 0; vis[id] = 1;
} tot ++;
id = (id + 1)%cnt;
} return tmp;
}
void in() {
cnt = 0;
while (~scanf("%s", s[cnt])) {
if (End(s[cnt][0], s[cnt][1], s[cnt][2])) break;
scanf("%s", t[cnt]);
for (int i = 0; s[cnt][i]; i++) if (!AZ(s[cnt][i])) puts("别输入除大写字母以外的字符, 请关闭重来");
for (int i = 0; t[cnt][i]; i++) if (!AZ(t[cnt][i])) puts("别输入除大写字母以外的字符, 请关闭重来");
sort(s[cnt], s[cnt]+strlen(s[cnt])); sort(t[cnt], t[cnt]+strlen(t[cnt]));
init(s[cnt], t[cnt], cnt);
printf("第%d个函数:%s->%s\n", cnt+1, s[cnt], t[cnt]); cnt ++;
}
}
void query() {
puts("请输入属性集求闭包");
while (~scanf("%s", q)) {
if (End(q[0], q[1], q[2])) break;
printf("(%s)+ : ", q); out(solve(trans(q)));
}
}
void dfs(int id, ll v) {
if(id == 26) {
ll s = solve(v);
out(v, ' '); printf("-> {");
for(int i = s; i; i = (i-1)&s) out(i, ',');
puts("NULL}\n");
} else {
if(judge[id]) dfs(id+1, v<<1|1);
dfs(id+1, v<<1);
}
}
void fuck() {
CLS(judge, 0, sizeof judge);
for (int i = 0; i < cnt; i++) {
for (int j = 0; s[i][j]; j++) judge[s[i][j] - 'A'] = 1;
for (int j = 0; t[i][j]; j++) judge[s[i][j] - 'A'] = 1;
} dfs(0, 0);
}
int main(){
printf("请输入函数依赖,请使用空格代替箭头\n");
in(); query(); return fuck(), 0;
}