`
songdawei001
  • 浏览: 51918 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

数字按规则生成分解算法实现

    博客分类:
  • java
阅读更多

首先先把规则说下
数字ID生成规则
1、正反向开始不能为连4位数为升序/降序(匹配此条件时给此4位的末位相关应位置加1重新计算;如:234589、251234、829876)
2、不能为对称数字(若总位数为奇数,则以中间一位的两边判断对称;匹配此条件时给此数字加1重新计算;如:789987、1235321)
3、任意连续2位相同的数不能在任何地方出现3次(匹配此条件时则给第3次现的位置第2位加1后重新计算;如:28865522、2277155)
4、不能为任何地方1位数连续三个一样数字(匹配此条件时给此三位的末位加1后重新计算;如:299901、666127、973888)
5、正反向开始每2位不能连续出现3次一样(匹配此条件时给第3次出现的2位的末数上加1重新计算;如:121212563、5929292)
6、正反向开始每3/4/5位不能连续出现2次一样 (匹配此条件时给第2次出现的位置的末位加1重新计算;如:12312378、67345345、234523458、5678956789)
7、数值不能在以下范围内(19500101 - 22010102,13000000000-14000000000,15000000000-16000000000)

以下是用JAVA语言实现:

public class GenerateUIDUtil {

	/**
	 * 正反向开始不能为连4位数为升序/降序(匹配此条件时给此4位的末位相关应位置加1重新计算;如:234589、251234、829876)
	 * 
	 * @param nextUID
	 *            长整型数字
	 * @param arr
	 *            长整型nextUID的1位数字组成的位数
	 * @return
	 */
	private static long scendOrDescend(long nextUID, int arr[]) {
		// 标记是否符合条件并同时兼顾着保存上一个两连续数的差因子
		int sub = 0;
		for (int i = 0; i < 3; i++) {
			int subs = arr[i + 1] - arr[i];
			if (Math.abs(subs) != 1) {
				sub = 0;
				break;
			} else {
				if (sub == 0) {
					sub = subs;
				} else {
					if (subs != sub) {
						sub = 0;
						break;
					}
				}
			}
		}
		if (sub != 0) {
			int f = 1;
			for (int i = 0; i < arr.length - 4; i++) {
				f = 10 * f;
			}
			return nextUID(nextUID + f);
		}
		for (int i = arr.length - 1; i > arr.length - 4; i--) {
			int subs = arr[i] - arr[i - 1];
			if (Math.abs(subs) != 1) {
				sub = 0;
				break;
			} else {
				if (sub == 0) {
					sub = subs;
				} else {
					if (subs != sub) {
						sub = 0;
						break;
					}
				}
			}
		}
		if (sub != 0) {
			return nextUID + 1;
		}
		return nextUID;
	}

	/**
	 * 不能为任何地方1位数连续三个一样数字(匹配此条件时给此三位的末位加1后重新计算;如:299901、666127、973888)
	 * 
	 * @param nextUID
	 * @param arr
	 * @return
	 */
	private static long threeSame(long nextUID, int arr[]) {
		int index = 0;
		int count = 1;
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] != arr[i - 1]) {
				count = 1;
			} else {
				count = count + 1;
				if (count >= 3) {
					index = arr.length - i;
					break;
				}
			}
		}
		if (count >= 3) {
			int i = 1;
			for (int k = 1; k < index; k++) {
				i = i * 10;
			}
			return nextUID(nextUID + i);
		}

		return nextUID;
	}

	/**
	 * 不能为对称数字(若总位数为奇数,则以中间一位的两边判断对称;匹配此条件时给此数字加1重新计算;如:789987、1235321)
	 * 
	 * @param nextUID
	 * @param attr
	 * @return
	 */
	public static long symmetrical(long nextUID, int[] arr, int mid, int mod) {
		if (mod == 0) {
			for (int m = mid - 1, k = mid; m >= 0 && k < arr.length; m--, k++) {
				if (arr[m] != arr[k]) {
					return nextUID;
				}
			}
			nextUID = nextUID + 1;
		} else {
			for (int m = mid - 1, k = mid + 1; m >= 0 && k < arr.length; m--, k++) {
				if (arr[m] != arr[k]) {
					return nextUID;
				}
			}
			nextUID = nextUID + 1;
		}
		return nextUID;
	}

	/**
	 * 任意连续2位相同的数不能在任何地方出现3次(匹配此条件时则给第3次现的位置第2位加1后重新计算;如:28865522、2277155)
	 * 
	 * @param nextUID
	 * @param arr
	 * @return
	 */
	public static long twoSame(long nextUID, int[] arr) {
		int index = -1;
		int count = 0;
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] == arr[i - 1]) {
				if ((i - 1) != index) {
					count++;
					index = i;
					if (count >= 3) {
						int p = 1;
						for (int k = 1; k < arr.length - index; k++) {
							p = p * 10;
						}
						return nextUID(nextUID + p);
					}
				}
			}
		}
		return nextUID;
	}

	/**
	 * 
	 * @param nextUID
	 * @param arr
	 * @return
	 */
	public static long twoAndTreeSame(long nextUID, int[] arr) {
		boolean ret = false;
		for (int i = 0; i <= 3; i++) {
			if (arr[i] != arr[i + 2]) {
				ret = true;
				break;
			}
		}
		if (!ret) {
			int p = 1;
			for (int i = 0; i < arr.length - 6; i++) {
				p = p * 10;
			}
			return nextUID(nextUID + p);
		}
		ret = false;
		for (int i = arr.length - 1; i >= arr.length - 3; i--) {
			if (arr[i] != arr[i - 2]) {
				ret = true;
				break;
			}
		}
		if (!ret) {
			return nextUID + 1;
		} else {
			return nextUID;
		}
	}

	/**
	 * 
	 * @param nextUID
	 * @param arr
	 * @return
	 */
	public static long moreAndTwoSame(long nextUID, int[] arr) {
		boolean ret = false;
		for (int i = 0; i <= 2; i++) {
			if (arr[i] != arr[i + 3]) {
				ret = true;
				break;
			}
		}
		if (!ret) {
			int p = 1;
			for (int i = 0; i < arr.length - 6; i++) {
				p = p * 10;
			}
			return nextUID(nextUID + p);
		}
		ret = false;
		for (int i = arr.length - 1; i >= arr.length - 3; i--) {
			if (arr[i] != arr[i - 3]) {
				ret = true;
				break;
			}
		}
		if (!ret) {
			return nextUID(nextUID + 1);
		}
		ret = false;
		if (nextUID > 10000000) {
			for (int i = 0; i <= 3; i++) {
				if (arr[i] != arr[i + 4]) {
					ret = true;
					break;
				}
			}
			if (!ret) {
				int p = 1;
				for (int i = 0; i < arr.length - 8; i++) {
					p = p * 10;
				}
				return nextUID(nextUID + p);
			}
			ret = false;
			for (int i = arr.length - 1; i >= arr.length - 4; i--) {
				if (arr[i] != arr[i - 4]) {
					ret = true;
					break;
				}
			}
			if (!ret) {
				return nextUID(nextUID + 1);
			}
		}
		ret = false;
		if (nextUID > 1000000000) {
			for (int i = 0; i <= 4; i++) {
				if (arr[i] != arr[i + 5]) {
					ret = true;
					break;
				}
			}
			if (!ret) {
				int p = 1;
				for (int i = 0; i < arr.length - 10; i++) {
					p = p * 10;
				}
				return nextUID(nextUID + p);
			}
			ret = false;
			for (int i = arr.length - 1; i >= arr.length - 5; i--) {
				if (arr[i] != arr[i - 5]) {
					ret = true;
					break;
				}
			}
			if (!ret) {
				return nextUID + 1;
			}
		}
		return nextUID;
	}

	public static void main(String args[]) {
		int k = 0;
		StringBuilder sb = new StringBuilder();
		long nextUID = 101000;
		while (nextUID < 100000000) {
			long tempUID = nextUID + 1;
			nextUID = GenerateUIDUtil.nextUID(tempUID);
			if (nextUID != tempUID) {
				sb.append("原值:" + tempUID + ",新值:" + nextUID + "\n");
				k++;
			}
		}
		try {
			IOUtil.string2File(sb.toString(), new java.io.File("d:/code.txt"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// System.out.println(GenerateUIDUtil.nextUID(22010102));

	}

	/**
	 * 数值不能在以下范围内(19500101 -
	 * 22010102,13000000000-14000000000,15000000000-16000000000)
	 * 
	 * @param nextUID
	 * @param arr
	 * @return
	 */
	public static long spacial(long nextUID, int[] arr) {
		if (nextUID >= 13000000000l && nextUID <= 16000000000l) {
			return 17001001010l;
		} else if (nextUID >= 19500101 && nextUID <= 22011231) {
			int month = (int) (nextUID % 10000) / 100;
			int day = (int) (nextUID % 100);
			if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
				return 22011232;
			}
		}
		return nextUID;
	}

	/**
	 * 
	 * 
	 * @param cuttentUID
	 * @return
	 */
	public static long nextUID(long cuttentUID) {
		long nextUID = cuttentUID;
		long tempUID = nextUID;
		int[] arr = null;
		long p = 1000000000000000000l;
		for (int i = 0; i < 19; i++) {
			if (tempUID == 0)
				break;
			int key = (int) (tempUID / p);
			tempUID = tempUID % p;
			p = p / 10;
			if (key != 0) {
				if (arr == null) {
					arr = new int[19 - i];
				}
				arr[arr.length + i - 19] = key;
			}
		}

		// 假如规则
		// 数值不能在以下范围内(19500101 -
		// 22010102,13000000000-14000000000,15000000000-16000000000)
		nextUID = spacial(nextUID, arr);
		// 不能为任何地方1位数连续三个一样数字(匹配此条件时给此三位的末位加1后重新计算;如:299901、666127、973888)
		nextUID = threeSame(nextUID, arr);
		int mid = arr.length / 2;
		int mod = arr.length % 2;
		// 不能为对称数字(若总位数为奇数,则以中间一位的两边判断对称;匹配此条件时给此数字加1重新计算;如:789987、1235321)
		nextUID = symmetrical(nextUID, arr, mid, mod);
		// 正反向开始不能为连4位数为升序/降序(匹配此条件时给此4位的末位相关应位置加1重新计算;如:234589、251234、829876)
		nextUID = scendOrDescend(nextUID, arr);
		// 任意连续2位相同的数不能在任何地方出现3次(匹配此条件时则给第3次现的位置第2位加1后重新计算;如:28865522、2277155)
		nextUID = twoSame(nextUID, arr);
		// 正反向开始每2位不能连续出现3次一样(匹配此条件时给第3次出现的2位的末数上加1重新计算;如:121212563、5929292)
		nextUID = twoAndTreeSame(nextUID, arr);
		// 6、正反向开始每3/4/5位不能连续出现2次一样(匹配此条件时给第2次出现的位置的末位加1重新计算;如:12312378、67345345、234523458、5678956789)
		nextUID = moreAndTwoSame(nextUID, arr);
		return nextUID;
	}
}
 

 

1
1
分享到:
评论

相关推荐

    二维联合正态分布伪随机数生成算法的研究与实现

    伪随机数是一类遵循特定数学规则产生的数字序列,它们看似随机,但实际上是由确定性的算法产生的。常见的伪随机数生成方法包括但不限于: - **线性同余法**:这是一种基于线性方程式的伪随机数生成方法,具有简单易...

    DWT域数字图像水印算法实现PPT学习教案.pptx

    **DWT域数字图像水印算法实现** 在数字媒体领域,图像水印技术是一种重要的版权保护手段,它通过在原始图像中嵌入不可见或难以察觉的信息(即水印),来标识图像的所有权或者验证其真实性。离散小波变换(Discrete ...

    在 Rust 中实现的所有算法_rust_代码_下载

    排序算法 气泡 桶 鸡尾酒调酒器 数数 循环 交换 堆 插入 侏儒 合并 奇偶 饼子 快的 基数 选择 壳 傀儡 梳子 桶 蒂姆索特 图表 迪杰斯特拉 Kruskal 的最小生成树 Prim 的最小生成树 广度优先...

    FP-GROWTH算法的实现

    这个算法的核心思想是避免生成庞大的候选频繁项集,而是通过一种高效的前缀路径分解方法来降低计算复杂性。 首先,我们要理解FP-GROWTH的基本步骤: 1. **数据预处理**:将原始数据转换为事务数据库,其中每个事务...

    几种加密解密算法实现

    RSA算法基于大数因子分解的困难性,使用一对公钥和私钥。公钥用于加密,私钥用于解密。该算法广泛应用于数字签名、密钥交换等领域。 4. **SVM(Support Vector Machine)** - SVM是一种监督学习算法,主要用于分类...

    MATLAB算法实战应用案例精讲-爬行动物搜索算法-MATLAB实现源代码RSA

    《MATLAB算法实战应用案例精讲-爬行动物搜索算法-MATLAB实现源代码RSA》是一本专注于利用MATLAB进行算法实现与应用的教程,特别关注了爬行动物搜索算法和RSA加密算法。MATLAB是一种强大的数值计算和编程环境,广泛...

    狄洛尼三角网生成算法研究

    在算法实现上,通常分为静态和动态两种方式。静态算法如辐射扫描法、分解法和扩展法,在构建初期确定所有三角形,不会因新增点而改变已有结构。动态算法则会在增加新点时调整已有三角网,以保持狄洛尼特性,例如增量...

    FPGA实现的DES算法

    在FPGA上实现DES,首先需要将算法分解为多个并行执行的子任务,利用FPGA的并行性来提高加密速度。这通常包括以下几个步骤: 1. **预处理**:对输入数据进行初始置换,将64位明文按特定规则重新排列。 2. **轮密钥...

    经典算法(C语言)包含51个经典算法的C语言实现

    在IT领域,算法是解决问题的关键,而C语言作为底层编程的基石,被广泛用于实现各种高效算法。以下是一些从给定的标题和描述中提取的C语言实现的经典算法: 1. **汉诺塔(Hanoi Tower)**:这是一个递归算法问题,目标...

    算法导论部分实现代码Java版

    在算法实现中,数组经常用于动态规划、排序等场景。 - **链表**:链表提供了一种灵活的方式来存储元素,每个元素(节点)包含数据和指向下一个元素的引用。链表分为单向链表、双向链表和循环链表,适用于解决不同...

    基于Matlab的小波域图像融合算法实现(1).pdf

    通过调用wavelet函数进行小波分解,使用融合规则生成新的小波系数,然后使用waverec函数进行逆小波变换,最终得到融合图像。在实现过程中,需要注意的是,合理的参数设置和优化的融合算法是影响融合效果的关键。 5....

    数独游戏的问题生成及求解算法优化1

    数独是一种广受欢迎的逻辑推理游戏,其基本规则是在一个9x9的网格中,将数字1到9填充到每个小宫格内,使得每一行、每一列以及9个3x3的小九宫格内,每个数字都恰好出现一次。这个游戏涉及到的问题包括问题的生成和...

    基于EZW的嵌入式图像编码算法的研究

    - 构建零树:按照EZW算法的规则查找和标记零树。 - 熵编码:编码非零系数及其位置信息。 - 生成二进制输出:将编码后的数据写入文件。 - 解码过程:读取二进制文件,解码并重构图像。 - 结果比较:使用MATLAB分析...

    游戏算法.pdf

    为了实现这一目标,需要采用有效的算法来确保每个单元格的数字填充正确且满足游戏规则。常用的算法包括回溯法、递归算法等。 ### 关键知识点二:数独的编程实现 #### 回溯算法 - **定义**:回溯算法是一种通过试探...

    实现罗马与阿拉伯数字互转(上机笔试题)

    在编程领域,尤其是在进行算法设计和面试准备时,经常会遇到一些经典的题目,比如将罗马数字转化为阿拉伯数字,反之亦然。本题目的目标是利用C++语言在控制台上实现4000以内罗马数字和阿拉伯数字之间的转换。下面将...

    一种视频缩放插值算法的FPGA实现.pdf

    在文献中的算法实现部分,详细描述了双三次插值算法在FPGA上的硬件实现,包括如何将插值运算分解为水平和垂直方向的处理步骤,并通过FPGA验证了算法的有效性,满足了视频图像缩放的要求。 此外,文档中还提到了文章...

    基于DCT-SVD和标记矩阵的鲁棒可逆数字水印算法.docx

    本文提出了一种结合离散余弦变换(Discrete Cosine Transform, DCT)和奇异值分解(Singular Value Decomposition, SVD)的新型数字水印算法。该算法旨在克服传统数字水印技术中存在的不可感知性与鲁棒性之间的矛盾...

    在FPGA使用Karatsuba算法实现双精度浮点乘法

    最后,根据舍入规则(如最近舍入)处理尾数,再组合符号位、阶码和尾数生成最终的64位双精度浮点乘法结果。 FPGA的并行处理能力使其成为实现这种复杂运算的理想平台。通过巧妙地布线和逻辑门的配置,可以构建出执行...

    经典算法大全PDF

    数字拆解是指将数字分解成几个数的和,而组合生成则是指生成所有可能的组合,这些方法在解决组合优化问题时非常有用。 #### 求最大公因数、最小公倍数和因式分解 这些算法用于基本的数学运算,它们是计算机科学和...

Global site tag (gtag.js) - Google Analytics