Johnson-Trotter(JT)算法生成排列
/**
* 使用JT算法进行排列组合。
* 注意:请务必保持范型和比较接口范型一致,否则可能产生不可预知的错误
* @author LiuYeFeng<897908343@qq.com>
* @date 2015年4月9日 下午5:31:00
* @CopyRight 2015 TopView Inc
* @version V1.0
* @param <E> 需要排列的元素的范型,请务必保持范型和比较接口范型一致,否则可能产生不可预知的错误
*/
public class JTAlgorithm<E>{ //存放排列元素的数组
protected E[] array;
//元素的方向数组
private Direction[] directions;
//比较器,用于比较元素大小
private Compare<E> compare; public JTAlgorithm(Class<? extends Compare<E>> clazz) {
//获取比较方法的实例
this.compare = (Compare) ReflectUtils.newInstance(clazz);
} public JTAlgorithm(Compare<E> compare) {
//获取比较方法的实例
this.compare = compare;
}
public List<E[]> generate(E[] elements) {
List<E[]> result = new ArrayList<E[]>(); //初始化工作
init(elements); //最大可移动元素的位置
int biggestFlag = findBiggestMobileElement();
//自身也为一种排列
result.add(Arrays.copyOf(array, array.length)); //存在可移动最大元素k
while (biggestFlag != -1) {
//将k和箭头指向的相邻元素互换
biggestFlag = changeBiggestElementAndNeighbor(biggestFlag);
//调转所有大于k的元素的方向
changeDirection(biggestFlag);
//将新排列添加到结果集
result.add(Arrays.copyOf(array, array.length));
//重新查找可移动最大元素
biggestFlag = findBiggestMobileElement();
} return result;
}
private void init(E[] elements) {
//用快排把元素排序
QuickSort<E> qk = new QuickSort<E>(compare);
qk.sort(elements, 0, elements.length - 1); array = elements;
directions = new Direction[array.length]; //初始化方向
for (int i = 0; i < directions.length; i++) {
directions[i] = Direction.LEFT;
}
}
/**
* 把比loc位置大的元素的方向反转
* @param loc
*/
private void changeDirection(int loc) {
for (int i = 0; i < array.length; i++) {
if (compare.greaterThan(array[i], array[loc])) {
directions[i] = (directions[i] == Direction.LEFT) ? Direction.RIGHT : Direction.LEFT;
}
}
}
/**
* 把loc元素和它的邻居互换,并把互换后loc的新位置返回
* @param loc
* @return loc的新位置
*/
private int changeBiggestElementAndNeighbor(int loc) {
int neighbor = -1; if (directions[loc] == Direction.LEFT) {
neighbor = loc - 1;
} else {
neighbor = loc + 1;
} E temp = array[loc];
array[loc] = array[neighbor];
array[neighbor] = temp; Direction dTemp = directions[loc];
directions[loc] = directions[neighbor];
directions[neighbor] = dTemp; return neighbor;
}
/**
* 查找最大可移动元素
* @return 最大可移动元素的位置
*/
private int findBiggestMobileElement() {
int loc = -1;
int biggestLoc = -1; for (int i = 0; i < array.length; i++) {
//判断左右方向
if (directions[i] == Direction.LEFT) {
//如果是头元素,则无法向左比较,跳过
if (i == 0) {
continue;
} if (compare.greaterThan(array[i], array[i - 1])) {
loc = i;
}
} else {
//如果是尾元素,则无法向右比较,跳过
if (i == array.length - 1) {
continue;
} if (compare.greaterThan(array[i], array[i + 1])) {
loc = i;
}
} //如果第一次找到可移动元素,则把最大可移动元素改变,之后把本次找到的可移动元素和最大可移动元素进行比较
if (loc != -1 && biggestLoc == -1) {
biggestLoc = loc;
}else if (biggestLoc != -1 && compare.greaterThan(array[loc], array[biggestLoc])) {
biggestLoc = loc;
}
} return biggestLoc;
}
}
Johnson-Trotter(JT)算法生成排列的更多相关文章
- PHP HMAC_SHA1 算法 生成算法签名
HMAC_SHA1(Hashed Message Authentication Code, Secure Hash Algorithm)是一种安全的基于加密hash函数和共享密钥的消息认证协议. 它可 ...
- ZeroMQ接口函数之 :zmq_z85_decode – 从一个用Z85算法生成的文本中解析出二进制密码
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_z85_decode zmq_z85_decode(3) ØMQ Manual - ØMQ/4.1 ...
- dfs 生成排列和组合
利用深度优先搜索的性质可以方便的生成n的排列和组合,但是生成组合时每个组合里面元素的个数必须事先确定,以前以为生成组合跟排列一样到n时就可以回溯,直到今天做了某题之后才发现那是错的,那样做生成不了所有 ...
- 根据twitter的snowflake算法生成唯一ID
C#版本 /// <summary> /// 根据twitter的snowflake算法生成唯一ID /// snowflake算法 64 位 /// 0---0000000000 000 ...
- 算法生成N芒星
前面两个图像生成算法是:道教的太极八卦图和佛教的卐和卍字图.这一节整个洋气的图像:芒星.但愿我别召唤出什么恐怖的禁忌,尤其今晚还是万圣节之夜.平时看玄幻小说,经常读到有关六芒星,七芒星,九芒星的技法. ...
- 在 iPad 上试验从用算法生成法线贴图-到法线映射光照效果
在 iPad 上试验从用算法生成法线贴图-到法线映射光照效果 目录 概述 一般来说, 法线贴图是用高模的法线图, 低模的纹理图, 来生成较好的渲染效果. 而法线图通常是通过图像处理软件来生成的, 这里 ...
- C# 根据twitter的snowflake算法生成唯一ID
C# 版算法: using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- 蓝桥杯--算法提高 排列数 (简单dfs)
算法提高 排列数 时间限制:1.0s 内存限制:256.0MB 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入 ...
- Prim算法生成迷宫
初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...
随机推荐
- Spring官网阅读(十三)ApplicationContext详解(下)
文章目录 BeanFactory 接口定义 继承关系 接口功能 1.HierarchicalBeanFactory 2.ListableBeanFactory 3.AutowireCapableBea ...
- leetcode485——最大连续1的个数(easy)
一.题目描述 给定一个二进制数组, 计算其中最大连续1的个数. 示例 1: 输入: [1,1,0,1,1,1] 输出: 3 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3. 注意 ...
- 今天主要做的是Remember Me(记住我)功能的实现
功能就是让网站登录过的人只要不注销,下次打开网站之后直接进入,不用重复登录,此功能主要是session与cookie的配合运用,具体实现是这样的,在登录页面判断并完成登录,然后将所需数据写入sessi ...
- uCOS2014.1.7
主要关于任务堆栈: 在计算机中一般设置一个专用的地址寄存器用来存放堆栈的栈顶地址,这个寄存器称为堆栈指针(SP). 任务堆栈有两种,一种是地址向下增长的,PC就是采用这样的堆栈: 另一种是地址向上增长 ...
- 第六次java上机作业
.编写一个简单程序,要求数组长度为5,静态赋值10,,,,,在控制台输出该数组的值. package mm; public class Test { public static void main(S ...
- flink源码阅读
Flink面试--源码篇 1.Flink Job的提交流程? 2.Flink所谓"三层图"结构是哪几个"图"? 3.JobManger在集群中扮演了什么角色? ...
- 安装laravel环境之homestead(for mac)
1.先下载virtualbox + vagrant 2.执行命令 vagrant box add laravel/homestead 3.新建一个空文件夹,在里面下载代码.我是放在当前用户下的新建的W ...
- 类型信息(反射,RTTI)
类型信息 1.java如何在运行时识别对象和类的信息 "传统的"RTTI run-time type identification ,假设我们在编译时已经知道了所有类型,在编译的时 ...
- 【比赛随笔】2020.4.25NOIonline2
之前许多比赛没有统一记录,可能从这次开始会认真打比赛的博客了. p.s.这里的数据是洛谷上的民间数据. T1 涂色游戏 这题据说是cf的原题,不过作为蒟蒻的我,没有打过. 题目链接在这里 题意分析 这 ...
- 笨办法学习python之hashmap
#!/user/bin/env python #-*-coding:utf-8 -*- #Author: qinjiaxi #初始化aMap列表,把列表num_buckets添加到aMap中,num_ ...