入门指南:理解ASCII编码在Java中的应用
前言
小伙伴们,你们好呀!我是老寇!
我们都知道计算机只能理解二进制码,一个二进制位(bit)只有0或1两种状态,而一个字节(byte)由8个二进制位组成,因此有256种组合,即00000000 ~ 111111111。
ASCII编码是美国制定的一套字符编码,对英文的字符和二进制位之间的关系,做了统一规定,沿用至今。
ASCII编码一共规定了128个字符,包括阿拉伯数字、大小写字母、其他字符(空格、换行.....)
48~57为0到9十个阿拉伯数字: '0'~'9'
65~90为26个大写英文字母 :'A'~'Z'
97~122号为26个小写英文字母:'a'~'z'
之所以只有128个字符,是因为最前面的一位统一规定为 0
如果是使用英语是没有问题,但是欧洲的一些不使用英语的国家,却发现128个字符不够用,又扩展了一些字符,加入一些带重音的字符、希腊字母等等字符加进去,由原本 0 最高位改成 1
拓展出来了128个二进制数,即10000000 ~ 111111111,从而涵盖基本的西欧语言。
说到这里,厉害啦我的国,中国NB!
随着使用计算机的国家越来越多,ascii编码不能满足我们汉语的需要,需要扩展字符集,因此国家标准总局发布了一套国家标准,也就是gb2312(简体中文),后面又加入了生僻字、繁体字等等,就有了后面的gbk字符集。gbk又是向下兼容gb2312。
每个国家都有一套自己的编码系统,通过编码和解码出来的字符五花八门,出现了乱码的情况,因此,为了实现跨语言、跨平台的文本转换和处理需求,ISO国际标准化组织提出了Unicode的新标准,Unicode字符集涵盖了世界上所有的文字和符号字符,Unicode编码为字符集中的每一个字符指定了唯一的二进制编码,彻底解决之前不同编码系统的冲突和乱码问题。
正文
我们一起看个程序
public class Ascii { public static void main(String[] args) { char c = 23495; System.out.println("Unicode编码:" + c); char chinese = '寇'; int number = chinese; System.out.println("中文的Unicode码:" + number); char upper = 'A'; number = upper; System.out.println("大写字母的ASCII码:" + number); char lower = 'a'; number = lower; System.out.println("小写字母的ASCII码:" + number); char num = '0'; number = num; System.out.println("数字的ASCII码:" + number); System.out.println("Unicode码为23495,强制类型转换为" + (char)23495); System.out.println("ASCII码为65,强制类型转换为" + (char)65); System.out.println("ASCII码为97,强制类型转换为" + (char)97); System.out.println("ASCII码为48,强制类型转换为" + (char)48); //char向上兼容int,因此'c'和'a'会转成int再进行计算 System.out.println("'c'减去'a':" + ('c' - 'a')); } }
Unicode编码:寇
中文的Unicode码:23495
大写字母的ASCII码:65
小写字母的ASCII码:97
数字的ASCII码:48
Unicode码为23495,强制类型转换为寇
ASCII码为65,强制类型转换为A
ASCII码为97,强制类型转换为a
ASCII码为48,强制类型转换为0
'c'减去'a':2
运行结果分析:每个字符都有唯一对应的编码值,而char转换为int类型,不需要强制类型转换,而int转为char需要强制类型转换。
byte 取值范围:-2^8 ~ 2^8-1,即 -128 ~ 127
char 取值范围: 0 ~ 65535
int 取值范围: -2^31 ~ 2^31-1,即 -2147483648 ~ 2147483647
=> int > char,因此char能够向上兼容int,但是int要强制类型转换为char。
说到这里,你们可能就有疑问啦,为什么char可以存汉字?这是因为char是按照字符存储的,不管英文还是中文,固定占用占用2个字节,用来储存Unicode字符。范围在0~65536。
c语言说的char类型与我们java的byte类型是一致的
补充:char是有16个二进制位,2个字节,希望大家不要与c语言的char类型弄混淆啦
结论:如果是做算法题并且只有字母的情况下,完全没有必要开辟256,这样做会造成资源浪费,通过减'a'的方式,将数组长度缩小到26
技巧:求重复数字可以通过arr[i]++方式来做,arr[i]++ => arr[i] = arr[i] + 1,arr[i]能够充当临时变量
上一篇: 暄桐教室推荐的50本必读好书清单:第三十九本《前朝梦忆》
下一篇: 多任务处理:第一课:我的线程旅程
推荐阅读
-
贪婪算法在 Python、JavaScript、Java、C++ 和 C# 中的多种实现及其在硬币变化、分数骑士、活动选择和使用哈夫曼编码的最小生成树问题中的应用实例
-
NeurIPS 2022 | 最强斗地主AI!网易互娱AI Lab提出基于完美信息蒸馏的方法-完美信息蒸馏(PTIE) 在斗地主游戏中,非完美信息的引入主要是由于三位玩家均不能看到别人的手牌,对于任意一位玩家而言,仅可知道其余两位玩家当前手牌的并集,而难于精准判断每位玩家当前手牌。完美信息蒸馏的思路是针对这种非完美问题,构建一个第三方角色,该角色可以看到三位玩家的手牌,该角色在不告知每位玩家完美信息的情况下通过信息蒸馏的方式引导玩家打出当前情况下合理的出牌。 以强化学习常用的 Actor-Critic 算法为例,PTIE 在 Actor-Critic 算法的应用中可以利用 Critic 的 Value 输出作为蒸馏手段来提升 Actor 的表现。具体而言即在训练中 Critic 的输入为完美信息(包含所有玩家的手牌信息),Actor 的输入为非完美信息(仅包含自己手牌信息),此种情况下 Critic 给予的 Value 值包含了完美信息,可以更好地帮助 Actor 学习到更好的策略。 从更新公式上来看,正常的 Actor-Critic 算法 Actor 更新的方式如下: 在 PTIE 模式下,对于每个非完美信息状态 h,我们可以在 Critic 中构建对应的完美信息状态 D(h),并用 Critic 的输出来更新 Actor 的策略梯度,从而达到完美信息蒸馏的效果。 PTIE 框架的整体结构如下图所示: 无论是训练还是执行过程中智能体都不会直接使用完美信息,在训练中通过蒸馏将完美信息用于提升策略,从而帮助智能体达到一个更高的强度。 PTIE 的另一种蒸馏方式是将完美信息奖励引入到奖励值函数的训练中,PerfectDou 提出了基于阵营设计的完美信息奖励 node reward,以引导智能体学习到斗地主游戏中的合作策略,其定义如下: 如上所示,完美信息部分 代表 t 时刻地主手牌最少几步可以出完,在斗地主游戏中可以近似理解为是距游戏获胜的距离, 代表 t 时刻地主阵营和农民阵营距游戏获胜的距离之差, 为调节系数。通过此种奖励设计,在训练时既可以一定程度地引入各玩家的手牌信息(出完的步数需要知道具体手牌才能计算),同时也鼓励农民以阵营的角度做出决策,提升农民的合作性。 特征构建: PerfectDou 针对牌类游戏的特点主要构建了两部分特征:牌局状态特征和动作特征。其中牌局状态特征主要包括当前玩家手牌牌型特征、当前玩家打出的卡牌牌型特征、玩家角色、玩家手牌数目等常用特征,动作特征主要用于刻画当前状态下玩家的所有可能出牌,包括了每种出牌动作的牌型特征、动作的卡牌数目、是否为最大动作等特征。 牌型特征为 12 * 15 的矩阵,如下图所示: 该矩阵前 4 行代表对应每种卡牌的张数,5-12 行代表该种卡牌的种类和对应位置。 网络结构和动作空间设计 针对斗地主游戏出牌组合数较多的问题,PerfectDou 基于 RLCard 的工作上对动作空间进行了简化,对占比最大的两个出牌牌型:飞机带翅膀和四带二进行了动作压缩,将整体动作空间由 27472 种缩减到 621 种。 PerfectDou 策略网络结构如下图所示: 策略网络结构同样分为两部分:状态特征部分和动作特征部分。 在状态特征部分,LSTM 网络用于提取玩家的历史行为特征,当前牌局状态特征和提取后的行为特征会再通过多层的 MLP 网络输出当前的状态信息 embedding。 在动作特征部分,每个可行动作同样会经过多层 MLP 网络进行编码,编码后的动作特征会与其对应的状态信息 embedding 经过一层 MLP 网络计算两者间的相似度,并经由 softmax 函数输出对应的动作概率。 实验结果
-
Java 类加载器的作用 - 简介:类加载器是 Java™ 中一个非常重要的概念。类加载器负责将 Java 类的字节码加载到 Java 虚拟机中。本文首先详细介绍了 Java 类加载器的基本概念,包括代理模型、加载类的具体过程和线程上下文类加载器等。然后介绍了如何开发自己的类加载器,最后介绍了类加载器在 Web 容器和 OSGi™ 中的应用。 类加载器是 Java 语言的一项创新,也是 Java 语言广受欢迎的重要原因之一。它允许将 Java 类动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 开始出现,最初是为了满足 Java Applets 的需求而开发的,Java Applets 需要从远程位置下载 Java 类文件并在浏览器中执行。现在,类加载器已广泛应用于网络容器和 OSGi。一般来说,Java 应用程序的开发人员不需要直接与类加载器交互;Java 虚拟机的默认行为足以应对大多数情况。但是,如果遇到需要与类加载器交互的情况,而您又不太了解类加载器的机制,就很容易花费大量时间调试异常,如 ClassNotFoundException 和 NoClassDefFoundError。本文将详细介绍 Java 的类加载器,帮助读者深入理解 Java 语言中的这一重要概念。下面先介绍一些基本概念。 类加载器的基本概念 顾名思义,类加载器用于将 Java 类加载到 Java 虚拟机中。一般来说,Java 虚拟机以如下方式使用 Java 类:Java 源程序(.java 文件)经 Java 编译器编译后转换为 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码并将其转换为 java.lang 实例。每个实例都用来表示一个 Java 类。通过该实例的 newInstance 方法创建该类的对象。实际情况可能更加复杂,例如,Java 字节代码可能是由工具动态生成或通过网络下载的。 基本上,所有类加载器都是 java.lang.ClassLoader 类的实例。下面将详细介绍这个 Java 类。 java.lang.ClassLoader 类简介 java.lang.ClassLoader 类的基本职责是根据给定类的名称为其查找或生成相应的字节码,然后根据这些字节码定义一个 Java 类,即 java.lang.Class 类的实例。除此之外,ClassLoader 还负责加载 Java 应用程序所需的资源,如图像文件和配置文件。不过,本文只讨论它加载类的功能。为了履行加载类的职责,ClassLoader 提供了许多方法,其中比较重要的方法如表 1 所示。下文将详细介绍这些方法。 表 1.与加载类相关的 ClassLoader 方法
-
玩转Kotlin性能测试:JMH入门指南一 - 测试基础" "深入理解JMH在Kotlin中的应用:基准测试实战解析" "轻松实践Kotlin基准测试:JMH工具详解与实例总结
-
入门指南:理解ASCII编码在Java中的应用
-
第四章复习指南:理解网络模拟器在软考网络规划师中的应用
-
深度学习中的不确定性量化:2020年实用技术与应用大解析 - 61页精华解读" 这份报告深入剖析了近年来深度学习领域中不确定性量化(UQ)技术的最新发展,包括其在强化学习(RL)中的运用实例。探讨了贝叶斯近似和集成学习等主流UQ方法在各个具体场景中的广泛应用,比如自动驾驶、目标识别、图像修复、医疗影像分析(如分类和分割)、文本理解(如文本分类和风险评估)、以及生物信息学等多个领域。 报告进一步梳理了UQ方法在深度学习领域的关键应用案例,并针对当前面临的挑战及未来研究方向进行了概览和展望,为这一领域的研究人员和实践者提供了有价值的参考指南。
-
理解与实战:Java SSH库JSch - 用途解析、四大认证法、无密码登录设置、SSH公钥验证深入讲解、三种选择方案、SFTP文件传输详解、Maven集成及实用代码实例 - 专讲JSch在SFTP文件传输中的应用
-
在Java中实现钩子函数的简易理解与应用
-
南邮OJ Web任务大揭秘:层层挑战剖析 1. 挑战一:迷宫般的目录探索 题目作者似乎穷举了所有可能的目录组合,最终在404.php中的