计算等价类

首先,什么是等价关系:

等价关系是集合元素间的一种代数关系,用字母E来表示,对于一个集合中的两个元素,如果他们之间存在一种等价关系,那么必须满足以下性质:

1.  自反性,对于任意一个元素x, 它与自己存在等价关系,即(x,x) 满足E

2.  对称性,如果(x,y) 满足 E, 那么 (y, x) 也属于E

3.  传递性,如果(x,y) 满足 E,(y,z)满足E,那么(x,z)也满足E.

接下来,看下面一个等价类的算法:

假设有集合S: {1, 2, … n-1}. 同时有两个数组A,B,他们的元素都来自集合S,且长度都是m, A,B 两数组用来确定集合S 中元素的等价关系,假定A[k] 与 B[k]是等价的,那么S便会被划分成几个不相交的等价类子集,例如:

n = 7,m=4,

假定:

A = {1, 5, 3, 6}

B = {2, 1, 0, 5}

于是S便会被划分成3个不相交的等价类子集:

S1 = {0, 3}

S2 = {1, 2, 5, 6}

S3 = {4}

给你一个数组S, 以及数组A,B, 要求你计算出S被划分的等价类子集。

一种方法是,用队列,把等价的各个元素链接起来,那么互相链接的类就是等价类。

另一种方法是利用等价类的传递性,如果A与B等价,B与C等价那么A与C也等价。

代码如下:

public class Number {
	public  int val;
    public  ArrayList set = null;
    public  boolean visited = false;
    
    public Number(int val) {
    	this.val = val;
    	set = new ArrayList();
    	set.add(val);
    }
}

public class EquivalClass {
	private Number[] numArray = null;
	
    public EquivalClass(int n, int[] A, int[] B) {
        numArray = new Number[n];
    	for (int i = 0; i < n; i++) {
    		numArray[i] = new Number(i);
    	}
    	
    	for (int i = 0; i < A.length; i++) {
    		int  a = A[i];
    		int  b = B[i];
    		
    		makeSet(numArray[a], numArray[b]);
    	}
    	
    }
    
    private void makeSet(Number a, Number b) {
    	a.set.addAll(b.set);
    	b.set = a.set;
    }
    
    public void printAllEquivalSet() {
    	for (int i = numArray.length - 1; i >= 0; i--) {
    		printEquivalSet(numArray[i]);
    	}
    }
    
    private void printEquivalSet(Number number) {
    	if (number.visited == true) {
    		return;
    	}
    	
    	number.visited = true;
    	System.out.print("{ ");
    	Iterator it = number.set.iterator();
    	while (it.hasNext()) {
    		int v = it.next();
    		System.out.print(v + " ");
    		numArray[v].visited = true;
    	}
    	
		System.out.println(" }");
    	
    }
    
   
}



你可能感兴趣的:(刷题总结,java)