Shinn
唯天下之至诚能胜天下之至伪;唯天下之至拙能胜天下之至巧.
posts - 19,comments - 125,trackbacks - 3
此算法我在网上有搜索,暂时感觉我自己的算法最符合要求 :)

最近一个案子涉及到条码打印.要求是唯一的序列.中间有一个日期,最后3位为流水号.但打印的张数会超过999;
因此必须用到26个大写字母,现在要求如下.999以前就是普通数字(001~999),再多就开始在百位使用字母即999的后一个数字为A00此时十位和个位还不能使用字母(平时打印会少于3600张,为了客户看起来方便),
只有在百位将Z用完后才允许在十位使用字母,十位用完才允许个位使用字母


用36进制的话3位可以表示36*36*36=46656个数字

注意事项:
1)不能重复
2)数字个数应达到46656个
3)效率不能太低
4)请在本地测试没有重复序列号

因为家里的电脑没有安装Visual Studio,所以格式就.
private readonly char[] Char26{}=new char{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z};
private readonly char[] Char36{}=new char{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z};

public string ConvertNum(int num)
{
if(num<0 || num>=46655)
{
 
throw new Exception("输入的数字超出范围");
}

else if(num>=12959)
{
string value="";
 num
-=12959;
char d=Char26[(int)(num/1296)];
num
=num%1296;
char t=Char36[num%36];
char h=Char36[(int)(num/36)];
return value+h+t+d;
}

else if(num>3599)
{
 
string value="";
 num
-=3599;
 
char t=Char26[(int)(num/360)];
 num
=num%1296;
 
char h=Char36[num%36];
 
int d=num%10;
 
return value+h+t+d;
}

else if(num>=10)
{
 
string value="";
 num
-=3599;
 
char h=Char36[(int)(num/100)];
 num
=num%100;
 
int t=(int)(num/10);
 
int d=num%10;
 
return value+h+t+d;
}

else
{
 
return "00"+num;

}

 


}






由于在家没有代码,先给出测试的伪代码
//定义一个新list<string> nums
//i从0到46655循环
//输入i获取序列号num
//nums中是否包含num
//不包含就将num添加到nums
//包含就输出该重复序列
//循环完毕
//检查nums中的num个数是否为46656


有网友提到什么时候出现3字母.
我是在在Z99的后一个数字即为0A0,
而在0A9之后的一个数字为1A0
ZA9的后一个数字为0B0

ZZ9的后一个数字为00A

00Z的后一个数字为01A(请思考为什么)

我编写的算法已经用到案子中去了,且经过测试可以获得所有46656个数字.(代码在下周五放出,呵呵)
期间为了加快运算速度,我使用了表驱动法,取得了较好的计算效率.
另外计划写个关于表驱动法的小文




posted on 2008-04-22 22:37 Shinn 阅读(5841) 评论(24)  编辑 收藏 网摘

FeedBack:
2008-04-11 09:31 | 狼Robot      
那要是超过了46655怎么办啊?
  回复  引用  查看    
2008-04-11 10:15 | kirc      
不对吧?应该达不到 46656 啊
因为不会出现9ab这个数吧?

  回复  引用  查看    
2008-04-11 10:19 | kirc      
z99之后是1a0?0a0?还是aa0?
  回复  引用  查看    
2008-04-11 11:43 | SZW      
不错的想法,只是对于楼主最上面的“案子”,我想使用二维条码可以很轻松的解决这个问题
  回复  引用  查看    
2008-04-11 15:22 | 装配脑袋      
@kirc
当然是za0啦^_^

  回复  引用  查看    
#6楼[楼主]
2008-04-11 22:11 | Shinn      
@狼Robot
目前客户的日打印量只有5K~10K冗余还是比较大的

  回复  引用  查看    
#7楼[楼主]
2008-04-11 22:12 | Shinn      
@kirc
全字母是肯定要出现的,

  回复  引用  查看    
#8楼[楼主]
2008-04-11 22:15 | Shinn      
@SZW

条码的位数一般是不允许改变的,更不要说是改成二维码了

目前客户的编码规则是由客户的客户规定的,更加不能随便改了

  回复  引用  查看    
2008-04-12 16:47 | heys[未注册用户]
@Shinn(楼主)

同意@kirc的看法。
按你的要求不可能出现第一位是数字后面两位有字母的36进制数。。。。
'10a'这个数什么时候出现?

  回复  引用    
2008-04-12 20:11 | SZW      
@Shinn
这样的话就没办法了,不过你使用了这个“36进制”是不是也要和客户通气的呢?还是这样的条码可以被普通的扫码枪(软件)识别?

  回复  引用  查看    
#11楼[楼主]
2008-04-12 20:18 | Shinn      
当然是询问过客户是否可以使用36进制的.
而且这样的条码也能被普通的条码扫描枪读取,说简单点条码枪就相当于一个键盘,只不过是自动输入而已.是不需要装驱动和其他软件的.


  回复  引用  查看    
2008-04-12 20:26 | SZW      
@Shinn
呵呵这个我知道,这是我大学专业内的东西,谢谢楼主回答,之前我自己还没试过超过10进制的一维条码,所以还不知道识别情况怎么样,有机会继续交流这方面的东西:)

  回复  引用  查看    
2008-04-12 20:43 | SZW      
对了,关于kirc 的说法我也认同,因为一定要等到上一级是字母之后,下级才能使用字母的话,应该是
10*10*10 = 1000
+ 26*10*10 = 2600
+ 26*26*10 = 6760
+ 26*26*26 = 17576
------------------------
27936

粗略想了一下,不周之处请指正!

  回复  引用  查看    
2008-04-12 21:42 | 随风逝去(叶进)      
思路还是不错的,可是为什么使用字母要从百位开始,而不是从个位开始呢??
  回复  引用  查看    
2008-04-12 23:00 | 簡簡單單..      
-_-!!!
  回复  引用  查看    
2008-04-13 09:11 | 沙加      
我也曾经写过一个, 可使用的字符数比你这个多,我是区分大小写的~~算法虽然是笨了点~~其实应该使用取余来计算的~~
随便看看吧 http://www.cnblogs.com/darkangle/archive/2008/02/15/1069743.html" target="_new">http://www.cnblogs.com/darkangle/archive/2008/02/15/1069743.html

  回复  引用  查看    
#17楼[楼主]
2008-04-13 09:18 | Shinn      
@随风逝去(叶进)
客户部分仓库每天打印数小于3600,为了看起来直观所以一开始只是百位有字母

  回复  引用  查看    
#18楼[楼主]
2008-04-13 09:20 | Shinn      
@SZW
@沙加

其实算法和沙加的是一样,也是分段求余就好了

  回复  引用  查看    
2008-04-14 15:39 | 地狱门神      
话说即使是用楼主的方法也应该用Hashtable或者Dictionary<String,Int32>而不应该用List<String>
  回复  引用  查看    
2008-04-14 18:24 | steven.zhan[未注册用户]
00Z的后一个数字为01A(请思考为什么)
因为010之前用了。。。

To SZW:
在百位用字母前,个位和十位没有使用的字母在后面用到了,所以是完整的36位进制。

  回复  引用    
2008-04-15 11:03 | abinchen[未注册用户]
楼主的意思是数字用完了以后先用百位字母,百位字母用完再用十位,同时百位恢0,十位字母用完用个位,同时十位恢0。
所以Z99->0A0, 0A9->1A0, ZA9->0B0, ZZ9->00A。
那Z0A之后应该为01A吧,00Z是不是应该为序列中最后一个了呢?

  回复  引用    
2008-04-23 08:25 | 李战      
http://www.cnblogs.com/Emoticons/yoyocici/224025633.gif" alt="" />这种方法俺用了近十年了,俺将其称为X36表示法,主要用来作记录标识。
其中的X表示第一位一定是字母,以符合编程语言的标识符规范。http://www.cnblogs.com/Emoticons/msn/tongue_smile.gif" alt="" />
这样,在进行脚本编程的时候,这个记录标识就能直接作为变量名了。http://www.cnblogs.com/Emoticons/QQ/laf.gif" alt="" />


  回复  引用  查看    
2008-04-23 09:02 | good man      
先收藏在说
  回复  引用  查看    
2008-04-23 11:14 | rex xiang      
车牌号就是这样编码的, 是很早就有的, 相当正常的思路, 不需要挑战. http://www.cnblogs.com/Emoticons/QQ/laf.gif" alt="" />
  回复  引用  查看    



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1147473




相关文章:

相关链接: