猜姓氏一般的都是127个姓之内,以下代码中一共包括400多个姓氏,这个猜姓氏的算法就是将每个姓氏对应一个独一无二的2进制编码。然后按2进制数不同bit位置上是1的进行分组,这样每组开头的数分别是1,2,4,8,16,32,64,128和256,将姓氏出现的那个组的第1个数字加在一起,得到的编号就是对应的姓。
import com.google.common.collect.Lists;import java.util.List;public class LastNameGuessing { private static String[] LAST_NAMES = ("王,李,张,刘,陈,杨,黄,吴,赵,周,徐,孙,马,朱,胡,林,郭,何,高,罗,郑,梁," + "谢,宋,唐,许,邓,冯,韩,曹,曾,彭,萧,蔡,潘,田,董,袁,于,余,叶,蒋,杜,苏,魏,程,吕,丁,沈,任,姚,卢,傅,钟,姜," + "崔,谭,廖,范,汪,陆,金,石,戴,贾,韦,夏,邱,方,侯,邹,熊,孟,秦,白,江,阎,薛,尹,段,雷,黎,史,龙,陶,贺,顾,毛," + "郝,龚,邵,万,钱,严,赖,覃,洪,武,莫,孔,汤,向,常,温,康,施,文,牛,樊,葛,邢,安,齐,易,乔,伍,庞,颜,倪,庄,聂," + "章,鲁,岳,翟,殷,詹,申,欧,耿,关,兰,焦,俞,左,柳,甘,祝,包,宁,尚,符,舒,阮,柯,纪,梅,童,凌,毕,单,季,裴,霍," + "涂,成,苗,谷,盛,曲,翁,冉,骆,蓝,路,游,辛,靳,欧阳,管,柴,蒙,鲍,华,喻,祁,蒲,房,滕,屈,饶,解,牟,艾,尤,阳," + "时,穆,农,司,卓,古,吉,缪,简,车,项,连,芦,麦,褚,娄,窦,戚,岑,景,党,宫,费,卜,冷,晏,席,卫,米,柏,宗,瞿,桂," + "全,佟,应,臧,闵,苟,邬,边,卞,姬,师,和,仇,栾,隋,商,刁,沙,荣,巫,寇,桑,郎,甄,丛,仲,虞,敖,巩,明,佘,池,查," + "麻,苑,迟,邝,官,封,谈,匡,鞠,惠,荆,乐,冀,郁,胥,南,班,储,原,栗,燕,楚,鄢,劳,谌,奚,皮,粟,冼,蔺,楼,盘,满," + "闻,位,厉,仝,区,郜,海,阚,花,权,强,帅,屠,豆,朴,盖,练,廉,禹,井,祖,漆,巴,丰,支,卿,国,狄,平,计,索,宣,晋," + "相,初,门,雲,容,敬,来,扈,晁,芮,都,普,阙,浦,戈,伏,鹿,薄,邸,雍,辜,羊,阿,乌,母,裘,亓,修,邰,赫,杭,况,那," + "宿,鲜,印,逯,隆,茹,诸,战,慕,危,玉,银,亢,嵇,公,哈,湛,宾,戎,勾,茅,利,於,呼,居,揭,干,但,尉,冶,斯,元,束," + "檀,衣,信,展,阴,昝,智,幸,奉,植,衡,富,尧,闭,由,伊,万俟,司马,上官,夏侯,诸葛,东方,赫连,皇甫,尉迟,公羊," + "澹台,公冶,宗政,濮阳,淳于,单于,太叔,申屠,公孙,仲孙,轩辕,令狐,钟离,宇文,长孙,慕容,鲜于,闾丘,司徒,司空," + "亓官,司寇,子车,颛孙,端木,巫马,公西,漆雕,乐正,壤驷,公良,拓跋,夹谷,宰父,谷梁,段干,百里,东郭,南门,呼延," + "羊舌,微生,梁丘,左丘,东门,西门,南宫").split(","); private static int MAX = LAST_NAMES.length; // 255 or 127,一般的就算127个姓 private static final List<List<LastName>> GROUPS = init(); private static int log(int x, int base) { return (int) Math.ceil(Math.log(x) / Math.log(base)); } private static List<List<LastName>> init() { int size = log(MAX + 1, 2); List<LastName> data = getData(); List<LastName> list = data.subList(0, MAX); List<List<LastName>> groups = Lists.newArrayList(); for (int i = 0; i < size; i++) { List<LastName> group = Lists.newArrayList(); groups.add(group); for (LastName t : list) { int id = t.getId(); int b = (id >> i) & 0x1; // 高位取0 if (b == 1) { group.add(t); String lastName = t.getLastName(); System.out.printf("%3d\t%s\t", id, lastName); } } System.out.println("\n"); } return groups; } private static List<LastName> getData() { int length = LAST_NAMES.length; List<LastName> lastNames = Lists.newArrayList(); for (int i = 0; i < length; i++) { String s = LAST_NAMES[i]; LastName lastName = new LastName(); lastName.setId(i + 1); lastName.setLastName(s); lastNames.add(lastName); } return lastNames; } public static void query(String q) { int size = log(MAX + 1, 2); String result = ""; for (int i = 0; i < size; i++) { List<LastName> group = GROUPS.get(i); boolean found = false; for (LastName g : group) { String lastName = g.getLastName(); if (lastName.equals(q)) { found = true; break; } } if (found) { result = "1" + result; } else { result = "0" + result; } } System.out.printf("%-10s->%4d:%s%n", result, Integer.parseInt(result, 2), q); // 10000110 -> 134 } public static void main(String[] args) { }}class LastName { private int id; private String lastName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; }} |