《漫画算法》源码整理-7
Posted GarfieldEr007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《漫画算法》源码整理-7相关的知识,希望对你有一定的参考价值。
MyBitmap
public class MyBitmap
//每一个word是一个long类型元素,对应64位二进制
private long[] words;
//bitmap的位数大小
private int size;
public MyBitmap(int size)
this.size = size;
this.words = new long[(getWordIndex(size-1) + 1)];
/**
* 判断bitmap某一位的状态
* @param bitIndex 位图的第bitIndex位
*/
public boolean getBit(int bitIndex)
if(bitIndex<0 || bitIndex>size-1)
throw new IndexOutOfBoundsException("超过bitmap有效范围");
int wordIndex = getWordIndex(bitIndex);
return (words[wordIndex] & (1L << bitIndex)) != 0;
/**
* 把bitmap某一位设为真
* @param bitIndex 位图的第bitIndex位
*/
public void setBit(int bitIndex)
if(bitIndex<0 || bitIndex>size-1)
throw new IndexOutOfBoundsException("超过bitmap有效范围");
int wordIndex = getWordIndex(bitIndex);
words[wordIndex] |= (1L << bitIndex);
/**
* 定位bitmap某一位所对应的word
* @param bitIndex 位图的第bitIndex位
*/
private int getWordIndex(int bitIndex)
//右移6位,相当于除以64
return bitIndex >> 6;
public static void main(String[] args)
MyBitmap bitMap = new MyBitmap(128);
bitMap.setBit(126);
bitMap.setBit(75);
System.out.println(bitMap.getBit(126));
System.out.println(bitMap.getBit(78));
LRUCache算法
import java.util.HashMap;
public class LRUCache
private Node head;
private Node end;
//缓存存储上限
private int limit;
private HashMap<String, Node> hashMap;
public LRUCache(int limit)
this.limit = limit;
hashMap = new HashMap<String, Node>();
public String get(String key)
Node node = hashMap.get(key);
if (node == null)
return null;
refreshNode(node);
return node.value;
public void put(String key, String value)
Node node = hashMap.get(key);
if (node == null)
//如果key不存在,插入key-value
if (hashMap.size() >= limit)
String oldKey = removeNode(head);
hashMap.remove(oldKey);
node = new Node(key, value);
addNode(node);
hashMap.put(key, node);
else
//如果key存在,刷新key-value
node.value = value;
refreshNode(node);
public void remove(String key)
Node node = hashMap.get(key);
if(node == null)
return;
removeNode(node);
hashMap.remove(key);
/**
* 刷新被访问的节点位置
* @param node 被访问的节点
*/
private void refreshNode(Node node)
//如果访问的是尾节点,无需移动节点
if (node == end)
return;
//移除节点
removeNode(node);
//重新插入节点
addNode(node);
/**
* 删除节点
* @param node 要删除的节点
*/
private String removeNode(Node node)
if(node == head && node == end)
//移除唯一的节点
head = null;
end = null;
else if(node == end)
//移除尾节点
end = end.pre;
end.next = null;
else if(node == head)
//移除头节点
head = head.next;
head.pre = null;
else
//移除中间节点
node.pre.next = node.next;
node.next.pre = node.pre;
return node.key;
/**
* 尾部插入节点
* @param node 要插入的节点
*/
private void addNode(Node node)
if(end != null)
end.next = node;
node.pre = end;
node.next = null;
end = node;
if(head == null)
head = node;
class Node
Node(String key, String value)
this.key = key;
this.value = value;
public Node pre;
public Node next;
public String key;
public String value;
public static void main(String[] args)
LRUCache lruCache = new LRUCache(5);
lruCache.put("001", "用户1信息");
lruCache.put("002", "用户2信息");
lruCache.put("003", "用户3信息");
lruCache.put("004", "用户4信息");
lruCache.put("005", "用户5信息");
lruCache.get("002");
lruCache.put("004", "用户4信息更新");
lruCache.put("006", "用户6信息");
System.out.println(lruCache.get("001"));
System.out.println(lruCache.get("006"));
A*搜索算法
import java.util.ArrayList;
import java.util.List;
public class AStar
//迷宫地图
public static final int[][] MAZE =
0, 0, 0, 0, 0, 0, 0 ,
0, 0, 0, 1, 0, 0, 0 ,
0, 0, 0, 1, 0, 0, 0 ,
0, 0, 0, 1, 0, 0, 0 ,
0, 0, 0, 0, 0, 0, 0
;
/**
* A星寻路主逻辑
* @param start 迷宫起点
* @param end 迷宫终点
*/
public static Grid aStarSearch(Grid start, Grid end)
ArrayList<Grid> openList = new ArrayList<Grid>();
ArrayList<Grid> closeList = new ArrayList<Grid>();
//把起点加入 openList
openList.add(start);
//主循环,每一轮检查一个当前方格节点
while (openList.size() > 0)
// 在openList中查找 F值最小的节点作为当前方格节点
Grid currentGrid = findMinGird(openList);
// 当前方格节点从openList中移除
openList.remove(currentGrid);
// 当前方格节点进入 closeList
closeList.add(currentGrid);
// 找到所有邻近节点
List<Grid> neighbors = findNeighbors(currentGrid, openList, closeList);
for (Grid grid : neighbors)
//邻近节点不在openList中,标记父亲、G、H、F,并放入openList
grid.initGrid(currentGrid, end);
openList.add(grid);
//如果终点在openList中,直接返回终点格子
for (Grid grid : openList)
if ((grid.x == end.x) && (grid.y == end.y))
return grid;
//openList用尽,仍然找不到终点,说明终点不可到达,返回空
return null;
private static Grid findMinGird(ArrayList<Grid> openList)
Grid tempGrid = openList.get(0);
for (Grid grid : openList)
if (grid.f < tempGrid.f)
tempGrid = grid;
return tempGrid;
private static ArrayList<Grid> findNeighbors(Grid grid, List<Grid> openList, List<Grid> closeList)
ArrayList<Grid> gridList = new ArrayList<Grid>();
if (isValidGrid(grid.x, grid.y-1, openList, closeList))
gridList.add(new Grid(grid.x, grid.y - 1));
if (isValidGrid(grid.x, grid.y+1, openList, closeList))
gridList.add(new Grid(grid.x, grid.y + 1));
if (isValidGrid(grid.x-1, grid.y, openList, closeList))
gridList.add(new Grid(grid.x - 1, grid.y));
if (isValidGrid(grid.x+1, grid.y, openList, closeList))
gridList.add(new Grid(grid.x + 1, grid.y));
return gridList;
private static boolean isValidGrid(int x, int y, List<Grid> openList, List<Grid> closeList)
//是否超过边界
if (x < 0 || x >= MAZE.length || y < 0 || y >= MAZE[0].length)
return false;
//是否有障碍物
if(MAZE[x][y] == 1)
return false;
//是否已经在openList中
if(containGrid(openList, x, y))
return false;
//是否已经在closeList中
if(containGrid(closeList, x, y))
return false;
return true;
private static boolean containGrid(List<Grid> grids, int x, int y)
for (Grid grid : grids)
if ((grid.x == x) && (grid.y == y))
return true;
return false;
static class Grid
public int x;
public int y;
public int f;
public int g;
public int h;
public Grid parent;
public Grid(int x, int y)
this.x = x;
this.y = y;
public void initGrid(Grid parent, Grid end)
this.parent = parent;
this.g = parent.g + 1;
this.h = Math.abs(this.x - end.x) + Math.abs(this.y - end.y);
this.f = this.g + this.h;
public static void main(String[] args)
//设置起点和终点
Grid startGrid = new Grid(2, 1);
Grid endGrid = new Grid(2, 5);
//搜索迷宫终点
Grid resultGrid = aStarSearch(startGrid, endGrid);
//回溯迷宫路径
ArrayList<Grid> path = new ArrayList<Grid>();
while (resultGrid != null)
path.add(new Grid(resultGrid.x, resultGrid.y));
resultGrid = resultGrid.parent;
//输出迷宫和路径,路径用星号表示
for (int i = 0; i < MAZE.length; i++)
for (int j = 0; j < MAZE[0].length; j++)
if (containGrid(path, i, j))
System.out.print("*, ");
else
System.out.print(MAZE[i][j] + ", ");
System.out.println();
发红包算法
import java.math.BigDecimal;
import java.util.*;
public class Redpackage
/**
* 拆分红包
* @param totalAmount 总金额(以分为单位)
* @param totalPeopleNum 总人数
*/
public static List<Integer> divideRedPackage(Integer totalAmount, Integer totalPeopleNum)
List<Integer> amountList = new ArrayList<Integer>();
Integer restAmount = totalAmount;
Integer restPeopleNum = totalPeopleNum;
Random random = new Random();
for(int i=0; i<totalPeopleNum-1; i++)
//随机范围:[1,剩余人均金额的两倍),左闭右开
int amount = random.nextInt(restAmount / restPeopleNum * 2 - 1) + 1;
restAmount -= amount;
restPeopleNum --;
amountList.add(amount);
amountList.add(restAmount);
return amountList;
/**
* 拆分红包V2
* @param totalAmount 总金额(以分为单位)
* @param totalPeopleNum 总人数
*/
public static List<Integer> divideRedPackageV2(Integer totalAmount, Integer totalPeopleNum)
List<Integer> amountList = new ArrayList<Integer>();
Set<Integer> segments = new HashSet<Integer>();
Random random = new Random();
for(int i = 0; i< totalPeopleNum-1; i++)
int segment = random.nextInt(totalAmount-2) + 1;
int delta = random.nextInt(1)==0 ? 1 : -1;
while(segments.contains(segment) || segment == 0)
segment = (segment+delta)%totalAmount;
segments.add(segment);
List<Integer> segmentList = new ArrayList<Integer>(segments);
Collections.sort(segmentList);
for(int i=0; i<segmentList.size(); i++)
Integer amount;
if(i==0)
amount = segmentList.get(0);
else
amount = segmentList.get(i) - segmentList.get(i-1) ;
amountList.add(amount);
amountList.add(totalAmount - segmentList.get(segmentList.size()-1));
return amountList;
public static void main(String[] args)
List<Integer> amountList = divideRedPackage(1000, 10);
for(Integer amount : amountList)
System.out.println("抢到金额:" + new BigDecimal(amount).divide(new BigDecimal(100)));
以上是关于《漫画算法》源码整理-7的主要内容,如果未能解决你的问题,请参考以下文章