如何判断一个数字是1开头? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
m
V2EX    问与答

如何判断一个数字是1开头?

  •  
  •   m 2013-01-14 17:19:15 +08:00 6938 次点击
    这是一个创建于 4736 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如变量值为:
    1000
    200
    900000

    我要判断1000时返回true
    同样
    1=true
    10 = true
    100=true

    其他非1开头都为false

    用什么算法可以判断?(除了转为string之外)
    70 条回复    1970-01-01 08:00:00 +08:00
    explon
        1
    explon  
       2013-01-14 17:19:56 +08:00   1
    截取第一字节啊
    NemoAlex
        2
    NemoAlex  
       2013-01-14 17:20:28 +08:00
    不同语言的写法不同,楼主想要哪种
    m
        3
    m  
    OP
       2013-01-14 17:21:08 +08:00
    @explon 变量是个Integer,有没不转为string后再判断的数学方法
    m
        4
    m  
    OP
       2013-01-14 17:21:57 +08:00
    @NemoAlex 算法是一样的吧?我用的java,哪种语言都可以
    itommy
        5
    itommy  
       2013-01-14 17:25:12 +08:00 via iPhone
    %10 = 1 ?
    m
        6
    m  
    OP
       2013-01-14 17:26:55 +08:00
    @itommy 这个。。。100%10=0
    m
        7
    m  
    OP
       2013-01-14 17:28:49 +08:00
    我了说似乎是挺重要的一点
    1111=false
    12000=false
    1230=false
    101=false

    也就是仅判断是否是1后面跟了0
    clww
        8
    clww  
       2013-01-14 17:29:16 +08:00
    应该是除以10...
    m
        9
    m  
    OP
       2013-01-14 17:31:23 +08:00
    @clww 除10只是减一位的0而已,在值为10000的时候也得不到1啊
    itommy
        10
    itommy  
       2013-01-14 17:33:18 +08:00 via iPhone
    @m 记得有个能算出int长度的公式 然后除以就可以了 那个长度 等于 1就 true了

    如果 是 2333 这样的就用 int(2333/1000)
    NemoAlex
        11
    NemoAlex  
       2013-01-14 17:34:30 +08:00
    楼主完全没有描述清楚想要找什么...
    bitsmix
        12
    bitsmix  
       2013-01-14 17:34:43 +08:00
    /^10*$/.test(number)
    clww
        13
    clww  
       2013-01-14 17:35:18 +08:00   1
    @m 回复时你补充上面的那条还没刷出来。。。
    你的原需求一直不断除10就行了
    miaoever
        14
    miaoever  
       2013-01-14 17:35:41 +08:00
    取每一位,然后加起来等于1?
    yyai3
        15
    yyai3  
       2013-01-14 17:35:50 +08:00   2
    log
    Sunyanzi
        16
    Sunyanzi  
       2013-01-14 17:37:53 +08:00   1
    我其实挺想帮 LZ 以便换到某论坛的邀请码的 ... 但我不太理解需求 ...

    (T) 1
    (F) 2
    (T) 10
    (F) 11
    (F) 99
    (T) 100
    (F) 101
    (F) 150
    (T) 1000
    (F) 1001

    如果是我上面描述的那样 ... 以 10 为底取对数也就是 lg ...

    判断结果是否为整数即可 ...
    alexrezit
        17
    alexrezit  
       2013-01-14 17:38:01 +08:00   1
    bool Blah(int i)
    {
    if (i > 10) {
    return Blah(i/10);
    } else {
    return i == 1;
    }
    }
    forest520
        18
    forest520  
       2013-01-14 17:38:33 +08:00   1
    for(; n % 10==0 && n > 1; n /= 10);
    result = (n == 1);
    alexrezit
        19
    alexrezit  
       2013-01-14 17:39:35 +08:00
    @alexrezit
    是 >= 10, 蛋疼的手机输入法...
    alexrezit
        20
    alexrezit  
       2013-01-14 17:44:10 +08:00   1
    @forest520
    你提醒了我, 可以缩减一下:
    Blah(int i){return i>9?Blah(i/10):i==1;}
    alexrezit
        21
    alexrezit  
       2013-01-14 17:45:29 +08:00
    @alexrezit
    bool 又没复制上... orz
        22
    m  
    OP
       2013-01-14 17:53:38 +08:00
    @Sunyanzi 你说的没错,但我没看明白解决方法,写个代码看下?是否能比循环/10好些?
    m
        23
    m  
    OP
       2013-01-14 17:55:07 +08:00
    @itommy 你说的没错,算出数字长度(位数)的公式是什么?
    Air_Mu
        24
    Air_Mu  
       2013-01-14 18:06:08 +08:00   1
    不懂程序
    大概是循环判断此变量是否大于10
    如果大于10就除以10 直到其小于10. 返回此时的值。(设为x)

    如果100<=x*100<=110就返回真。



    比如1024 得出x为1.024 真 咳咳
    Air_Mu
        25
    Air_Mu  
       2013-01-14 18:07:01 +08:00
    修正下 应该是如果大于10就除以10 直到其小于等于10
    Air_Mu
        26
    Air_Mu  
       2013-01-14 18:07:38 +08:00
    再修:
    如果100<=x*100<110就返回真
    blacktulip
        27
    blacktulip  
       2013-01-14 18:10:47 +08:00   1
    。。。。。。

    def one_zero?(number)
    return true if Math.log10(number) % 1 == 0
    return false
    end

    p one_zero?(1000) # => true
    p one_zero?(2000) # => false
    p one_zero?(1200) # => false
    m
        28
    m  
    OP
       2013-01-14 18:16:34 +08:00
    @bitsmix 看不明白这个公式,能解释下吗?
    reusFork
        29
    reusFork  
       2013-01-14 18:17:30 +08:00   1
    def starts_with_digit_1(n):
    return n / (10 ** (math.log10(n))) == 1
    blacktulip
        30
    blacktulip  
       2013-01-14 18:18:37 +08:00
    @m 那不是公式,是正则匹配
    dadastan
        31
    dadastan  
       2013-01-14 18:23:16 +08:00
    s/10*/
    alexrezit
        32
    alexrezit  
       2013-01-14 18:33:44 +08:00   1
    @m
    我的方法不行么? 不需要库的支持, 我不太清楚 Java 能否计算 log.
    Sunyanzi
        33
    Sunyanzi  
       2013-01-14 18:36:33 +08:00   1
    @Air_Mu

    <?php
    var_dump( check( 1 ) );
    var_dump( check( 10 ) );
    var_dump( check( 11 ) );


    function check( $number ) {

    $checker = log10( $number );

    return ( $checker == intval( $checker ) );

    }

    // 这样可以么 ..? 不可以的话我想办法写一个 Java 版本的恩 ...
    Sunyanzi
        34
    Sunyanzi  
       2013-01-14 18:37:09 +08:00
    我我 ... 我 @ 错人了 ... 是 @ LZ 来着 ...
    Air_Mu
        35
    Air_Mu  
       2013-01-14 18:39:23 +08:00
    面红耳赤.....完全忘记对数是什么了...去wiki了下看了半天居然还没理解。
    初中的时候明明觉得很简单的.....
    tioover
       36
    tioover  
       2013-01-14 18:39:59 +08:00
    转成科学计数法以后再判断……
    blacktulip
        37
    blacktulip  
       2013-01-14 18:46:09 +08:00
    @Air_Mu 比方说 十的五次方是一万, 那么 一万的以十为底的对数就是五 ,一种记数方法而已。
    blacktulip
        38
    blacktulip  
       2013-01-14 18:48:59 +08:00
    @Air_Mu 哈哈,脑子糊涂了,十的五次方是十万才对,不好意思,不过对数就那个意思
    Air_Mu
        39
    Air_Mu  
       2013-01-14 18:51:57 +08:00
    @blacktulip 哎 惭愧...中学时期数学一直挺好的。大学后荒置后完全忘记了.
    CoX
        40
    CoX  
       2013-01-14 18:52:43 +08:00   1
    来个python的吧
    n = str(n)
    n[:1]=="1" and int(n[1:] + "0")==0
    Sunyanzi
        41
    Sunyanzi  
       2013-01-14 19:04:19 +08:00   1
    @m 关于效率对比 ...

    $number = 1;
    循环 0.000678062
    对数 0.001754999

    $number = 10;
    循环 0.000564098
    对数 0.001772165

    $number = 10000000;
    循环 0.000665903
    对数 0.001778841

    $number = bcpow( 10, 32 ); // 10^32
    循环 0.000611066 ( 结果错误 )
    对数 0.001586914


    不过事实看来 ... 在 php 里面对数的效率完全不如做多次除法 ...

    对数的唯一优势在于如果一个数字特别大 ... 超过了整数可以处理的范围 ...

    当除法无法计算的时候对数永远可以给出正确的答案这样 ...

    附我的连续除法程序 ...

    while ( true ) {

    if ( $number < 10 ) {

    if ( 1 == $number ) return true;

    else return false;

    } else $number /= 10;

    }
    Mutoo
        42
    Mutoo  
       2013-01-14 19:23:58 +08:00   1
    这不是很笑意吗。。消去后面所有零,然后判断最后是不是为1就行了。

    while(!(a%10))a/=10;
    return a==1;
    m
        43
    m  
    OP
       2013-01-14 22:11:37 +08:00
    谢谢各位,问题已解决,

    使用对数是最好的方案,优雅,准确,表达式为:
    Math.log10(number)%1==0

    相对而言用正则违反题意,需要转string

    循环除10则略傻

    @Sunyanzi 说的效率问题,与增加逻辑复杂度来说,应该可以忽略了
    alexrezit
        44
    alexrezit  
       2013-01-14 22:15:38 +08:00
    @Sunyanzi
    你们都不爱用 recursion 么?
    m
        45
    m  
    OP
       2013-01-14 22:20:15 +08:00
    @alexrezit 这不是没必要专门写个递归函数来做这个么, log10大赞,虽然已经完全不知道对数是干嘛的了
    Sunyanzi
        46
    Sunyanzi  
       2013-01-14 22:21:35 +08:00   1
    那么那么 ... 如果有帮助的话 ... 顺求某个你懂的论坛的邀请 ...

    前几天来晚了哭泣 ...

    _________@________.__
    webmaster_sunyanzi_cn

    @alexrezit 不是爱不爱用 ... 关键是这个事情为什么要 recursion ..?

    function huh( $number ) {

    if ( $number < 10 ) {

    if ( 1 == $number ) return true;

    else return false;

    } else return huh( $number / 10 );

    }

    写成这样的好处何在呢 ..?
    m
        47
    m  
    OP
       2013-01-14 22:32:48 +08:00
    @Sunyanzi 我已经精尽人亡挤不出码了,产量极其有限啊!只能发感谢了
    Sunyanzi
        48
    Sunyanzi  
       2013-01-14 22:35:46 +08:00
    @m 喔喔那好吧 ... 果然来晚了就是来晚了 ...

    恩恩 ... thanks all the same ...
    alexrezit
        49
    alexrezit  
       2013-01-14 22:47:08 +08:00
    @m
    @Sunyanzi
    Recursion 思路不是更简单么? 难道 recursion 会降低效率?
    txx
        50
    txx  
       2013-01-14 23:21:30 +08:00
    @alexrezit 更喜欢写while ...当初做数据结构练习的时候 递归导致了栈溢出= =......
    m
        51
    m  
    OP
       2013-01-14 23:25:10 +08:00
    @alexrezit 因为提高逻辑复杂度,不妥
    013231
        52
    013231  
       2013-01-15 00:30:56 +08:00   3
    既然你决定使用math.log10(x) % 1 == 0,说明你想匹配的是形如/10+/的数字。这种数字相当有限,完全可以不使用缓慢的log,直接查表即可。
    先估算一下x可能的范围,假设x <= 10**19:
    http://gist.github.com/4531249
    CoX
        53
    CoX  
       2013-01-15 00:56:15 +08:00
    @013231 这效率应该最高了吧
    haohaolee
        54
    haohaolee  
       2013-01-15 01:46:53 +08:00
    我表示怀疑,对数真的不会产生误差?以至于还要考虑 floor 或者 round?
    查表那个很有意思啊
    laskuma
        55
    laskuma  
       2013-01-15 02:39:43 +08:00   1
    @m 觉得LZ要是在代码里试用对数 那才是逻辑复杂 非常不妥
    Mutoo
        56
    Mutoo  
       2013-01-15 09:08:50 +08:00
    取对数的效率太低了吧,还有一个问题,对数产生的是浮点数,而%取余是整型运算,误差就不说了。
        57
    Mutoo  
       2013-01-15 09:09:46 +08:00   1
    @Mutoo (没打完不小心按回复)

    Javascript:

    Math.log(100000000000000000001)/Math.log(10)%1==0 //true
    m
        58
    m  
    OP
       2013-01-15 09:15:40 +08:00
    @Mutoo 是log10算法效率低下?我都不知道对数是干嘛的了
    什么是代替方案?存个表还是正则匹配?
    Mutoo
        59
    Mutoo  
       2013-01-15 09:22:39 +08:00
    Mutoo
        60
    Mutoo  
       2013-01-15 09:24:33 +08:00   1
    @m log的内部实现比循环取余更ugly,只是你看不到……你要是觉得循环取余难看,就把他封装成函数,丢一边去。函数体也就2行(见42楼),取个好听点的名字就行了。
    2lbj
        61
    2lbj  
       2013-01-15 11:17:09 +08:00
    我去不是这么复杂吧?!!
    2lbj
        62
    2lbj  
       2013-01-15 11:18:13 +08:00
    这种事情果断用正则表达式啊?
    xpfd
        63
    xpfd  
       2013-01-15 11:46:09 +08:00
    不断的对10取余 余数不为0 返false 然后除10 判断是不是1或者0
    alexrezit
        64
    alexrezit &bsp;
       2013-01-15 11:52:44 +08:00
    @m
    Recursion 在逻辑上应该是更简单才对吧...
    m
        65
    m  
    OP
       2013-01-15 12:05:46 +08:00
    我测试了一下执行效率,测试结果如下:
    regex : used:706657ns
    log10 : used:23906ns
    contains: used:11346ns
    while : used:1216ns

    可见使用正则是最慢的,整整706657ns @2lbj

    我使用的测试代码如下:
    //regex
    boolean is10=(""+n).matches("^10*$");

    //log10
    boolean is10=Math.log10(n)%1==0;

    //contains
    boolean is10=TEN.contains(n);

    //while
    while(true){
    n=n/10;
    if(n==1){
    return true;
    }else if(n<10){
    return false;
    }
    }


    BTW:我最终还是使用了log10方法进行判断
    chisj
        66
    chisj  
       2013-01-15 12:32:01 +08:00
    @explon 有木有考虑大端序和小端序?哈哈!
    picasso250
        67
    picasso250  
       2013-01-15 13:23:55 +08:00
    目测52楼效率最高。log10的方案目测应该比循环除还慢(毕竟循环除是整数除法,而log10应该是double的除法)。
    soulteary
        68
    soulteary  
       2013-01-15 14:21:26 +08:00
    @Mutoo IEEE754标准的JS你懂的,js的话,查表应该是不错选择。
    sangwei
        69
    sangwei  
       2013-01-15 14:24:26 +08:00   1
    给个最土的思路:
    //32 位 int -2,147,483,648 ~ +2,147,483,647
    if (x == 1 or x == -1) return true;
    if (x == 10 or x == -10) return true;
    ...
    if (x == 1,000,000,000 or x == -1,000,000,000) return true;
    return false;
    madao
        70
    madao  
       2013-01-15 15:42:27 +08:00
    @013231 有意思
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2371 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 10:18 PVG 18:18 LAX 02:18 JFK 05:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86