JAVA_算法_中国公历算法&中国农历算法
中国日历(公历+农历)算法
中国公历算法
中国公历算法不是太难,关键是星期值的确定。这里给出了简单算法:
public static int dayOfWeek(int y, int m, int d) {
int w = 1; // 公历一年一月一日是星期一,所以起始值为星期日
y = (y-1)%400 + 1; // 公历星期值分部 400 年循环一次
int ly = (y-1)/4; // 闰年次数
ly = ly - (y-1)/100;
ly = ly + (y-1)/400;
int ry = y - 1 - ly; // 常年次数
w = w + ry; // 常年星期值增一
w = w + 2*ly; // 闰年星期值增二
w = w + dayOfYear(y,m,d);
w = (w-1)%7 + 1;
return w;
}
中国农历算法
根公历相比,中国农历的算法相当复杂。我在网上找的算法之中, 的算法是最好的一个。这个算法使用了大量的数据来确定农历月份和节气的分部,它仅实用于公历 1901 年到 2100 年之间的 200 年。
中国农历计算程式
跟据 提供的算法,我写了下面这个程式:
[HTML]
/**
* ChineseCalendarGB.java
* Copyright (c) 1997-2002 by Dr. Herong Yang.
/
* 中国农历算法 - 实用于公历 1901 年至 2100 年之间的 200 年*/
import java.text.*;
import java.util.*;
class ChineseCalendarGB {
Java万年历源代码,可显示公历、农历、系统时间、国际时间
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
public class wannianli extends JFrame implements ActionListener, MouseListener {
private Calendar cld = Calendar.getInstance();//获取一个Calendar类的实例对象
private String[] astr = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
private DefaultTableModel dtm = new DefaultTableModel(null, astr);
private JTable table = new JTable(dtm);
private JScrollPane sp = new JScrollPane(table);
java 中国大陆的身份证检验算法,以及15位和18位身份证的相互转换
import java.util.regex.*;/*** 中国大陆的身份证检验算法,以及15位和18位身份证的相互转换。* @author hutz**/public class IdCardUtil {public IdCardUtil(){}/*** 15位身份证号码转化为18位的身份证。如果是18位的身份证则直接返回,不作任何变化。* @param idCard,15位的有效身份证号码* @return idCard18 返回18位的有效身份证*/public String IdCard15to18(String idCard){idCard = idCard.trim();StringBuffer idCard18 = new StringBuffer(idCard);//加权因子//int[] weight = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//校验码值char[] checkBit = {'1','0','X','9','8','7','6','5','4','3','2'};int sum = 0;//15位的身份证if(idCard != null && idCard.length()==15){idCard18.insert(6, "19");for(int index=0;indexchar c = idCard18.charAt(index);int ai = Integer.parseInt(new Character(c).toString());//sum = sum+ai*weight[index];//加权因子的算法int Wi = ((int)Math.pow(2, idCard18.length()-index))%11;sum = sum+ai*Wi;}int indexOfCheckBit = sum%11; //取模idCard18.append(checkBit[indexOfCheckBit]);}return idCard18.toString();}/*** 转化18位身份证位15位身份证。如果输入的是15位的身份证则不做任何转化,直接返回。* @param idCard 18位身份证号码* @return idCard15*/public String IdCard18to15(String idCard){idCard = idCard.trim();StringBuffer idCard15 = new StringBuffer(idCard);if(idCard!=null && idCard.length()==18){idCard15.delete(17, 18);idCard15.delete(6, 8);}return idCard15.toString();}/*** 校验是否是一个有效的身份证。如果是18的身份证,则校验18位的身份证。15位的身份证不校验,也无法校验* @param idCart* @return*/public boolean checkIDCard(String idCard){boolean isIDCard = false;Pattern pattern = pile("\\d{15}|\\d{17}[x,X,0-9]");Matcher matcher = pattern.matcher(idCard);if(matcher.matches()){//可能是一个身份证isIDCard = true;if(idCard.length()==18){//如果是18的身份证,则校验18位的身份证。15位的身份证暂不校验String IdCard15 = IdCard18to15(idCard);String IdCard18 = IdCard15to18(IdCard15);if(!idCard.equals(IdCard18)){isIDCard = false;}}else if(idCard.length()==15){isIDCard = true;}else{isIDCard = fal
Java国密相关算法(bouncycastle)
Java国密相关算法(bouncycastle)
bouncycastle是一个开源的Java密码学库,提供了对多种加密算法
的支持,包括AES、DES、RSA、DSA等。该库由一个由志愿者组成的团队
开发和维护,其中也包括了Java国密算法的支持。
国家密码局制定了一系列国家密码算法标准,这些算法可用于保护敏
感信息的传输和存储。bouncycastle库通过实现这些标准,提供了对国
密算法的支持。
bouncycastle库提供的国密相关算法包括SM2、SM3和SM4
SM2是一种基于椭圆曲线密码学的非对称加密算法,用于数字签名和
密钥交换。它采用了椭圆曲线上的运算,具有较高的安全性和效率。bouncycastle库提供了SM2加密、解密和签名的功能。
SM3是一种密码哈希算法,用于计算消息的摘要。它采用了类似SHA-256的设计思路,但具有更高的安全性。bouncycastle库提供了SM3算法
的实现,可用于计算消息的摘要。
SM4是一种分组密码算法,用于对称加密和解密。它采用了类似于
AES的分组密码设计,但是算法结构和算法细节存在一些差异。bouncycastle库提供了SM4的加密和解密功能。
除了国密相关算法,bouncycastle库还提供了对PKCS、PKCS等密码
学标准的支持,以及对数字证书的生成和处理的功能。
在使用Java国密相关算法时,可以通过引入bouncycastle库来实现。首先,需要将bouncycastle库添加到项目的classpath中。然后,在代
码中引入相应的包,例如:
java祖冲之算法实现 -回复
java祖冲之算法实现-回复
Java祖冲之算法实现是什么?
祖冲之算法,也称为祖冲之开方算法,是中国古代数学家祖冲之(约公元321年-约公元379年)发现的一种求平方根的算法。这个算法通过近似不断逼近平方根的值,是一种迭代算法。在Java中,我们可以通过编写代码来实现祖冲之算法。
构建Java工程并导入相关类库
首先,我们需要创建一个新的Java工程。在工程中,我们需要导入两个重要的类库:java.math.BigDecimal和java.math.MathContext。这两个类库提供了高精度的数学运算支持,也是我们实现祖冲之算法所必需的。
导入类库的方法很简单。在Java IDE中,我们可以通过右键点击项目,选择“Properties”或“Build Path”,然后选择“Add External JARs”来导入类库。
编写Java代码实现祖冲之算法
在编写代码之前,我们需要理解祖冲之算法的原理。祖冲之算法的基本思想是:对于任意一个非负数x,我们可以通过反复迭代的方法来逼近它的平方根。迭代的公式为:x = (x + n/x) / 2,其中n为待求的数的平方。
接下来,我们可以编写Java代码来实现祖冲之算法。首先,我们需要定义一个函数来计算平方根:
java
public static BigDecimal squareRoot(BigDecimal n, MathContext mc) {
BigDecimal x0 = new BigDecimal("0");
BigDecimal x1 = new BigDecimal(Math.sqrt(n.doubleValue()));
Java国密相关算法(bouncycastle)
Java国密相关算法(bouncycastle)公⽤类算法:
XxxKeyPair.java
/**
* @Author: dzy
* @Date: 2018/9/27 14:18
* @Describe: 公私钥对
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class XxxKeyPair {
private String priKey; //私钥
private String pubKey; //公钥
}
CommonUtils.java
import ng3.StringUtils;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* @ClassName: CommonUtils
* @Description: 通⽤⼯具类
* @since: 0.0.1
* @author: dzy
* @date: 2017年2⽉22⽇上午11:46:44
*/
public class CommonUtils {
/**
* @param date ⽇期
* @param pattern 模式如:yyyyMMdd等
* @return
* @Title: formatDate
java常用的算法函数
java常用的算法函数
Java是一种广泛使用的编程语言,也是许多应用程序的首选语言。在Java中,算法函数是非常重要的,它们可以大大简化代码的编写,并
显著提高程序的效率。以下是一些Java常用的算法函数,它们是编写
优秀Java程序不可或缺的一部分。
1.排序算法
排序算法是计算机科学中的一个重要主题,Java中也有很多算法用于
排序。常用的排序算法包括冒泡排序、选择排序、插入排序、堆排序、快速排序和归并排序。这些算法中,快速排序和归并排序是效率最高
的算法。
2.查找算法
在Java中查找算法包括线性搜索和二分查找。线性搜索适用于小型数
据集,而二分查找适用于大型数据集。Java提供了许多查找函数,例
如contains和indexOf函数,它们可以快速找到数组或列表中的特定项。
3.递归算法
递归算法是将问题分解为多个相似的子问题的一种算法。递归经常用
于树形结构或图形结构的数据。Java中的递归函数可以简化代码的编写,并使代码更易于阅读和理解。
4.动态规划算法
动态规划算法是一种优化的递归算法,它可以用于解决一些复杂的问
题。在Java中,动态规划算法通常用于计算最长公共子序列、最小编辑距离和背包问题等。
5.数学算法
Java中的数学算法可以用于计算各种数学函数,例如三角函数、指数函数和对数函数等。Java的Math类提供了许多数学函数,例如sin函数、cos函数和sqrt函数等。
6.密码学算法
Java中的密码学算法可以用于加密和解密数据。常用的密码学算法包括AES、RSA和MD5等。在Java中,可以使用Java Cryptography Extension(JCE)库来实现密码学算法。
万年历---java算法实现
万年历---java算法实现
万年历是我在网上见到的一份极高高精度的万年历,其采用先进的算法实现,其精度堪比刘安国教授为中国科学院国家授时中心制作的日梭万年历。但网络上只有javascript 版本。于是自己将其翻译为java程序,并公布于此,方便大家使用。
本文中讲的万年历是一款采用现代天文算法制作的农历历算程序,含有公历与回历信息,可以很方便的进行公、农、回三历之间的转换。提供公元-4712年到公元9999年的日期查询功能。其中1500年到1940农历数据已经与陈垣的《二十史朔闰表》核对;含有从公420元(南北朝/宋武帝元年)到今的基本年号。在过去几百年中,寿星万年历的误差是非常小的,节气时刻计算及日月合朔时刻的平均误差小于1秒,太阳坐标的最大可能误差为0.2角秒,月亮坐标的最大可能误差为3角秒,平均误差为误差的1/6。万年历中含有几百个国内城市的经纬度,并且用户可根据自已的需要扩展经纬度数据。
代码如下:
/**
* @author lxslove
* @mail moodlxs at 163
*
*/
public class SolarTerm {
// ========角度变换===============
private static final double rad = 180 * 3600 / Math.PI; // 每弧度的角秒数
private static final double RAD = 180 / Math.PI; // 每弧度的角度数
// ================日历计算===============
Java安全算法(摘要加密国密算法)
Java安全算法(摘要加密国密算法)
⼀、安全算法
1. 算法分类:摘要算法、加密算法和国密算法;
2. 摘要算法:指加密过程不需要秘钥,密⽂⽆法被解密,并且只有输⼊相同的明⽂数据经过相同的消息摘要算法才能得到相同的密⽂,如:MD5和SHA1;
3. 加密算法
A. 分类:对称加密、⾮对称加密及Hash算法;
B. 对称加密:指加密和解密使⽤相同的秘钥,如DES和AES算法;
C. ⾮对称加密:指加密和解密使⽤不同的秘钥,包含公钥和私钥,公钥可以公开,私钥⾃⼰保管,公钥加密私钥解密或私钥加密公钥解密,如RSA和DSA,该技术安全性更好,但性能更慢,主要⽤于登录、数字签名、数字证书认证等场景;
D. Hash算法:指通过算法将值映射到表中⼀个位置来访问记录,以加快查询速度,如MD5和SHA;
4. 国密算法:指国家密码局认定的国产密码算法,如:SM1(对称加密)、SM2(⾮对称加密)、SM3(消息摘要)、SM4等,其中SM1为对称加密,该算法不公开,需要通过加密的芯⽚接⼝进⾏调⽤。
⼆、AES(对称加密算法)
1. 特点
A. 加密速度更快,安全性更好,会替代DES,是⽬前最流⾏的对称加密算法;
B. 使⽤128位的加密块,还有192和256位长度的秘钥;
2. 算法分组
A. ECB模式;
B. CBC模式:是ECB模式的改进版,应⽤最⼴;
3.⽰例
package com.ruhuanxingyun.javabasic.util;
import cn.hutool.core.util.StrUtil;
java节假日算法_基于Java代码实现判断春节、端午节、中秋节等法定节假日的方法...
java节假⽇算法_基于Java代码实现判断春节、端午节、中秋
节等法定节假⽇的⽅法...
⼀、前⾔
最近⼯作上遇到⼀个问题,后端有⼀个定时任务,需要⽤JAVA每天判断法定节假⽇、周末放假,上班等情况,其实想单独通过逻辑什么的去判断中国法定节假⽇的放假情况,基本不可能,因为国家每⼀年的假期可能不⼀样,是⼈为设定的;
所以只能依靠其它⼿段,能想到的⽐较靠谱的如下:
1.⽹络接⼝:有些数据服务商会提供,要么是收钱的,要么是次数限制,等等各种问题,效果不理想,可控性差,我也没试过,如:
或者
2.在线解析⽹页信息,获取节假⽇情况:严重依赖被解析的⽹站⽹页,所以在选取⽹站的时候,要找稍微靠谱点的;
3.根据国家规定的法定节假⽇放假情况,每年录⼊系统,这种如果客户不怕⿇烦的话。还是⽐较靠谱的;
本Demo将选择第⼆种来实现;
⼆、使⽤htmlunit在线解析⽹页信息,获取节假⽇情况
⼀开始是使⽤jsoup去解析⽹页的,效果不理想,如果⽹页是动态⽣成的时候,⽤jsoup遇到了各种问题,所以改成了htmlunit,总得来说htmlunit还是很强⼤的,能够模拟浏览器运⾏,被誉为java浏览器的开源实现;
⾸先去官⽹下载相关jar包,以及阅读相关⽂档:
我这⾥解析的⽹页是360的万年历:
⽇历界⾯如下:
被解析的 HTML格式如下:
实现步骤:
1、加载页⾯;
2、循环等待页⾯加载完成(可能会有⼀些动态页⾯,是⽤javascript⽣成);
3、根据⽹页格式解析html内容,并提取关键信息存⼊封装好的对象;
注意点:
1、难点在于判断是否休假及假期类型,由于原页⾯并没有标明每⼀天的假期类型,所以这⾥的逻辑要⾃⼰去实现,详情参考代码;
java调用算法模型的方式
java调用算法模型的方式
以Java调用算法模型的方式
一、背景介绍
在现今大数据时代,算法模型的应用越来越广泛,其能够帮助我们从海量数据中挖掘有价值的信息。而Java作为一种广泛应用于企业级软件开发的编程语言,也提供了丰富的工具和库,使得我们能够轻松地调用和使用算法模型。本文将介绍如何以Java调用算法模型,以及一些相关的注意事项。
二、选择合适的算法模型
在使用Java调用算法模型之前,首先需要选择合适的算法模型。常见的算法模型包括机器学习模型、深度学习模型、自然语言处理模型等。根据自己的需求和数据特点,选择合适的算法模型是非常重要的。
三、准备模型文件
在调用算法模型之前,需要准备好相应的模型文件。模型文件通常由训练过程生成,包含了算法模型的参数和权重等信息。在Java中,可以将模型文件保存在本地,或者保存在远程服务器上。
四、导入相关依赖
在Java中调用算法模型,通常需要导入相关的依赖库。例如,对于机器学习模型,可以使用Apache的开源库“Mahout”,或者使用
Google的开源库“TensorFlow”。根据选择的算法模型和依赖库,进行相应的依赖导入。
五、加载模型文件
在Java中调用算法模型,首先需要加载模型文件。可以使用Java 提供的文件操作API,读取本地的模型文件;或者使用网络请求库,从远程服务器下载模型文件。将读取或下载的模型文件加载到内存中。
六、数据预处理
在调用算法模型之前,通常需要对输入数据进行预处理。预处理的方式根据具体的算法模型和数据特点而定。例如,对于机器学习模型,可以对输入数据进行特征提取和归一化等操作。
java算法总结
java算法总结
Java算法总结
Java是一种广泛使用的编程语言,它具有高效、可靠、安全等特点,因此在算法领域也得到了广泛的应用。本文将对Java算法进行总结,包括常用的算法类型、算法实现方法以及算法优化技巧等方面。
一、常用的算法类型
1. 排序算法:包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。
2. 查找算法:包括顺序查找、二分查找、哈希查找等。
3. 图论算法:包括最短路径算法、最小生成树算法、拓扑排序算法等。
4. 字符串算法:包括字符串匹配算法、字符串编辑距离算法等。
5. 动态规划算法:包括背包问题、最长公共子序列问题、最长递增子序列问题等。
二、算法实现方法
1. 递归实现:递归是一种常用的算法实现方法,它可以将一个问题分解成多个子问题,然后逐步解决这些子问题,最终得到问题的解。
2. 迭代实现:迭代是一种循环实现方法,它可以通过循环来解决问题,通常比递归更高效。
3. 分治实现:分治是一种将问题分解成多个子问题,然后分别解决这些子问题,最终将子问题的解合并成原问题的解的方法。
4. 贪心实现:贪心是一种通过每一步的最优选择来得到全局最优解的方法。
三、算法优化技巧
1. 时间复杂度优化:通过优化算法的时间复杂度来提高算法的效率,例如使用哈希表来优化查找算法的时间复杂度。
2. 空间复杂度优化:通过优化算法的空间复杂度来减少算法的内存占用,例如使用滚动数组来优化动态规划算法的空间复杂度。
3. 剪枝优化:通过剪枝来减少算法的搜索空间,例如使用剪枝来优化深度优先搜索算法的效率。
4. 并行优化:通过并行计算来提高算法的效率,例如使用多线程来优化排序算法的效率。
java加解密算法--常见加解密算法
java加解密算法--常见加解密算法
什么是加密算法?
百度百科给出的解释如下:
数据加密的基本过程就是对原来为明⽂的⽂件或数据按某种算法进⾏处理,使其成为不可读的⼀段代码,通常称为“密⽂”,使其只能在输⼊相应的密钥之后才能显⽰出本来内容,通过这样的途径来达到保护数据不被⾮法⼈窃取、阅读的⽬的。该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程。
简单来说,就是把某⼀段数据(明⽂),按照“某种规则”转换成另外⼀段不可读的数据(密⽂)。这⾥选定的“规则”,就是加密算法。理所当然,当别⼈拿到“密⽂”,解析出“明⽂”的难度取决于加密算法的破解难度。
1. 算法种类
单向加密
对称加密
⾮对称加密
1.1 单向加密
即加密之后不能解密,⼀般⽤于数据验证
1) Base64
Base64 编码是从⼆进制到字符的过程,⽤ 64 个字符来表⽰任意的⼆进制数据。对于开发⼈员来说,拿到密⽂,很容易就能够解析成明⽂。因此严格来说,Base64不能称之为加密算法,仅仅是⼀种编码⽅式。它常常⽤于发送Http请求时对URL中参数的编码,保证不是⼀眼就看出来了这些参数的意义,或者图⽚编码传输。
转换⽅法:
1 字节(byte) = 8 ⽐特位(bit)
Base64 定义了 64 (2^6)个可打印字符表⽰⼆进制的⽅法,也就是说 6 个 bit 的⼆进制数据可以⽤对应的字符代替表⽰
对于连续多个⼆进制数据,每 3 个字节⼀组进⾏转换,3个字节 24 bit,然后将其分为 4 部分(3×8 = 4×6),每个部分刚好 6 bit,⾼位补0,将 6 bit ⼆进制转换为 Base64 定义的字符即完成转换
java国密的原理
Java国密的基本原理
1. 国密算法简介
国密算法是指由中国密码学专家自主研发的密码算法,主要包括SM1对称加密算法、SM2椭圆曲线公钥密码算法、SM3杂凑算法和SM4分组密码算法。这些算法已经成
为中国密码应用的基石,被广泛应用于电子商务、金融支付、公共安全等领域。
2. Java国密的基本原理
Java国密是指在Java平台上实现的国密算法。Java国密的基本原理涉及到以下几个方面:
2.1 JDK版本选择
Java国密的实现需要选择支持国密算法的JDK版本。目前,Oracle JDK不直接支
持国密算法,因此可以选择使用由中国密码局发布的BC-JDK(Bouncy Castle JDK)或者由阿里巴巴开源的Alibaba JDK。
2.2 密钥管理
Java国密的密钥管理基于Java Cryptography Architecture (JCA)。JCA提供了
密钥管理的API,可以生成、存储和管理密钥。对于国密算法,可以通过JCA生成
国密算法所需的密钥对、密钥对的导入导出、密钥的存储等操作。
2.3 加密和解密
Java国密的加密和解密是基于JCA提供的Cipher类实现的。Cipher类提供了加密和解密的功能,可以通过指定国密算法的名称来创建Cipher对象。对于SM1和
SM4算法,可以使用ECB、CBC、CTR等模式进行加密和解密。
2.4 签名和验签
Java国密的签名和验签是基于JCA提供的Signature类实现的。Signature类提供了数字签名和验签的功能,可以通过指定国密算法的名称来创建Signature对象。对于SM2算法,可以使用ECDSA算法进行签名和验签。
国密算法Java代码的标准实现
国密算法Java代码的标准实现
前⼀阵⼦做的项⽬,越来越多的⾦融类应⽤使⽤国密算法进⾏加解密的运算。
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
SM1 为对称加密。其加密强度与AES相当。该算法不公开,调⽤该算法时,需要通过加密芯⽚的接⼝进⾏调⽤。
SM2为⾮对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥⽣成速度都快于RSA。ECC 256位(SM2采⽤的就是ECC 256位的⼀种)安全强度⽐RSA 2048位⾼,但运算速度快于RSA。
SM3 消息摘要。可以⽤MD5作为对⽐理解。该算法已公开。校验结果为256位。
SM4 ⽆线局域⽹标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
由于SM1、SM4加解密的分组⼤⼩为128bit,故对消息进⾏加解密时,若消息长度过长,需要进⾏分组,要消息长度不⾜,则要进⾏填充。
JAVA代码:Util:
1import javax.crypto.SecretKey;
2import javax.crypto.SecretKeyFactory;
3import javax.crypto.spec.PBEKeySpec;
4import javax.crypto.spec.SecretKeySpec;
5import java.math.BigInteger;
6import java.security.NoSuchAlgorithmException;
7import java.security.SecureRandom;
java算法代码实现
java算法代码实现
一、Java算法概述
Java算法是指在Java编程语言中实现的各种计算机算法。它们可以用于解决各种问题,例如排序、搜索、图形处理和数据分析等。Java算法通常由一组指令组成,这些指令按照特定的顺序执行,以达到预期的结果。
二、Java算法的分类
根据不同的标准,Java算法可以分为不同的类别。以下是常见的分类方式:
1. 基本排序算法:包括冒泡排序、选择排序和插入排序等。
2. 高级排序算法:包括快速排序、归并排序和堆排序等。
3. 搜索算法:包括线性搜索和二分搜索等。
4. 图形处理算法:包括图像滤波和边缘检测等。
5. 数据分析算法:包括聚类分析和分类器等。
三、Java基本排序算法代码实现
以下是三种基本排序算法(冒泡排序、选择排序和插入排序)的Java 代码实现:
1. 冒泡排序
public static void bubbleSort(int[] arr) { int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
2. 选择排序
public static void selectionSort(int[] arr) { int n = arr.length;
for (int i = 0; i < n - 1; i++) {
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
JAVA_算法_中国公历算法&中国农历算法
public static int dayOfWeek(int y, int m, int d) {
int w = 1; // 公历一年一月一日是星期一,所以起始值为星期日
y = (y-1)%400 + 1; // 公历星期值分部 400 年循环[xun huan]一次
int ly = (y-1)/4; // 闰年次数
ly = ly - (y-1)/100;
ly = ly + (y-1)/400;
int ry = y - 1 - ly; // 常年次数
w = w + ry; // 常年星期值增一
w = w + 2*ly; // 闰年星期值增二
w = w + dayOfYear(y,m,d);
w = (w-1)%7 + 1;
return w;
}
中国农历算法[suan fa]
根公历相比,中国农历的算法[suan fa]相当复杂。我在网上找的算法[suan fa]之中, 的算法[suan fa]是最好的一个。这个算法[suan fa]使用了大量的数据[shu ju]来确定农历月份和节气的分部,它仅实用于[yong yu]公历 1901 年到 2100 年之间的 200 年。
中国农历计算程式
跟据 提供的算法[suan fa],我写了下面这个程式:
/**
* ChineseCalendarGB.java
* Copyright (c) 1997-2002 by Dr. Herong Yang
* 中国农历算法[suan fa] - 实用于[yong yu]公历 1901 年至 2100 年之间的 200 年
*/
import java.text.*;
import java.util.*;
class ChineseCalendarGB {
private int gregorianYear;
private int gregorianMonth;
private int gregorianDate;
private boolean isGregorianLeap;
private int dayOfYear;
private int dayOfWeek; // 周日一星期的第一天
private int chineseYear;
private int chineseMonth; // 负数表示闰月
private int chineseDate;
private int sectionalTerm;
private int principleTerm;
private static char[] daysInGregorianMonth =
{31,28,31,30,31,30,31,31,30,31,30,31};
private static String[] stemNames =
{"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
private static String[] branchNames =
{"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
private static String[] animalNames =
{"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};
public static void main(String[] arg) {
ChineseCalendarGB c = new ChineseCalendarGB();
String cmd = "day";
int y = 1901;
int m = 1;
int d = 1;
if (arg.length>0) cmd = arg[0];
if (arg.length>1) y = Integer.parseInt(arg[1]);
if (arg.length>2) m = Integer.parseInt(arg[2]);
if (arg.length>3) d = Integer.parseInt(arg[3]);
c.setGregorian(y,m,d);
puteChineseFields();
puteSolarTerms();
if (cmd.equalsIgnoreCase("year")) {
String[] t = c.getYearTable();
for (int i=0; i } else if (cmd.equalsIgnoreCase("month")) {
String[] t = c.getMonthTable();
for (int i=0; i } else {
System.out.println(c.toString());
}
}
public ChineseCalendarGB() {
setGregorian(1901,1,1);
}
public void setGregorian(int y, int m, int d) {
gregorianYear = y;
gregorianMonth = m;
gregorianDate = d;
isGregorianLeap = isGregorianLeapYear(y);
dayOfYear = dayOfYear(y,m,d);
dayOfWeek = dayOfWeek(y,m,d);
chineseYear = 0;
chineseMonth = 0;
chineseDate = 0;
sectionalTerm = 0;
pr
incipleTerm = 0;
}
public static boolean isGregorianLeapYear(int year) {
boolean isLeap = false;
if (year%4==0) isLeap = true;
if (year%100==0) isLeap = false;
if (year%400==0) isLeap = true;
return isLeap;
}
public static int daysInGregorianMonth(int y, int m) {
int d = daysInGregorianMonth[m-1];
if (m==2 && isGregorianLeapYear(y)) d++; // 公历闰年二月多一天
return d;
}
public static int dayOfYear(int y, int m, int d) {
int c = 0;
for (int i=1; i c = c + daysInGregorianMonth(y,i);
}
c = c + d;
return c;
}
public static int dayOfWeek(int y, int m, int d) {
int w = 1; // 公历一年一月一日是星期一,所以起始值为星期日
y = (y-1)%400 + 1; // 公历星期值分部 400 年循环[xun huan]一次
int ly = (y-1)/4; // 闰年次数
ly = ly - (y-1)/100;
ly = ly + (y-1)/400;
int ry = y - 1 - ly; // 常年次数
w = w + ry; // 常年星期值增一
w = w + 2*ly; // 闰年星期值增二
w = w + dayOfYear(y,m,d);
w = (w-1)%7 + 1;
return w;
}
private static char[] chineseMonths = {
// 农历月份大小压缩[ya suo]表,两个字节表示一年。两个字节共十六个二进制[er jin zhi]位数,
// 前四个位数表示闰月月份,后十二个位数表示十二个农历月份的大小。
0x00,0x04,0xad,0x08,0x5a,0x01,0xd5,0x54,0xb4,0x09,0x64,0x05,0x59,0x45,
0x95,0x0a,0xa6,0x04,0x55,0x24,0xad,0x08,0x5a,0x62,0xda,0x04,0xb4,0x05,
0xb4,0x55,0x52,0x0d,0x94,0x0a,0x4a,0x2a,0x56,0x02,0x6d,0x71,0x6d,0x01,
0xda,0x02,0xd2,0x52,0xa9,0x05,0x49,0x0d,0x2a,0x45,0x2b,0x09,0x56,0x01,
0xb5,0x20,0x6d,0x01,0x59,0x69,0xd4,0x0a,0xa8,0x05,0xa9,0x56,0xa5,0x04,
0x2b,0x09,0x9e,0x38,0xb6,0x08,0xec,0x74,0x6c,0x05,0xd4,0x0a,0xe4,0x6a,
0x52,0x05,0x95,0x0a,0x5a,0x42,0x5b,0x04,0xb6,0x04,0xb4,0x22,0x6a,0x05,
0x52,0x75,0xc9,0x0a,0x52,0x05,0x35,0x55,0x4d,0x0a,0x5a,0x02,0x5d,0x31,
0xb5,0x02,0x6a,0x8a,0x68,0x05,0xa9,0x0a,0x8a,0x6a,0x2a,0x05,0x2d,0x09,
0xaa,0x48,0x5a,0x01,0xb5,0x09,0xb0,0x39,0x64,0x05,0x25,0x75,0x95,0x0a,
0x96,0x04,0x4d,0x54,0xad,0x04,0xda,0x04,0xd4,0x44,0xb4,0x05,0x54,0x85,
0x52,0x0d,0x92,0x0a,0x56,0x6a,0x56,0x02,0x6d,0x02,0x6a,0x41,0xda,0x02,
0xb2,0xa1,0xa9,0x05,0x49,0x0d,0x0a,0x6d,0x2a,0x09,0x56,0x01,0xad,0x50,
0x6d,0x01,0xd9,0x02,0xd1,0x3a,0xa8,0x05,0x29,0x85,0xa5,0x0c,0x2a,0x09,
0x96,0x54,0xb6,0x08,0x6c,0x09,0x64,0x45,0xd4,0x0a,0xa4,0x05,0x51,0x25,
0x95,0x0a,0x2a,0x72,0x5b,0x04,0xb6,0x04,0xac,0x52,0x6a,0x05,0xd2,0x0a,
0xa2,0x4a,0x4a,0x05,0x55,0x94,0x2d,0x0a,0x5a,0x02,0x75,0x61,0xb5,0x02,
0x6a,0x03,0x61,0x45,0xa9,0x0a,0x4a,0x05,0x25,0x25,0x2d,0x09,0x9a,0x68,
0xda,0x08,0xb4,0x09,0xa8,0x59,0x54,0x03,0xa5,0x0a,0x91,0x3a,0x96,0x04,
0xad,0xb0,0xad,0x04,0xda,0x04,0xf4,0x62,0xb4,0x05,0x54,0x0b,0x44,0x5d,
0x52,0x0a,0x95,0x04,0x55,0x22,0x6d,0x02,0x5a,0x71,0xda,0x02,0xaa,0x05,
0xb2,0x55,0x49,0x0b,0x4a,0x0a,0x2d,0x39,0x36,0x01,0x6d,0x80,0x6d,0x01,
0xd9,0x02,0xe9,0x6a,0xa8,0x05,0x29,0x0b,0x9a,0x4c,0xaa,0x08,0xb6,0x08,
0xb4,0x38,0x6c,0x09,0x54,0x75,0xd4,0x0a,0xa4,0x05,0x45,0x55,0x95,0x0a,
0x9a,0x04,0x55,0x44,0xb5,0x04,0x6a,0x82,0x6a,0x05,0xd2,0x0a,0x92,0x6a,
0x4a,0x05,0x55,0x0a,0x2a,0x4a,0x5a,0x02,0xb5,0x02,0xb2,0x31,0x69,0x03,
0x31,0x73,0xa9,0x0a,0x4a,0x05,0x2d,0x55,0x2d,0x09,0x5a,0x01,0xd5,0x48,
0xb4,0x09,0x68,0x89,0x54,0x0b,0xa4,0x0a,0xa5,0x6a,0x95,0x04,0xad,0x08,
0x6a,0x44,0xda,0x04,0x74,0x05,0xb0,0x25,0x54,0x03
};
// 初始日,公历农历对应日期:
// 公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日
private static int baseYear = 1901;
private static int baseMonth = 1;
private static int baseDate = 1;
private static int baseIndex = 0;
private static int baseChineseYear = 4598-1;
private static int baseChineseMonth = 11;
private static int baseChineseDate = 11;
public int computeChineseFields() {
if (gregorianYear<1901 || gregorianYear>2100) return 1;
int startYear = baseYear;
int startMonth = baseMonth;
int startDate = baseDate;
chineseYear = baseChineseYear;
chineseMonth = baseChineseMonth;
chineseDate = baseChineseDate;
// 第二个对应日,用以提高计算效率
// 公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日
if (gregorianYear >= 2000) {
startYear = baseYear + 99;
startMonth = 1;
startDate = 1;
chineseYear = baseChineseYear + 99;
chineseMonth = 11;
chineseDate = 25;
}
int daysDiff = 0;
for (int i=startYear; i daysDiff += 365;
if (isGregorianLeapYear(i)) daysDiff += 1; // leap year
}
for (int i=startMonth; i daysDiff += daysInGregorianMonth(gregorianYear,i);
}
daysDiff += gregorianDate - startDate;
chineseDate += daysDiff;
int lastDate = daysInChineseMonth(chineseYear, chineseMonth);
int nextMonth = nextChineseMonth(chineseYear, chineseMonth);
while (chineseDate>lastDate) {
if (Math.abs(nextMonth) chineseMonth = nextMonth;
chineseDate -= lastDate;
lastDate = daysInChineseMonth(chineseYear, chineseMonth);
nextMonth = nextChineseMonth(chineseYear, chineseMonth);
}
return 0;
}
private static int[] bigLeapMonthYears = {
// 大闰月的闰年年份
6, 14, 19, 25, 33, 36, 38, 41, 44, 52,
55, 79,117,136,147,150,155,158,185,193
};
public static int daysInChineseMonth(int y, int m) {
// 注意:闰月 m < 0
int index = y - baseChineseYear + baseIndex;
int v = 0;
int l = 0;
int d = 30;
if (1<=m && m<=8) {
v = chineseMonths[2*index];
l = m - 1;
if ( ((v>>l)&0x01)==1 ) d = 29;
} else if (9<=m && m<=12) {
v = chineseMonths[2*index+1];
l = m - 9;
if ( ((v>>l)&0x01)==1 ) d = 29;
} else {
v = chineseMonths[2*index+1];
v = (v>>4)&0x0F;
if (v!=Math.abs(m)) {
d = 0;
} else {
d = 29;
for (int i=0; i if (bigLeapMonthYears[i]==index) {
d = 30;
break;
}
}
}
}
return d;
}
public static int nextChineseMonth(int y, int m) {
int n = Math.abs(m) + 1;
if (m>0) {
int index = y - baseChineseYear + baseIndex;
int v = chineseMonths[2*index+1];
v = (v>>4)&0x0F;
if (v==m) n = -m;
}
if (n==13) n = 1;
return n;
}
private static char[][] sectionalTermMap = {
{7,6,6,6,6,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,
4,5,5},
{5,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,4,3,3,3},
{6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},
{5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,4,4,5,5,4,4,4,5,4,4,4,4,5},
{6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},
{6,6,7,7,6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},
{7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7},
{8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},
{8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,7},
{9,9,9,9,8,9,9,9,8,8,9,9,8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,8},
{8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},
{7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7}
};
private static char[][] sectionalTermYear = {
{13,49,85,117,149,185,201,250,250},
{13,45,81,117,149,185,201,250,250},
{13,48,84,112,148,184,200,201,250},
{13,45,76,108,140,172,200,201,250},
{13,44,72,104,132,168,200,201,250},
{5 ,33,68,96 ,124,152,188,200,201},
{29,57,85,120,148,176,200,201,250},
{13,48,76,104,132,168,196,200,201},
{25,60,88,120,148,184,200,201,250},
{16,44,76,108,144,172,200,201,250},
{28,60,92,124,160,192,200,201,250},
{17,53,85,124,156,188,200,201,250}
};
private static char[][] principleTermMap = {
{21,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,20,20,20,20,20,19,
20,20,20,19,19,20},
{20,19,19,20,20,19,19,19,19,19,19,19,19,18,19,19,19,18,18,19,19,18,
18,18,18,18,18,18},
{21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,21,20,20,
20,20,19,20,20,20,20},
{20,21,21,21,20,20,21,21,20,20,20,21,20,20,20,20,19,20,20,20,19,19,
20,20,19,19,19,20,20},
{21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,21,21,20,20,
21,21,20,20,20,21,21},
{22,22,22,22,21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,
21,21,20,20,21,21,21},
{23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,
22,23,22,22,22,22,23},
{23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,
23,23,22,22,22,23,23},
{23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,
23,23,22,22,22,23,23},
{24,24,24,24,23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,
23,23,22,22,23,23,23},
{23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,22,22,22,22,21,22,
22,22,21,21,22,22,22},
{22,22,23,23,22,22,22,23,22,22,22,22,21,22,22,22,21,21,22,22,21,21,
21,22,21,21,21,21,22}
};
private static char[][] principleTermYear = {
{13,45,81,113,149,185,201},
{21,57,93,125,161,193,201},
{21,56,88,120,152,188,200,201},
{21,49,81,116,144,176,200,201},
{17,49,77,112,140,168,200,201},
{28,60,88,116,148,180,200,201},
{25,53,84,112,144,172,200,201},
{29,57,89,120,148,180,200,201},
{17,45,73,108,140,168,200,201},
{28,60,92,124,160,192,200,201},
{16,44,80,112,148,180,200,201},
{17,53,88,120,156,188,200,201}
};
public int computeSolarTerms() {
if (gregorianYear<1901 || gregorianYear>2100) return 1;
sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth);
principleTerm = principleTerm(gregorian
Year, gregorianMonth);
return 0;
}
public static int sectionalTerm(int y, int m) {
if (y<1901 || y>2100) return 0;
int index = 0;
int ry = y-baseYear+1;
while (ry>=sectionalTermYear[m-1][index]) index++;
int term = sectionalTermMap[m-1][4*index+ry%4];
if ((ry == 121)&&(m == 4)) term = 5;
if ((ry == 132)&&(m == 4)) term = 5;
if ((ry == 194)&&(m == 6)) term = 6;
return term;
}
public static int principleTerm(int y, int m) {
if (y<1901 || y>2100) return 0;
int index = 0;
int ry = y-baseYear+1;
while (ry>=principleTermYear[m-1][index]) index++;
int term = principleTermMap[m-1][4*index+ry%4];
if ((ry == 171)&&(m == 3)) term = 21;
if ((ry == 181)&&(m == 5)) term = 21;
return term;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Gregorian Year: "+gregorianYear+"\n");
buf.append("Gregorian Month: "+gregorianMonth+"\n");
buf.append("Gregorian Date: "+gregorianDate+"\n");
buf.append("Is Leap Year: "+isGregorianLeap+"\n");
buf.append("Day of Year: "+dayOfYear+"\n");
buf.append("Day of Week: "+dayOfWeek+"\n");
buf.append("Chinese Year: "+chineseYear+"\n");
buf.append("Heavenly Stem: "+((chineseYear-1)%10)+"\n");
buf.append("Earthly Branch: "+((chineseYear-1)%12)+"\n");
buf.append("Chinese Month: "+chineseMonth+"\n");
buf.append("Chinese Date: "+chineseDate+"\n");
buf.append("Sectional Term: "+sectionalTerm+"\n");
buf.append("Principle Term: "+principleTerm+"\n");
return buf.toString();
}
public String[] getYearTable() {
setGregorian(gregorianYear,1,1);
computeChineseFields();
computeSolarTerms();
String[] table = new String[58]; // 6*9 + 4
table[0] = getTextLine(27, "公历年历:"+gregorianYear);
table[1] = getTextLine(27, "农历年历:"+(chineseYear+1)
+ " ("+stemNames[(chineseYear+1-1)%10]
+ branchNames[(chineseYear+1-1)%12]
+ " - "+animalNames[(chineseYear+1-1)%12]+"年)");
int ln = 2;
String blank = " "
+" " + " ";
String[] mLeft = null;
String[] mRight = null;
for (int i=1; i<=6; i++) {
table[ln] = blank;
ln++;
mLeft = getMonthTable();
mRight = getMonthTable();
for (int j=0; j String line = mLeft[j] + " " + mRight[j];
table[ln] = line;
ln++;
}
}
table[ln] = blank;
ln++;
table[ln] = getTextLine(0,
"##/## - 公历日期/农历日期,(*)#月 - (闰)农历月第一天");
ln++;
return table;
}
public static String getTextLine(int s, String t) {
String str = " "
+" " + " ";
if (t!=null && s str = str.substring(0,s) + t + str.substring(s+t.length());
return str;
}
private static String[] monthNames =
{"一","二","三","四","五","六","七","八","九","十","十一","十二"};
public String[] getMonthTable() {
setGregorian(gregorianYear,gregorianMonth,1);
computeChineseFields();
computeSolarTerms();
String[] table = new String[8];
String title = null;
if (gregorianMonth<11) title = " ";
else title = " ";
title = title + monthNames[gregorianMonth-1] + "月"
+ " ";
String header = " 日 一 二 三 四 五 六 ";
String blank =
" ";
table[0] = title;
table[1] = header;
int wk = 2;
String line = "";
for (int i=1; i line += " " + ' ';
}
int days = daysInGregorianMonth(gregorianYear,gregorianMonth);
for (int i=gregorianDate; i<=days; i++) {
line += getDateString() + ' ';
rollUpOneDay();
if (dayOfWeek==1) {
table[wk] = line;
line = "";
wk++;
}
}
for (int i=dayOfWeek; i<=7; i++) {
line += " " + ' ';
}
table[wk] = line;
for (int i=wk+1; i table[i] = blank;
}
for (int i=0; i table[i] = table[i].substring(0,table[i].length()-1);
}
return table;
}
private static String[] chineseMonthNames =
{"正","二","三","四","五","六","七","八","九","十","冬","腊"};
private static String[] principleTermNames =
{"大寒","雨水","春分","谷雨","夏满","夏至","大暑","处暑","秋分","霜降",
"小雪","冬至"};
private static String[] sectionalTermNames =
{"小寒","立春","惊蛰","清明","立夏","芒种","小暑","立秋","白露","寒露",
"立冬","大雪"};
public String getDateString() {
String str = "* / ";
String gm = String.valueOf(gregorianMonth);
if (gm.length()==1) gm = ' ' + gm;
String cm = String.valueOf(Math.abs(chineseMonth));
if (cm.length()==1) cm = ' ' + cm;
String gd = String.valueOf(gregorianDate);
if (gd.length()==1) gd = ' ' + gd;
String cd = String.valueOf(chineseDate);
if (cd.length()==1) cd = ' ' + cd;
if (gregorianDate==sectionalTerm) {
str = " "+sectionalTermNames[gregorianMonth-1];
} else if (gregorianDate==principleTerm) {
str = " "+principleTermNames[gregorianMonth-1];
} else if (chineseDate==1 && chineseMonth>0) {
str = " "+chineseMonthNames[chineseMonth-1]+"月";
} else if (chineseDate==1 && chineseMonth<0) {
str = "*"+chineseMonthNames[-chineseMonth-1]+"月";
} else {
str = gd+'/'+cd;
}
return str;
}
public int rollUpOneDay() {
dayOfWeek = dayOfWeek%7 + 1;
dayOfYear++;
gregorianDate++;
int days = daysInGregorianMonth(gregorianYear,gregorianMonth);
if (gregorianDate>days) {
gregorianDate = 1;
gregorianMonth++;
if (gregorianMonth>12) {
gregorianMonth = 1;
gregorianYear++;
dayOfYear = 1;
isGregorianLeap = isGregorianLeapYear(gregorianYear);
}
sectionalTerm = sectionalTerm(gregorianYear,gregorianMonth);
principleTerm = principleTerm(gregorianYear,gregorianMonth);
}
chineseDate++;
days = daysInChineseMonth(chineseYear,chineseMonth);
if (chineseDate>days) {
chineseDate = 1;
chineseMonth = nextChineseMonth(chineseYear,chineseMonth);
if (chineseMonth==1) chineseYear++;
}
return 0;
}
}