`
songdawei001
  • 浏览: 51561 次
  • 性别: 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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics