Provide Best Programming Tutorials

拆解复杂问题:实现计算器

我们最终要实现的计算器功能如下: 1、输入一个字符串,可以包含+ - * /、数字、括号以及空格,你的算法返回运算结构。 2、要符合运算法则,括号的优先级最高,先乘除后加减。 3、除号是整数除法,无论正负都向 0 取整(5/2=2,-5/2=-2)。 4、可以假定输入的算式一定合法,且计算过程不会出现整型溢出,不会出现除数为 0 的意外情况。 比如输入如下字符串,算法会返回 9: 3 * (2-6 /(3 -7)) 可以看到,这就已经非常接近我们实际生活中使用的计算器了,虽然我们以前肯定都用过计算器,但是如果简单思考一下其算法实现,就会大惊失色: 1、按照常理处理括号,要先计算最内层的括号,然后向外慢慢化简。这个过程我们手算都容易出错,何况写成算法呢! 2、要做到先乘除,后加减,这一点教会小朋友还不算难,但教给计算机恐怕有点困难。 3、要处理空格。我们为了美观,习惯性在数字和运算符之间打个空格,但是计算之中得想办法忽略这些空格。 我记得很多大学数据结构的教材上,在讲栈这种数据结构的时候,应该都会用计算器举例,但是有一说一,讲的真的垃圾,不知道多少未来的计算机科学家就被这种简单的数据结构劝退了。 那么本文就来聊聊怎么实现上述一个功能完备的计算器功能,关键在于层层拆解问题,化整为零,逐个击破,相信这种思维方式能帮大家解决各种复杂问题。 下面就来拆解,从最简单的一个问题开始。 一、字符串转整数 是的,就是这么一个简单的问题,首先告诉我,怎么把一个字符串形式的正整数,转化成 int 型?…

Continue Reading

数字证书原理

文中首先解释了加密解密的一些基础知识和概念,然后通过一个加密通信过程的例子说明了加密算法的作用,以及数字证书的出现所起的作用。接着对数字证书做一个详细的解释,并讨论一下windows中数字证书的管理,最后演示使用makecert生成数字证书。如果发现文中有错误的地方,或者有什么地方说得不够清楚,欢迎指出! 1、基础知识       这部分内容主要解释一些概念和术语,最好是先理解这部分内容。 1.1、公钥密码体制(public-key cryptography) 公钥密码体制分为三个部分,公钥、私钥、加密解密算法,它的加密解密过程如下: 加密:通过加密算法和公钥对内容(或者说明文)进行加密,得到密文。加密过程需要用到公钥。解密:通过解密算法和私钥对密文进行解密,得到明文。解密过程需要用到解密算法和私钥。注意,由公钥加密的内容,只能由私钥进行解密,也就是说,由公钥加密的内容,如果不知道私钥,是无法解密的。 公钥密码体制的公钥和算法都是公开的(这是为什么叫公钥密码体制的原因),私钥是保密的。大家都以使用公钥进行加密,但是只有私钥的持有者才能解密。在实际的使用中,有需要的人会生成一对公钥和私钥,把公钥发布出去给别人使用,自己保留私钥。 1.2、对称加密算法(symmetric key algorithms) 在对称加密算法中,加密使用的密钥和解密使用的密钥是相同的。也就是说,加密和解密都是使用的同一个密钥。因此对称加密算法要保证安全性的话,密钥要做好保密,只能让使用的人知道,不能对外公开。这个和上面的公钥密码体制有所不同,公钥密码体制中加密是用公钥,解密使用私钥,而对称加密算法中,加密和解密都是使用同一个密钥,不区分公钥和私钥。         // 密钥,一般就是一个字符串或数字,在加密或者解密时传递给加密/解密算法。前面在公钥密码体制中说到的公钥、私钥就是密钥,公钥是加密使用的密钥,私钥是解密使用的密钥。   1.3、非对称加密算法(asymmetric key algorithms) 在非对称加密算法中,加密使用的密钥和解密使用的密钥是不相同的。前面所说的公钥密码体制就是一种非对称加密算法,他的公钥和是私钥是不能相同的,也就是说加密使用的密钥和解密使用的密钥不同,因此它是一个非对称加密算法。 1.4、RSA简介 RSA是一种公钥密码体制,现在使用得很广泛。如果对RSA本身有兴趣的,后面看我有没有时间写个RSA的具体介绍。 RSA密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。 由公钥加密的内容可以并且只能由私钥进行解密,并且由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以由并且只能由对方进行解密。 1.5、签名和加密 我们说加密,是指对某个内容加密,加密后的内容还可以通过解密进行还原。 比如我们把一封邮件进行加密,加密后的内容在网络上进行传输,接收者在收到后,通过解密可以还原邮件的真实内容。 这里主要解释一下签名,签名就是在信息的后面再加上一段内容,可以证明信息没有被修改过,怎么样可以达到这个效果呢?一般是对信息做一个hash计算得到一个hash值,注意,这个过程是不可逆的,也就是说无法通过hash值得出原来的信息内容。在把信息发送出去时,把这个hash值加密后做为一个签名和信息一起发出去。 接收方在收到信息后,会重新计算信息的hash值,并和信息所附带的hash值(解密后)进行对比,如果一致,就说明信息的内容没有被修改过,因为这里hash计算可以保证不同的内容一定会得到不同的hash值,所以只要内容一被修改,根据信息内容计算的hash值就会变化。当然,不怀好意的人也可以修改信息内容的同时也修改hash值,从而让它们可以相匹配,为了防止这种情况,hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。至于如何让别人可以解密这个签名,这个过程涉及到数字证书等概念,我们后面在说到数字证书时再详细说明,这里您先只需先理解签名的这个概念。 2、一个加密通信过程的演化…

Continue Reading

编程作业 — JSP

JSP中的阶乘表 使用JSP重写Servlet章节作业的第一题,显示阶乘表如图A所示 JSP中的乘法表 使用JSP重写Servlet章节作业的第一题,显示惩罚表格,如上图b所示 在JSP中计算税款 编写HTML表单以提示用户输入应纳税收入和备案状态,如图a所示。 单击计算税按钮,如图b所示。 修改密码 假设用户信息保存在数据库的表里,这个表叫Account,有三个字段:username,password和name。name代表用户的真实姓名。 这个Servlet完成以下功能: 验证用户名和密码是存在于数据库表里的。如果不是,则在网页上报告一个错误。确保用户两次输入的密码是一致的,否则报错如果没有问题,那么就更新用户的密码,并且把执行结果返回到网页上,如图b所示 在JSP中存储cookie 编写一个Servlet来存储以下的cookie到你的浏览器里,并且设置这些cookie的有效期为2两天。 Cookie 1: name is “color” and value is red. Cookie 2: name is “radius” and value is…

Continue Reading

章节总结-Java编程基础

Java 是平台无关的,这意味着只需编写一次程序,就可以在任何计算机上运行。Java 源程序文件名必须和程序中的公共类名一致,并且以扩展名.java 结束。每个类都被编译成一个独立的宇节码文件,该文件名与类名相同,扩展名为.class。使用javac 命令可以从命令行编译Java 源代码文件。使用java 命令可以从命令行运行Java 类。每个Java 程序都是一套类的定义集合。关键字class 引人类的定义,类的内容包含在块内。一个块以左花括号({)开始,以右花括号(})结束。方法包含在类中。每个可执行的Java 程序必须有一个main 方法。main 方法是程序开始执行的人口。Java 中的每条语句都是以分号(;)结束的,也称该符号为语句结束符。保留字或者称关楗字,对编译器而言都有特殊含义,在程序中不能用于其他目的。在 Java中,在单行上用两个斜杠( // )引导注释,称为行注释;在一行或多行用/ * 和 */包含注释,称为块注释或者段注释。编译器会忽略注释。Java 源程序是区分大小写的。编程错误可以分为三类:语法错误、运行时错误和逻辑错误。编译器报告的错误称为语法错误或者编译错误。运行时错误指引起程序非正常结束的错误。当一个程序没有按照预期的方式执行时,产生逻辑错误。

Continue Reading

Java各版本新特性

前言 更新的太快了,都学不过来了,最近了解一些Java8以后的一些特性,写下来希望对大家有帮助。 为什么选择Java11 容器环境支持,GC等领域的增强。进行了瘦身,更轻量级,安装包体积小。JDK11 是一个长期支持版。 这里大家可以关注一下我的个人专栏《Java 进阶集中营》,每天会给大家即时分享一个最新的java技术资讯,有优秀的java技术内容,也欢迎分享在我的专栏。JAVA 进阶集中营​zhuanlan.zhihu.com 特性介绍 由于直接从Java8跨越到Java11,所以特性介绍就把Java9-Java11的部分特性一起介绍一下。 Jshell @since 9 Jshell在Java9中就被提出来了,可以直接在终端写Java程序,回车就可以执行。Jshell默认会导入下面的一些包,所以在Jshell环境中这些包的内容都是可以使用的。 import java.lang.*; import java.io.*; import java.math.*; import java.net.*; import java.nio.file.*; import java.util.*; import java.util.concurrent.*; import java.util.function.*;…

Continue Reading
Close Menu