摘要: 使用位图生成真值组合。
难度: 初级。
 
/**
* 问题描述: 给定 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实现使用位图生成真值组合的更多相关文章

  1. java二维码生成-谷歌(Google.zxing)开源二维码生成学习及实例

    java二维码生成-谷歌(Google.zxing)开源二维码生成的实例及介绍   我们使用比特矩阵(位矩阵)的QR码编码在缓冲图片上画出二维码 实例有以下一个传入参数 OutputStream ou ...

  2. JAVA WEB项目中生成验证码及验证实例(附源码及目录结构)

    [我是一个初学者,自己总结和网上搜索资料,代码是自己敲了一遍,亲测有效,现将所有的目录结构和代码贴出来分享给像我一样的初学者] 作用 验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计 ...

  3. 疯狂位图之——位图生成12GB无重复随机乱序大整数集

    上一篇讲述了用位图实现无重复数据的排序,排序算法一下就写好了,想弄个大点数据测试一下,因为小数据在内存中快排已经很快. 一.生成的数据集要求 1.数据为0--2147483647(2^31-1)范围内 ...

  4. Verilog-FPGA硬件电路设计之一——if语句优先级(always块中的阻塞赋值生成的组合逻辑电路是按照顺利执行的)

    出处:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM 综合软件:Quartus II 一.有优先级的if语句 if..else if.. else i ...

  5. java自带uuid生成

    java自带uuid生成UUID.randomUUID().toString()

  6. 【java】Freemarker 动态生成word(带图片表格)

    1.添加freemarker.jar 到java项目. 2.新建word文档. 3.将文档另存为xml 格式. 4.将xml格式化后打开编辑(最好用notepad,有格式),找到需要替换的内容,将内容 ...

  7. 如何获取java运行时动态生成的class文件?

    查看运行时生成的文件,以更清楚运行情况. 查看动态生成的类,一般有两个方法: 1. 使用据说是jdk自带包sa-jdi.jar里的工具. 其中,不想自己搞,当然就利用下,sa-jdi.jar 里自带的 ...

  8. Java二维码生成与解码

      基于google zxing 的Java二维码生成与解码   一.添加Maven依赖(解码时需要上传二维码图片,所以需要依赖文件上传包) <!-- google二维码工具 --> &l ...

  9. java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串

    java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 package com.zdz.test; im ...

随机推荐

  1. java -jar Test.jar找不到main class问题

    如果你写了一些class,编 译到一个jar里面,但是在执行这个jar的时候报错,找不到main class,但是你明明是有的,是不是很郁闷,检查一下你的jar吧. 解压你的jar,打开META-IN ...

  2. Nginx(三)-- 配置文件之日志管理

    1.日志文件的默认存放位置 默认的日志文件存放位置在:nginx/logs/ 文件夹下,logs文件夹下有:access.log   error.log   nginx.pid 文件 2.nginx. ...

  3. Java之类型的转换

    1.String 类型转化为 int 类型,需要使用 Integer 类中的 parseInt() 方法或者 valueOf() 方法进行转换. int a = Integer.parseInt(st ...

  4. Linux系统故障排除

    可能出现的故障: 1,管理员密码忘记 进入单用户模式修改密码 2.系统无法正常启动 a.grub损坏(MBR损坏,grub配置文件丢失) b.系统初始化故障(某文件系统无法正常挂载.驱动不兼容) c. ...

  5. JAXB简单样例

    参考网页:http://www.mkyong.com/java/jaxb-hello-world-example/JAXB完整教程:https://jaxb.java.net/tutorial/1.J ...

  6. Apktool源码解析——第二篇

    上一篇讲到ApkDecoder这个类,大部分调用到还是Androlib类,而且上次发现brutall的代码竟然不是最新的,遂去找iBotP.的代码了. 今天来看Androlib的代码: private ...

  7. java 中的String类型数据添加双引号

    转义符 \ 加上引号   \" <?xml version="1.0"encoding="GBK"?> String temp = &qu ...

  8. Oracle正在执行和执行过的SQL语句

    1.正在执行的SQL select a.username, a.sid,b.SQL_TEXT, b.SQL_FULLTEXT from v$session a, v$sqlarea b where a ...

  9. Charles(网络封包分析工具)

    一.what Charles工具是通过将自己设置成系统的网络访问代理服务器,使得所有的网络访问请求都通过它来完成,从而实现了网络封包的截取和分析. 它能实现以下 支持SSL代理:截取分析SSL的请求. ...

  10. 性能分析工具gprof介绍(转载)

    性能分析工具gprof介绍Ver:1.0 目录1. GPROF介绍 42. 使用步骤 43. 使用举例 43.1 测试环境 43.2 测试代码 43.3 数据分析 53.3.1 flat profil ...