「java分组算法」java 数组排列组合算法

博主:adminadmin 2022-11-23 03:10:07 63

本篇文章给大家谈谈java分组算法,以及java 数组排列组合算法对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

IP 地址排序Java

package src;

import java.util.Comparator;

import java.util.List;

import java.util.ArrayList;

import java.util.Collections;

class Ip { //定义ip bean

int ip1;

int ip2;

int ip3;

int ip4;

public Ip(int ip1, int ip2, int ip3, int ip4) {

this.ip1 = ip1;

this.ip2 = ip2;

this.ip3 = ip3;

this.ip4 = ip4;

}

public int getIp1() {

return ip1;

}

public void setIp1(int ip1) {

this.ip1 = ip1;

}

public int getIp2() {

return ip2;

}

public void setIp2(int ip2) {

this.ip2 = ip2;

}

public int getIp3() {

return ip3;

}

public void setIp3(int ip3) {

this.ip3 = ip3;

}

public int getIp4() {

return ip4;

}

public void setIp4(int ip4) {

this.ip4 = ip4;

}

}

class ComparatorUser implements Comparator {

public int compare(Object arg1, Object arg2) {

Ip ip1 = (Ip) arg1;

Ip ip2 = (Ip) arg2;

int flag = ip1.getIp1() - ip2.getIp1();

if (flag == 0) { //如果一段相等用二段排序,以此类推

flag = ip1.getIp2() - ip2.getIp2();

} else if (flag == 0) {

flag = ip1.getIp3() - ip2.getIp3();

} else if (flag == 0) {

flag = ip1.getIp4() - ip2.getIp4();

}

return flag;

}

}

public class Test {

public static void main(String[] args) {

ListIp ipList = new ArrayListIp(); //定义ip List

ipList.add(new Ip(255, 2, 3, 4)); //存放ip,你的ip是从文本中读出来的.我相信你会读,也会放.

ipList.add(new Ip(172, 7, 8, 2));

ipList.add(new Ip(2, 3, 4, 5));

ipList.add(new Ip(2, 1, 2, 3));

ipList.add(new Ip(1, 2, 3, 4));

ipList.add(new Ip(202, 2, 3, 4));

ComparatorUser comparator = new ComparatorUser();

Collections.sort(ipList, comparator);

for (Ip ip : ipList) { //输出结果,jdk 1.5以上可以这么遍历list,如果你是1.4 就用list的长度遍历即可

System.out.println(ip.getIp1() + "." + ip.getIp2() + "."

+ ip.getIp3() + "." + ip.getIp4());

}

}

}

运行结果如下.

1.2.3.4

2.1.2.3

2.3.4.5

172.7.8.2

202.2.3.4

255.2.3.4

Java程序员在写SQL时常犯的错误!

Java程序员编程时需要混合面向对象思维和一般命令式编程的方法,能否完美的将两者结合起来完全得依靠编程人员的水准:

技能(任何人都能容易学会命令式编程)模式(有些人用“模式-模式”,举个例子,模式可以应用到任何地方,而且都可以归为某一类模式)心境(首先,要写个好的面向对象程序是比命令式程序难的多,你得花费一些功夫)

但当Java程序员写SQL语句时,一切都不一样了。SQL是说明性语言而非面向对象或是命令式编程语言。在SQL中要写个查询语句是很简单的。但在Java里类似的语句却不容易,因为程序员不仅要反复考虑编程范式,而且也要考虑算法的问题。

下面是Java程序员在写SQL时常犯的10个错误(没有特定的顺序)。

1、忘掉NULL

Java程序员写SQL时对NULL的误解可能是最大的错误。也许是因为(并非唯一理由)NULL也称作UNKNOWN。如果被称作 UNKNOWN,这还好理解些。另一个原因是,当你从数据库拿东西或是绑定变量时,JDBC将SQL NULL 和Java中的null对应了起来。这样导致了NULL = NULL(SQL)和null=null(Java)的误解。

对于NULL最大的误解是当NULL被用作行值表达式完整性约束条件时。另一个误解出现在对于NULL 在 NOT IN anti-joins的应用中。

解决方法:

好好的训练你自己。当你写SQL时要不停得想到NULL的用法:这个NULL完整性约束条件是正确的?NULL是否影响到结果?

2、在Java内存中处理数据

很少有Java开发者能将SQL理解的很好。偶尔使用的JOIN,还有古怪的UNION,好吧,但是对于窗口函数呢?还有对集合进行分组呢?许多 的Java开发者将SQL数据加载到内存中,将这些数据转换成某些相近的集合类型,然后再那些集合上面使用边界循环控制结构(至少在Java8的集合升级 以前)执行令人生厌的数学运算。

但是一些SQL数据库支持先进的(而且是SQL标准支持的)OLAP特性,这一特性表现更好而且写起来也更加方便。一个(并不怎么标准的)例子就 是Oracle超棒的MODEL分句。只让数据库来做处理然后只把结果带到Java内存中吧。因为毕竟所有非常聪明的家伙已经对这些昂贵的产品进行了优 化。因此实际上,通过将OLAP移到数据库,你将获得一下两项好处:

便利性。这比在Java中编写正确的SQL可能更加的容易。性能表现。数据库应该比你的算法处理起来更加快.而且更加重要的是,你不必再去传递数百万条记录了。

解决方法:

每次你使用Java实现一个以数据为中心的算法时,问问自己:有没有一种方法可以让数据库代替为我做这种麻烦事。

3、使用UNION代替UNION ALL

和UNION相比UNION ALL还需要额外的关键字。如果SQL标准已经规定了支持,那么可能会更好点。

UNION(允许重复)UNION DISTINCT (去除了重复)

移除重复行不仅很少需要(有时甚至是错的),而且对于带很多行的大数据集合会相当慢,因为两个子select需要排序,而且每个元组也需要和它的子序列元组比较。

注意即使SQL标准规定了INTERSECT ALL和EXCEPT ALL,很少数据库会实现这些没用的集合操作符。

解决方法:

每次写UNION语句时,考虑实际上是否需要UNION ALL语句。

4、通过JDBC分页技术给大量的结果进行分页操作

大部分的数据库都会支持一些分页命令实现分页效果,譬如LIMIT..OFFSET,TOP..START AT,OFFSET..FETCH语句等。即使没有支持这些语句的数据库,仍有可能对ROWNUM(Oracle)或者是ROW NUMBER()、OVER()过滤(DB2、SQL Server2008等),这些比在内存中实现分页更快速。在处理大量数据中,效果尤其明显。

解决方法:

仅仅使用这些语句,那么一个工具(例如JOOQ)就可以模拟这些语句的操作。

5、在Java内存中加入数据

从SQL的初期开始,当在SQL中使用JOIN语句时,一些开发者仍旧有不安的感觉。这是源自对加入JOIN后会变慢的固有恐惧。假如基于成本的 优化选择去实现嵌套循环,在创建一张连接表源前,可能加载所有的表在数据库内存中,这可能是真的。但是这事发生的概率太低了。通过合适的预测,约束和索 引,合并连接和哈希连接的操作都是相当的快。这完全是是关于正确元数据(在这里我不能够引用Tom Kyte的太多)。而且,可能仍然有不少的Java开发人员加载两张表通过分开查询到一个映射中,并且在某种程度上把他们加到了内存当中。

解决方法:

假如你在各个步骤中有从各种表的查询操作,好好想想是否可以表达你的查询操作在单条语句中。

6、在一个临时的笛卡尔积集合中使用 DISTINCT 或 UNION 消除重复项

通过复杂的连接,人们可能会对SQL语句中扮演关键角色的所有关系失去概念。特别的,如果这涉及到多列外键关系的话,很有可能会忘记在JOIN .. ON子句中增加相关的判断。这会导致重复的记录,但或许只是在特殊的情况下。有些开发者因此可能选择DISTINCT来消除这些重复记录。从三个方面来说 这是错误的:

它(也许)解决了表面症状但并没有解决问题。它也有可能无法解决极端情况下的症状。对具有很多列的庞大的结果集合来说它很慢。DISTINCT要执行ORDER BY操作来消除重复。对庞大的笛卡尔积集合来说它很慢,还是需要加载很多的数据到内存中。

解决方法:

根据经验,如果你获得了不需要的重复记录,还是检查你的JOIN判断吧。可能在某个地方有一个很难觉察的笛卡尔积集合。

7、不使用MERGE语句

这并不是一个过失,但是可能是缺少知识或者对于强悍的MERGE语句信心不足。一些数据库理解其它形式的更新插入(UPSERT)语句, 如 MYSQL的重复主键更新语句,但是MERGE在数据库中确是很强大,很重要,以至于大肆扩展SQL标准,例如SQL SERVER。

解决方法:

如果你使用像联合INSERT和UPDATE或者联合SELECT .. FOR UPDATE然后在INSERT或UPDATE等更新插入时,请三思。你完全可以使用一个更简单的MERGE语句来远离冒险竞争条件。

8、使用聚合函数代替窗口函数(window functions)

在介绍窗口函数之前,在SQL中聚合数据意味着使用GROUP BY语句与聚合函数相映射。在很多情形下都工作得很好,如聚合数据需要浓缩常规数据,那么就在join子查询中使用group查询。

但是在SQL2003中定义了窗口函数,这个在很多主流数据库都实现了它。窗口函数能够在结果集上聚合数据,但是却没有分组。事实上,每个窗口函数都有自己的、独立的PARTITION BY语句,这个工具对于显示报告太好了。

使用窗口函数:

使SQL更易读(但在子查询中没有GROUP BY语句专业)提升性能,像关系数据库管理系统能够更容易优化窗口函数

解决方法:

当你在子查询中使用GROUP BY语句时,请再三考虑是否可以使用窗口函数完成。

9、使用内存间接排序

SQL的ORDER BY语句支持很多类型的表达式,包括CASE语句,对于间接排序十分有用。你可能重来不会在Java内存中排序数据,因为你会想:

SQL排序很慢SQL排序办不到

解决方法:

如果你在内存中排序任何SQL数据,请再三考虑,是否不能在数据库中排序。这对于数据库分页数据十分有用。

10、一条一条地插入大量记录

JDBC“懂”批处理(batch),你应该不会忘了它。不要使用INSERT语句来一条一条的出入成千上万的记录,(因为)每次都会创建一个新 的PreparedStatement对象。如果你的所有记录都插入到同一个表时,那么就创建一个带有一条SQL语句以及附带很多值集合的插入批处理语 句。你可能需要在达到一定量的插入记录后才提交来保证UNDO日志瘦小,这依赖于你的数据库和数据库设置。

解决方法:

总是使用批处理插入大量数据。

来自:OSChina

译者:oschina.net/translate/10-common-mistakes-java-developers-make-when-writing-sql

java 按日期分组 算法

直接用SQL语句

select count(id) as 数量,day(date) as 生产日期 from table group by day(date) order by day(czrq)

如果库里不止一个月的数据,那么再加个where条件

开发中常见的加密方式及应用

开发中常见的加密方式及应用

一、base64

简述:Base64是网络上最常见的用于传输8Bit 字节码 的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。所有的数据都能被编码为并只用65个字符就能表示的文本文件。( 65字符:A~Z a~z 0~9 + / = )编码后的数据~=编码前数据的4/3,会大1/3左右(图片转化为base64格式会比原图大一些)。

应用:Base64编码是从二进制到字符的过程,可用于在 HTTP 环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一 标识符 (一般为128-bit的UUID)编码为一个字符串,用作HTTP 表单 和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制 数据编码 为适合放在URL(包括隐藏 表单域 )中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。

命令行进行Base64编码和解码

编码:base64 123.png -o 123.txt

解码:base64 123.txt -o test.png -D Base64编码的原理

原理:

1)将所有字符转化为ASCII码;

2)将ASCII码转化为8位二进制;

3)将二进制3个归成一组(不足3个在后边补0)共24位,再拆分成4组,每组6位;

4)统一在6位二进制前补两个0凑足8位;

5)将补0后的二进制转为十进制;

6)从Base64编码表获取十进制对应的Base64编码;

Base64编码的说明:

a.转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。

b.数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6个bit,按照其值选择查表选择对应的字符作为编码后的输出。

c.不断进行,直到全部输入数据转换完成。

d.如果最后剩下两个输入数据,在编码结果后加1个“=”;

e.如果最后剩下一个输入数据,编码结果后加2个“=”;

f.如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

二、HASH加密/单向散列函数

简述:Hash算法特别的地方在于它是一种单向算法,用户可以通过Hash算法对目标信息生成一段特定长度(32个字符)的唯一的Hash值,却不能通过这个Hash值重新获得目标信息。对用相同数据,加密之后的密文相同。 常见的Hash算法有MD5和SHA。由于加密结果固定,所以基本上原始的哈希加密已经不再安全,于是衍生出了加盐的方式。加盐:先对原始数据拼接固定的字符串再进行MD5加密。

特点:

1) 加密 后密文的长度是定长(32个字符的密文)的

2)如果明文不一样,那么散列后的结果一定不一样

3)如果明文一样,那么加密后的密文一定一样(对相同数据加密,加密后的密文一样)

4)所有的加密算法是公开的

5)不可以逆推反算(不能根据密文推算出明文),但是可以暴力 破解 ,碰撞监测

原理:MD5消息摘要算法,属Hash算法一类。MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要。

1)数据填充

对消息进行数据填充,使消息的长度对512取模得448,设消息长度为X,即满足X mod 512=448。根据此公式得出需要填充的数据长度。

填充方法:在消息后面进行填充,填充第一位为1,其余为0。

2)添加信息长度

在第一步结果之后再填充上原消息的长度,可用来进行的存储长度为64位。如果消息长度大于264,则只使用其低64位的值,即(消息长度 对264取模)。

在此步骤进行完毕后,最终消息长度就是512的整数倍。

3)数据处理

准备需要用到的数据:

4个常数:A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;

4个函数:F(X,Y,Z)=(X Y) | ((~X) Z);G(X,Y,Z)=(X Z) | (Y (~Z));H(X,Y,Z)=X ^ Y ^ Z;I(X,Y,Z)=Y ^ (X | (~Z));

把消息分以512位为一分组进行处理,每一个分组进行4轮变换,以上面所说4个常数为起始变量进行计算,重新输出4个变量,以这4个变量再进行下一分组的运算,如果已经是最后一个分组,则这4个变量为最后的结果,即MD5值。

三、对称加密

经典算法:

1)DES数据加密标准

DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

DES算法是这样工作的:如Mode为加密,则用Key去把数据Data进行加密, 生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。

2)3DES使用3个密钥,对消息进行(密钥1·加密)+(密钥2·解密)+(密钥3·加密)

3)AES高级加密标准

如图,加密/解密使用相同的密码,并且是可逆的

四、非对称加密

特点:

1)使用公钥加密,使用私钥解密

2)公钥是公开的,私钥保密

3)加密处理安全,但是性能极差

经典算法RSA:

1)RSA原理

(1)求N,准备两个质数p和q,N = p x q

(2)求L,L是p-1和q-1的最小公倍数。L = lcm(p-1,q-1)

(3)求E,E和L的最大公约数为1(E和L互质)

(4)求D,E x D mode L = 1

五、数字签名

原理以及应用场景:

1)数字签名的应用场景

需要严格验证发送方身份信息情况

2)数字签名原理

(1)客户端处理

对"消息"进行HASH得到"消息摘要"

发送方使用自己的私钥对"消息摘要"加密(数字签名)

把数字签名附着在"报文"的末尾一起发送给接收方

(2)服务端处理

对"消息" HASH得到"报文摘要"

使用公钥对"数字签名"解密

对结果进行匹配

六、数字证书

简单说明:

证书和驾照很相似,里面记有姓名、组织、地址等个人信息,以及属于此人的公钥,并有认证机构施加数字签名,只要看到公钥证书,我们就可以知道认证机构认证该公钥的确属于此人。

数字证书的内容:

1)公钥

2)认证机构的数字签名

证书的生成步骤:

1)生成私钥openssl genrsa -out private.pem 1024

2)创建证书请求openssl req -new -key private.pem -out rsacert.csr

3)生成证书并签名,有效期10年openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt

4)将PEM格式文件转换成DER格式openssl x509 -outform der -in rsacert.crt -out rsacert.der

5)导出P12文件openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt

iOS开发中的注意点:

1)在iOS开发中,不能直接使用PEM格式的证书,因为其内部进行了Base64编码,应该使用的是DER的证书,是二进制格式的;

2)OpenSSL默认生成的都是PEM格式的证书。

七、https

HTTPS和HTTP的区别:

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。

为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

HTTPS和HTTP的区别主要为以下四点:

1)https协议需要到ca申请证书,一般免费证书很少,需要交费。

2)http是 超文本传输协议 ,信息是明文传输,https则是具有 安全性 的 ssl 加密传输协议。

3)http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

4)http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的 网络协议 ,比http协议安全。

5)SSL:Secure Sockets Layer安全套接字层;用数据加密(Encryption)技术,可确保数据在网络上传输过程中不会被截取及窃听。目前一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全标准,但限制出境。只要3.0版本以上之I.E.或Netscape 浏览器 即可支持SSL。目前版本为3.0。SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

java分组算法的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java 数组排列组合算法、java分组算法的信息别忘了在本站进行查找喔。

The End

发布于:2022-11-23,除非注明,否则均为首码项目网原创文章,转载请注明出处。