Java实现使用位图生成真值组合
/**
* 问题描述: 给定 n 个布尔变量,打印所有真值组合。
* 例如, n = 2 时 , 所有真值组合为 (true, false),(true, true),(false, true),(false, false).
*
* 算法的基本思路:
* 使用一个长度为 n 的数组存储着 n 个布尔变量;位 1 表示 true , 位 0 表示 false,
* 生成每一个真值元组,实际上是生成一个由 0 和 1 表示的 数组。
*
* 生成每一个真值元组的方法:从零开始,逐次加一。
* 比如 000 -> 001 -> 010 -> 011 -> 100 -> 101 -> 110 -> 111
*
* 具体算法:
* 每次都从最低位开始,将最低位作【置 一】处理 :
* ① 如果最低位是 0 , 则置 1 即可【不进位】;
* ② 如果最低位为 1 , 则置 0 ; 由于有进位,进一步将次低位作【置一】处理。
* 直至某一位由 0 置 1 为止 【不进位】。
*
* 例如: 011 :
* ① 最低位为1, 置 0 , 并进位;
* ② 次低位为1, 置 0 , 并进位;
* ③ 次次低位为 0 , 置 1。 结果为 100
*
*
* 技巧:
* ① 由于这里只涉及置 1 或 置 0 , 实际上就是置 true 或 置 false ,
* 因此, 可以直接在数组里存储布尔值,并不必要在 1,0 和 true, false 之间转换。
*
* ② 设置一个结束标识变量 endflag ,当 1..1 -> 0..0 时 设置为 true
*
*/ package algorithm; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; public class Combination { private boolean[] combination ;
private long count;
private boolean endflag; public Combination(int n) {
if (n <= 0)
throw new IllegalArgumentException("参数必须为正整数");
if (combination == null) {
combination = new boolean[n];
count = 0;
endflag = false;
}
} /**
* 求解问题,打印所有的真值组合结果。
*
*/
public void solution()
{
System.out.println("n = " + combination.length + " ***** 所有真值组合: ");
do {
System.out.println(getOneTuple());
count++;
increOne();
} while(!terminate());
System.out.println("真值组合数: " + count);
} /**
* 逐次加一,生成每一个真值元组
*
*/
private void increOne()
{
int i;
for (i=0; i < combination.length; i++) {
// 若为 0 ,则置 1 , 结束。
if (combination[i] == false) {
combination[i] = true;
break;
}
else {
// 若为 1, 则置 0, 并通过 i++ 转至次低位进行相同处理
combination[i] = false;
}
}
// 由 1..1 -> 0..0 时, 设置 endflag = true;
if (i == combination.length) { endflag = true; }
} /**
* 根据整数数组表示生成的真值元组,转化为布尔数组表示生成的真值元组。
*
*/
private String getOneTuple()
{
StringBuilder tuple = new StringBuilder("(");
for (int i=0; i < combination.length; i++) {
tuple.append(combination[i]);
tuple.append(",");
}
// 删除 多余的 逗号
tuple.deleteCharAt(tuple.length()-1);
tuple.append(")");
return tuple.toString();
} /**
* 终止条件: 结束标识符 endflag = true;
*
*/
private boolean terminate()
{
return endflag == true;
} public static void main(String[] args) {
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
try {
String s = null;
while ((s = stdin.readLine()).matches("[1-9][0-9]*")) {
int n = Integer.parseInt(s);
System.out.println("n = " + n);
Combination c = new Combination(n);
c.solution();
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
// Combination c = new Combination(3);
// c.solution();
} }
算法分析:
总的运行时间由两部分组成: 置一处理时间 和 判断结束时间。
T(n) = setBit(n) + judgeEnd(n)
其中: judgeEnd(n) = 2^n ,因为从 0..0 -> 1..1 -> 0..0 每次变换做一个简单的比较操作,endflag == true ,总共花时 2^n
下面计算 setBit(n) :
n = 1 时 0 -> 1 setBit(1) = 1;
n = 2 时 00-> 01 -> 10 -> 11 setBit(2) = 121 【置位次数:1+2+1】
n = 3 时 000 –> 001 -> 010 -> 011 -> 100 -> 101 -> 110 -> 111 setBit(3) = 1213121
n = 4 时 0000 -> 0001 -> 0010 -> 0011 -> 0100 -> 0101 -> 0110 -> 0111 -> 1000 -> 1001 -> .. -> 1111 setBit(4) = 121312141213121
归纳可得:
setBit(n) = n + 2setBit(n-1) setBit(1) = 1 ; 解得: setBit(n) = O(n^2)
故 T(n) = 2^n
Java实现使用位图生成真值组合的更多相关文章
- java二维码生成-谷歌(Google.zxing)开源二维码生成学习及实例
java二维码生成-谷歌(Google.zxing)开源二维码生成的实例及介绍 我们使用比特矩阵(位矩阵)的QR码编码在缓冲图片上画出二维码 实例有以下一个传入参数 OutputStream ou ...
- JAVA WEB项目中生成验证码及验证实例(附源码及目录结构)
[我是一个初学者,自己总结和网上搜索资料,代码是自己敲了一遍,亲测有效,现将所有的目录结构和代码贴出来分享给像我一样的初学者] 作用 验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计 ...
- 疯狂位图之——位图生成12GB无重复随机乱序大整数集
上一篇讲述了用位图实现无重复数据的排序,排序算法一下就写好了,想弄个大点数据测试一下,因为小数据在内存中快排已经很快. 一.生成的数据集要求 1.数据为0--2147483647(2^31-1)范围内 ...
- Verilog-FPGA硬件电路设计之一——if语句优先级(always块中的阻塞赋值生成的组合逻辑电路是按照顺利执行的)
出处:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM 综合软件:Quartus II 一.有优先级的if语句 if..else if.. else i ...
- java自带uuid生成
java自带uuid生成UUID.randomUUID().toString()
- 【java】Freemarker 动态生成word(带图片表格)
1.添加freemarker.jar 到java项目. 2.新建word文档. 3.将文档另存为xml 格式. 4.将xml格式化后打开编辑(最好用notepad,有格式),找到需要替换的内容,将内容 ...
- 如何获取java运行时动态生成的class文件?
查看运行时生成的文件,以更清楚运行情况. 查看动态生成的类,一般有两个方法: 1. 使用据说是jdk自带包sa-jdi.jar里的工具. 其中,不想自己搞,当然就利用下,sa-jdi.jar 里自带的 ...
- Java二维码生成与解码
基于google zxing 的Java二维码生成与解码 一.添加Maven依赖(解码时需要上传二维码图片,所以需要依赖文件上传包) <!-- google二维码工具 --> &l ...
- java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串
java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 package com.zdz.test; im ...
随机推荐
- ios学习--TableView详细解释
-.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [DataTa ...
- java基础----->TCP和UDP套接字编程
这里简单的总结一下TCP和UDP编程的写法,另外涉及到HttpUrlConnection的用法 . TCP套接字 一.项目的流程如下说明: .客户输入一行字符,通过其套接字发送到服务器. .服务器从其 ...
- LeetCode——Single Number II
Description: Given an array of integers, every element appears three times except for one. Find that ...
- SSH电力项目四-显示首页
1.登录页面: 将上一节中的页面放到/WEB-INF/page/目录下,需要登录后才能访问该页面: 对应页面:/WEB-INF/page/menu/home.jsp <%@ page langu ...
- java如何发起https请求
1.写一个SSLClient类,继承至HttpClient import java.security.cert.CertificateException; import java.security.c ...
- angularJS的过滤器!
angularJS过滤器: filter currency date filter json limitTo lowercase number orderBy uppercase ...... Fil ...
- Think PHP递归重新排序无限极子分类数组(递归无限极分类)
Think PHP递归重新排序无限极子分类数组 // 递归重新排序无限极子分类数组 function recursive($array,$pid=0,$level=0){ $arr = array() ...
- 170808、生成为CVS文件
/** * Desc : 生成为CVS文件 * User : RICK * @param data 源数据List * @param map csv文件的列表头map * @param outPutP ...
- 170518、FastDFS_配置文件详解
http://bbs.chinaunix.net/thread-1941456-1-1.html 首先是 tracker.conf # is this config file disabled # f ...
- C# 生成四位数字字母混合验证码
private static void Rand() { var arr = new List<string>(); ; i < ; i++) { arr.Add(i.ToStrin ...