找回密码
 加入
搜索
查看: 11678|回复: 20

[效率算法] [已解决]如何将数字转换为36的7次方的数字字母组合,也就N进制与10进制的转换

 火.. [复制链接]
发表于 2012-6-20 11:04:59 | 显示全部楼层 |阅读模式
本帖最后由 xdcysten 于 2012-6-22 10:41 编辑

每一位数可代表0~1或A~Z, 字母不分大小写 ,可变数为 36, 但上了36以后逻辑就开始有点乱了,第二位要再从1一直递进直到Z完毕然后再到第三位数。

比如:0 = 0000000
         1 = 0000001
        10 = 000000A



——————————————————————
问题已经解决,感谢楼下的几位兄弟帮忙


10进制转N进制的,p版的代码:
Func _62Hex($iValue, $iHex)
If $iHex < 2 Or $iHex > 65 Then
Return SetError(1, 0, "")
EndIf

Local Const $KEY = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+@"

Local $iMod, $sResult

While $iValue
$iMod = Mod($iValue, $iHex)
$sResult = StringMid($KEY, $iMod + 1, 1) & $sResult

$iValue = Int($iValue / $iHex)

WEnd

;Return StringFormat("(%d)%s", $iHex, $sResult)
Return $sResult
EndFunc ;==>_62Hex
N进制转10进制的:
Func _N2Dec($iValue, $iHex)
        Local Const $KEY = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+@"
           Local $iValueLen = StringLen($iValue), $sResult
           If $iHex < 2 Or $iHex > StringLen($KEY) Then
                   Return SetError(1, 0, "")
           EndIf
        For $i = 1 To $iValueLen
                $sResult+=(StringInStr($KEY, StringMid($iValue, $i, 1),1)-1)* ($iHex^($iValueLen-$i))
        Next
        Return $sResult
EndFunc   ;==>_N2Dec

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2012-6-20 11:29:41 | 显示全部楼层
本帖最后由 netegg 于 2012-6-20 11:58 编辑

进制转换?这种超过10的进制转换,需要定义到底是一个数位还是两个数位,比方126,是怎么认定的,是1和26还是12和6,甚或是1,2,6
 楼主| 发表于 2012-6-20 11:57:01 | 显示全部楼层
回复 2# netegg


  网上查了一下,这个应该就是  10进制转36进制,但这方面的有效益的算法不去从何着手,逻辑不成
发表于 2012-6-20 12:00:34 | 显示全部楼层
回复 3# xdcysten
难倒也不是很难,就是写起来麻烦,无非是递归计算乘方和而已
发表于 2012-6-20 12:03:25 | 显示全部楼层
Global $dic=ObjCreate("scripting.dictionary")
For $n=0 To 9
        $dic($dic.count)=$n
Next
For $n=Asc("A") To Asc("Z")
        $dic($dic.count)=Chr($n)
Next

$n=Int(Random(1,36^7))
;$n=72

MsgBox(0,"",$n&@TAB&_Exchange($n))

Func _Exchange($n)
        $str=""
        Do
                $str=$dic(Mod($n,36))&$str
                $n=Int($n/36)
        Until $n<36
        $str=$dic($n)&$str
        Return $str
EndFunc
试下,太大不知会不会溢出
发表于 2012-6-20 12:11:30 | 显示全部楼层
Global $arr[36]
For $n=0 To 9
        $arr[$n]=$n
Next
For $i=Asc("A") To Asc("Z")
        $arr[$n]=Chr($i)
        $n+=1
Next

$n=Int(Random(1,36^7))
;$n=360

MsgBox(0,"",$n&@TAB&_Exchange($n))

Func _Exchange($n)
        $str=""
        Do
                $str=$arr[Mod($n,36)]&$str
                $n=Int($n/36)
        Until $n<36
        $str=$arr[$n]&$str
        Return $str
EndFunc
转换规则对应项不多,用数组实现吧

评分

参与人数 1金钱 +30 贡献 +5 收起 理由
xdcysten + 30 + 5 非常不错,学习了

查看全部评分

 楼主| 发表于 2012-6-20 12:31:46 | 显示全部楼层
回复 6# kevinch

多谢兄弟的回答,是这个了,能问多两个问题吗

1.在0~9,A~Z, a~z 字母大小混合情况如何实现呢
2.这些组合如何能反读出来,比如:0A = 10

数学和逻辑实在不成,还望见谅,请多多指教
发表于 2012-6-20 12:36:14 | 显示全部楼层
本帖最后由 netegg 于 2012-6-20 12:41 编辑

回复 7# xdcysten
我就说嘛,进制转换不是那么容易的,如果建立字典的话,还不如直接写个数组对应着换了
楼主,看看10进制和16进制转换的代码吧,自己试着扩展下,把里面的参数修改下
还有lz所说的混排,A,a到底是不是一样的,如果不是的话,那就不是36进制是62进制
 楼主| 发表于 2012-6-20 12:49:57 | 显示全部楼层
回复 8# netegg

多谢NETEGG提醒,刚才粗俗的看了一下,如果纯计算的话,效率会有小小小慢
写数组对应我觉得效率可能会好小小

看看能不能有些前辈有更高效的算法

最好可以互换的,像:10=0A                0A=10
 楼主| 发表于 2012-6-20 12:55:31 | 显示全部楼层
回复 8# netegg

对,是62进制,有时候需要这样的大小写字母数字混排,我有个想法,不知能用正则表达式来实现不?
发表于 2012-6-20 13:10:58 | 显示全部楼层
序列和mod值修改一下就行了
转换成十进制的话逐位:对就数值*进制^(位数-1),然后累加起来就行了
发表于 2012-6-20 15:58:15 | 显示全部楼层

MsgBox(0, "10 -> 36", _62Hex(111111111111111, 36))

Func _62Hex($iValue, $iHex)
        If $iHex < 2 OR $iHex > 62 Then
                Return SetError(1, 0, "")
        EndIf

        Local Const $KEY = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

        Local $iMod, $sResult

        While $iValue
                $iMod = Mod($iValue, $iHex)
                $sResult = StringMid($KEY, $iMod + 1, 1) & $sResult

                $iValue = Int($iValue / $iHex)
        WEnd

        Return StringFormat("(%d)%s", $iHex, $sResult)
EndFunc        ;==>_62Hex


简单取余就好了。

评分

参与人数 4金钱 +70 贡献 +20 收起 理由
shqf + 30 + 5 厉害
xdcysten + 20 + 5 方法巧妙
netegg + 5
user3000 + 20 + 5 学习了!

查看全部评分

发表于 2012-6-20 16:20:13 | 显示全部楼层
学习了 P版这个方法还是很不错的
发表于 2012-6-20 22:04:09 | 显示全部楼层
P版的经典。进制转换好像就是取余计算
 楼主| 发表于 2012-6-20 22:06:58 | 显示全部楼层
回复 12# pusofalse


试了P版的代码,方法很是巧妙,除了32或62进制外其它的进制也可以自定义

网上查了一下,下面是用php写的进制转换,对PHP语法不熟悉,any2Dec那里只明白要先计算字符的长度以此为计算次数,bcadd=加 bcmul=乘,其它就看不明了

请问那62进制转回10进制应该怎么写?
/**
 * 返回一字符串,十进制 number 以 radix 进制的表示。
 * @param dec       需要转换的数字
 * @param toRadix    输出进制。当不在转换范围内时,此参数会被设定为 2,以便及时发现。
 * @return    指定输出进制的数字
 */
function dec2Any($dec, $toRadix) {
    $MIN_RADIX = 2;
    $MAX_RADIX = 62;
    $num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    if ($toRadix < $MIN_RADIX || $toRadix > $MAX_RADIX) {
        $toRadix = 2;
    }
    if ($toRadix == 10) {
        return $dec;
    }
    // -Long.MIN_VALUE 转换为 2 进制时长度为65
    $buf = array();
    $charPos = 64;
    $isNegative = $dec < 0; //(bccomp($dec, 0) < 0);
    if (!$isNegative) {
        $dec = -$dec; // bcsub(0, $dec);
    }
 
    while (bccomp($dec, -$toRadix) <= 0) {
        $buf[$charPos--] = $num62[-bcmod($dec, $toRadix)];
        $dec = bcdiv($dec, $toRadix);
    }
    $buf[$charPos] = $num62[-$dec];
    if ($isNegative) {
        $buf[--$charPos] = '-';
    }
    $_any = '';
    for ($i = $charPos; $i < 65; $i++) {
        $_any .= $buf[$i];
    }
    return $_any;
}
 
/**
 * 返回一字符串,包含 number 以 10 进制的表示。
 * fromBase 只能在 2 和 62 之间(包括 2 和 62)。
 * @param number    输入数字
 * @param fromRadix    输入进制
 * @return  十进制数字
 */
function any2Dec($number, $fromRadix) {
    $num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $dec = 0;
    $digitValue = 0;
    $len = strlen($number) - 1;
    for ($t = 0; $t <= $len; $t++) {
        $digitValue = strpos($num62, $number[$t]);
        $dec = bcadd(bcmul($dec, $fromRadix), $digitValue);
    }
    return $dec;
}
 
$sol = '<br/>' . PHP_EOL;
echo any2Dec('ZZZZZZ', 62), $sol; // 56800235583
echo dec2Any('123456', 62), $sol; // w7e
echo any2Dec('w7e', 62), $sol; // 123456
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-22 09:36 , Processed in 0.108390 second(s), 29 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表