算法引论--寻找一对一映射
来源:互联网 发布:上海男人 知乎 编辑:程序博客网 时间:2024/05/21 07:12
寻找一对一映射
令f是一个把有限集映射到自身的函数(即A中的每一个元素都被映射到A中的另一个元素)。为了简单起见,用整数0到n来表示A中的元素,假定函数f用数组f[0..n]来表示,f[i]中占据的是f(i)的值。如果对每一个元素j,至多存在一个元素i映射到j,则称f是一个一对一的函数。函数f可以用图的形式来表示。
如果f原本就是一对一的,则整个集合A满足条件,且A必然也是最大的。另一方面,对于某些i,j,存在f[i] = f[j],那么S就不可能同时包含i和j,对于他们之间要消除哪一个,并不是任意的。例如:消除3,由于1映射到3,1也必须要消除,那么2也必须跟着1的消除而消除。但这样的子集不是最大的。
在我们决定如何把问题简化到小问题上,还可以做一些处理。比如,通过寻找一个元素是否属于S来减小问题的规模。
实现:用一个计数器c[i]来记录在每一个元素i。直觉上,c[i]等于映射到i的元素的数目。对于所有的i,通过在n个步骤内扫描数组并递增相应的计数器,可以计算出c[i],然后把所有计数器为零的元素放进一个队列,每一个步里,把元素j从队列中删除,并递减c[f[j]],同时如果c[f[j]]=0,把f[j]放进队列。
` import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Queue; public class Mapping { public ArrayList<Integer> algorithm_mapping (int[] f, int n) { if(f == null || f.length == 0) return null; ArrayList<Integer> s = new ArrayList<Integer>(); int[] c = new int[n]; //计数器 for (int i = 0; i < n; i++) s.add(Integer.valueOf(i)); for(int i = 0; i < n; i++) c[i] = 0; for (int i = 0; i < n; i++) c[f[i]]++; Queue<Integer> queue = new ArrayDeque<Integer>(); for(int i = 0; i < n; i++) { if (c[i] == 0) queue.offer(i); while(!queue.isEmpty()) { Integer j = queue.poll(); if (s.remove(j)) c[f[j]]--; if (c[f[j]] == 0) queue.offer(f[j]); } } return s;}public static void main(String[] args) { // TODO Auto-generated method stub Mapping m = new Mapping(); int[] f = new int[]{2,0,0,4,4,3,5}; ArrayList<Integer> result = m.algorithm_mapping(f,f.length); System.out.println(result.toString());}
}
`
阅读全文
0 0
- 算法引论--寻找一对一映射
- 算法引论--寻找一对一映射
- 算法引论
- 算法引论
- 算法引论
- 一对一映射
- 映射 一对一
- 映射一对一
- 一对一映射
- 一对一映射
- 一对一映射
- KMP算法引论
- 算法引论--多项式求值
- JPA关联映射 - 一对一映射
- hibernate映射关系一对一映射
- hibernate映射之一对一映射
- hibernate一对一映射例子
- hibernate一对一关联映射--
- Android模拟器端口被占用问题的解决办法
- yii1电子商城总结
- 在eclipse中把Tomcat 删掉不能重建问题
- 数据结构二叉树
- 怎样用Java写一个计算两个日期之间相差天数的GUI程序?
- 算法引论--寻找一对一映射
- codevs 3037 线段覆盖5 (dp+二分+快排)
- yii数据操作与widget
- XHTML的概念以及和HTML的区别
- 处理模运算
- C++学习笔记(一)
- 凡事都有例外-父类型依赖子类型
- C语言结构体相关知识
- yii 电子商城后台