有限状态机

  • 前言
  • 一、例题
    • 1、HashMap
    • 2、位运算
    • 3、有限状态机
      • a、如何更新?
      • b、源码
  • 总结
  • 参考文献
  • 附录
    • 补充知识

前言

有限状态机,顾名思义有限个状态在事件的触发下做出相应状态的转换。

一、例题

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

1、HashMap

可以用Map记录一个元素出现的次数,然后遍历Map得到记录次数为1的数字。

public int singleNumber3(int[] nums) {//用map记录该数字是否记录过Map<Integer, Integer> record = new HashMap<>();for (int num : nums) {record.put(num, record.getOrDefault(num, 0) + 1);}//寻找map中记录中只记录一次的数字for (int num : nums) {if (record.get(num) == 1)return num;}return 0;}

2、位运算

Integer,Java中4字节,4 x 8 = 32位,统计每一位为1出现的次数,再对3进行取余,就可以得到单次出现数字该位的值。

public int singleNumber4(int[] nums) {//1.按位相加int[] bit = new int[32];for (int num : nums) {for (int i = 0; i < 32; i++) {bit[i] += (num & (1 << i)) >> i;}}//2.按位对3取余得到结果的每一位int res = 0;for (int i = 0; i < 32; i++) {res |= (bit[i] % 3) << i;}return res;}

3、有限状态机

第二种方法种的对3取余,暗含着每一位上有3种状态,即0,1,2,即状态机0->1->2->0。
1)触发事件为0,状态不发生改变。
2)触发事件为1,状态0 -> 1 -> 2 -> 0这样改变。

注:图片来自于leetcode大神-------K神。
对于二进制,用2位来表示这三个状态,即00 -> 01 -> 10。然后接下来的目的就是更新这两位。(在此记为two one 两位)

a、如何更新?

  1. 更新one位:
if two == 0:if n == 0:one = oneif n == 1:one = ~one
if two == 1:one = 0

如何简化?内层配合two的值,变换的过程就像一个异或过程。

if two == 0:one = one ^ n
if two == 1:one = 0

再次简化,与外层two配合,整个内层与外层就像是逻辑与过程。

one = one ^ n & ~two

  1. 更新two位
    1)本来状态转移之后应该是01->10->00,但是先更新one位,得到01->00->10.
    2)把01->00->10也看成一个状态机,然后根据这个新状态机更新two位,得到01->10->00.(即我们要的结果)
    3)那是不是根据新状态机要再搞一个表达式来更新two?我们发现新状态机01->00->10跟旧状态机10->00->01的两位刚好相反,所以交换位置,用旧表达式来完成更新two.
  1. 如何实施?
    1)上面分析1位的状态如何,Integer有32位,可以同时运算。
    2)最后的状态只有00、01.只需取低位0或1来表示当前位的值。(即取one位)

b、源码

public int singleNumber5(int[] nums) {int ones = 0, twos = 0;for (int num : nums) {ones = ones ^ num & ~twos;twos = twos ^ num & ~ones;}return ones;}

总结

1)HashMap
2)位运算
3)有限状态机(二进制状态转换的简化过程)

参考文献

[1] Leetcode原题
[2] K神
[3] 数据结构与算法
[4] Java取反
[5] 运算符详解及优先级

附录

补充知识

  1. 异或、源码、反码、补码
  2. 运算符优先级
  3. Java中取反操作
    1)二进制取反:~1 = 0;~0 = 1;
    2)Java中数字取反:
    1.在计算机中,所有数据的表示方式都是以补码的方式存在;
    2.正数:符号位为0,原码,反码,补码相同;
    3.负数:符号位为1,补码 = 反码 + 1。

A. 正数取反解析:
step 1:先求得该数的原码;
step 2:原码取反得到答案原码;
step 3:答案原码转为补码,最后化为数值。

B. 负数取反解析:
step 1:先求得该数的原码;
step 2:再求得该数的补码;
step 3:补码取反得到答案补码,最后化为数值。

C. 举例说明:
(1)、~5 = -6过程解析
step 1:表示5的原码
5的原码为:00000000 00000000 00000000 00000101。
step 2:对5的原码取反
得到答案的原码:11111111 11111111 11111111 11111010
step 3:将答案的原码转成补码
通过原码得到反码:10000000 00000000 00000000 00000101
补码 = 反码 + 1:
答案的补码为:10000000 00000000 00000000 00000110
得到值:-6
前文中的答案4就是依此而来,10 + ~5 即为 10 + (-6)= 4。

D. 小结
取反操作符(~)结论总结:
当n为正数时,~(n) = -(n+1)
当n为负数时,~(-n) = n - 1,忽略负号

Java之有限状态机相关推荐

  1. java模拟生存RPG游戏开发

    2013-01-22 MVC 将原有程序,改写为MVC模式,同时学习优化.单例的使用.部分技能开始尝试用状态机实现. 近期最想实现的是,让给矮人添加寻路算法,让他自己动起来.. 2013-01-07 ...

  2. Java常用类库以及简介,具体使用细节进行百度(爬虫爬取的数据)

    来至于互联网 Office文档的Java处理包 POI [推荐] Apache POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目.目前POI已经有了Ruby版本. 结构: ...

  3. 确定有限状态机和非确定有限状态机详解 包含Java实现源码(Nondeterministic finite automata)

    本文将讲解确定有限自动状态机和非确定有限自动状态机的特点和区别.将结合图片例子重点讲解什么是非确定有限自动状态机.最后讲解如何将非确定状态机转换为确定的状态机.多图预警!! 有限自动状态机可以分为确定 ...

  4. 代码重构----使用java有限状态机来消除太多的if else判断

    1. 状态机基本概念 http://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA 状态存储关于过去的信息,就是 ...

  5. 【java有限状态机选型】

    java有限状态机探讨 前言 今天跟大家分享一个关于"状态机"的话题.状态属性在我们的现实生活中无处不在.比如经典的电商场景会有一系列的订单状态(待支付.待发货.已发货.超时.关闭 ...

  6. 有限状态自动机java实现_有限状态机FSM的几种简单实现

    标签: 有限状态机,Akka fsm,squirrel-foundation,java状态模式.责任链模式 1. 有限状态机的概念 有限状态机(英语:finite-state machine,缩写:F ...

  7. java输出abba_java - 有限状态机搜索“ABBA” - 堆栈内存溢出

    我正在尝试编写一个while switch case kinda代码,用于对有限状态机进行建模,该有限状态机搜索As和Bs字符串以查看字符串"ABBA"是否存在. 当我输入&quo ...

  8. Java 有限状态机 (设计模式——状态模式)

    Java 有限状态机 (设计模式--状态模式) 编写代码的时候,有时会遇见较为复杂的swith...case...和if...else...语句.这一刻有时会想到状态机,用有限状态机替换swith.. ...

  9. 基于有限状态机实现敏感词替换(Java)

    问题描述 给你一串字符串,与一组敏感词.将这个字符串中的敏感词全都替换成*号 例: 字符串:"你好你好呀傻逼草泥马情电影情色1234草尼阿三大苏打草泥马1都31321312你的十大恶趣味去& ...

最新文章

  1. pycharm 自动函数注释
  2. android沉浸代码,3秒钟搞定Android沉浸式状态栏
  3. Alcatel 6850实现静态路由
  4. test2 3-16 2021 模拟赛two
  5. android视频通信和web端,探讨用webrtc在手机和浏览器之间实现音视频实时通信的实施环境...
  6. C# 利用类名字符串调用并执行类方法
  7. 新款苹果手表来了!Apple Watch Series 7将于10月8日开售
  8. SuperBrowser简单游览器Android
  9. LINUX用C判断文件是否存在
  10. python编程控制安捷伦电源_安捷伦怎么设置电流电压输出 Agilent/HP 6674A DC电源 程控电源租赁 仪器仪表租赁 硬件测试服务...
  11. 数码相机冲洗照片的数据
  12. 微信小程序中音频播放
  13. 纵横杯2020 web wp
  14. 戴尔游匣7559-拆机磁盘换固态详解
  15. linux 时区文件的规则,linux – 如何将POSIX时间转换为Olson时区文件...
  16. Adobe2022更新,打开photoshop总是提示需要访问钥匙串秘钥怎么解决?
  17. 误删分区怎么办?必备数据恢复工具!
  18. 浙江大学MEM面试小结
  19. led手电筒烧灯珠_LED手电筒充电时候烧了怎么维修?
  20. [GWCTF 2019]枯燥的抽奖 1

热门文章

  1. 进程间通信————共享内存
  2. 中国热固性丙烯酸涂料市场现状及未来发展趋势
  3. 蓝桥算法训练 藏匿的刺客[Java]
  4. 主分区转换成逻辑分区需要多久
  5. 数据流图(DFD)画法
  6. vsuite ramdisk 注册_008-在阿里云物联网平台上一型一密动态注册设备(基于Android) - 杨奉武...
  7. Spring系列之Spring常用注解总结 原文:https://www.cnblogs.com/xiaoxi/p/5935009.html
  8. 2021入职培训有感:站在新的起点,迎接新的挑战
  9. 每日一书丨这是一本演示如何在实际应用中利用设计模式的书
  10. nginx + nginx-http-flv-module-1.2.10(包含nginx-rtmp-module) + video标签播放 http-flv 视频