m
V2EX  ›  问与答

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

  •  
  •   m · Jan 14, 2013 · 7202 views
    This topic created in 4891 days ago, the information mentioned may be changed or developed.
    例如变量值为:
    1000
    200
    900000

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

    其他非1开头都为false

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

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

    如果 是 2333 这样的就用 int(2333/1000)
    NemoAlex
        11
    NemoAlex  
       Jan 14, 2013
    楼主完全没有描述清楚想要找什么...
    bitsmix
        12
    bitsmix  
       Jan 14, 2013
    /^10*$/.test(number)
    clww
        13
    clww  
       Jan 14, 2013   ❤️ 1
    @m 回复时你补充上面的那条还没刷出来。。。
    你的原需求一直不断除10就行了
    miaoever
        14
    miaoever  
       Jan 14, 2013
    取每一位,然后加起来等于1?
    yyai3
        15
    yyai3  
       Jan 14, 2013   ❤️ 2
    log
    Sunyanzi
        16
    Sunyanzi  
       Jan 14, 2013   ❤️ 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  
       Jan 14, 2013   ❤️ 1
    bool Blah(int i)
    {
    if (i > 10) {
    return Blah(i/10);
    } else {
    return i == 1;
    }
    }
    forest520
        18
    forest520  
       Jan 14, 2013   ❤️ 1
    for(; n % 10==0 && n > 1; n /= 10);
    result = (n == 1);
    alexrezit
        19
    alexrezit  
       Jan 14, 2013
    @alexrezit
    是 >= 10, 蛋疼的手机输入法...
    alexrezit
        20
    alexrezit  
       Jan 14, 2013   ❤️ 1
    @forest520
    你提醒了我, 可以缩减一下:
    Blah(int i){return i>9?Blah(i/10):i==1;}
    alexrezit
        21
    alexrezit  
       Jan 14, 2013
    @alexrezit
    bool 又没复制上... orz
    m
        22
    m  
    OP
       Jan 14, 2013
    @Sunyanzi 你说的没错,但我没看明白解决方法,写个代码看下?是否能比循环/10好些?
    m
        23
    m  
    OP
       Jan 14, 2013
    @itommy 你说的没错,算出数字长度(位数)的公式是什么?
    Air_Mu
        24
    Air_Mu  
       Jan 14, 2013   ❤️ 1
    不懂程序
    大概是循环判断此变量是否大于10
    如果大于10就除以10 直到其小于10. 返回此时的值。(设为x)

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



    比如1024 得出x为1.024 真 咳咳
    Air_Mu
        25
    Air_Mu  
       Jan 14, 2013
    修正下 应该是如果大于10就除以10 直到其小于等于10
    Air_Mu
        26
    Air_Mu  
       Jan 14, 2013
    再修:
    如果100<=x*100<110就返回真
    blacktulip
        27
    blacktulip  
       Jan 14, 2013   ❤️ 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
       Jan 14, 2013
    @bitsmix 看不明白这个公式,能解释下吗?
    reusFork
        29
    reusFork  
       Jan 14, 2013   ❤️ 1
    def starts_with_digit_1(n):
    return n / (10 ** (math.log10(n))) == 1
    blacktulip
        30
    blacktulip  
       Jan 14, 2013
    @m 那不是公式,是正则匹配
    dadastan
        31
    dadastan  
       Jan 14, 2013
    s/10*/
    alexrezit
        32
    alexrezit  
       Jan 14, 2013   ❤️ 1
    @m
    我的方法不行么? 不需要库的支持, 我不太清楚 Java 能否计算 log.
    Sunyanzi
        33
    Sunyanzi  
       Jan 14, 2013   ❤️ 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  
       Jan 14, 2013
    我我 ... 我 @ 错人了 ... 是 @ LZ 来着 ...
    Air_Mu
        35
    Air_Mu  
       Jan 14, 2013
    面红耳赤.....完全忘记对数是什么了...去wiki了下看了半天居然还没理解。
    初中的时候明明觉得很简单的.....
    tioover
        36
    tioover  
       Jan 14, 2013
    转成科学计数法以后再判断……
    blacktulip
        37
    blacktulip  
       Jan 14, 2013
    @Air_Mu 比方说 十的五次方是一万, 那么 一万的以十为底的对数就是五 ,一种记数方法而已。
    blacktulip
        38
    blacktulip  
       Jan 14, 2013
    @Air_Mu 哈哈,脑子糊涂了,十的五次方是十万才对,不好意思,不过对数就那个意思
    Air_Mu
        39
    Air_Mu  
       Jan 14, 2013
    @blacktulip 哎 惭愧...中学时期数学一直挺好的。大学后荒置后完全忘记了.
    CoX
        40
    CoX  
       Jan 14, 2013   ❤️ 1
    来个python的吧
    n = str(n)
    n[:1]=="1" and int(n[1:] + "0")==0
    Sunyanzi
        41
    Sunyanzi  
       Jan 14, 2013   ❤️ 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  
       Jan 14, 2013   ❤️ 1
    这不是很笑意吗。。消去后面所有零,然后判断最后是不是为1就行了。

    while(!(a%10))a/=10;
    return a==1;
    m
        43
    m  
    OP
       Jan 14, 2013
    谢谢各位,问题已解决,

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

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

    循环除10则略傻

    @Sunyanzi 说的效率问题,与增加逻辑复杂度来说,应该可以忽略了
    alexrezit
        44
    alexrezit  
       Jan 14, 2013
    @Sunyanzi
    你们都不爱用 recursion 么?
    m
        45
    m  
    OP
       Jan 14, 2013
    @alexrezit 这不是没必要专门写个递归函数来做这个么, log10大赞,虽然已经完全不知道对数是干嘛的了
    Sunyanzi
        46
    Sunyanzi  
       Jan 14, 2013   ❤️ 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
       Jan 14, 2013
    @Sunyanzi 我已经精尽人亡挤不出码了,产量极其有限啊!只能发感谢了
    Sunyanzi
        48
    Sunyanzi  
       Jan 14, 2013
    @m 喔喔那好吧 ... 果然来晚了就是来晚了 ...

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

    javascript:

    Math.log(100000000000000000001)/Math.log(10)%1==0 //true
    m
        58
    m  
    OP
       Jan 15, 2013
    @Mutoo 是log10算法效率低下?我都不知道对数是干嘛的了
    什么是代替方案?存个表还是正则匹配?
    Mutoo
        59
    Mutoo  
       Jan 15, 2013
    Mutoo
        60
    Mutoo  
       Jan 15, 2013   ❤️ 1
    @m log的内部实现比循环取余更ugly,只是你看不到……你要是觉得循环取余难看,就把他封装成函数,丢一边去。函数体也就2行(见42楼),取个好听点的名字就行了。
    2lbj
        61
    2lbj  
       Jan 15, 2013
    我去不是这么复杂吧?!!
    2lbj
        62
    2lbj  
       Jan 15, 2013
    这种事情果断用正则表达式啊?
    xpfd
        63
    xpfd  
       Jan 15, 2013
    不断的对10取余 余数不为0 返false 然后除10 判断是不是1或者0
    alexrezit
        64
    alexrezit  
       Jan 15, 2013
    @m
    Recursion 在逻辑上应该是更简单才对吧...
    m
        65
    m  
    OP
       Jan 15, 2013
    我测试了一下执行效率,测试结果如下:
    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  
       Jan 15, 2013
    @explon 有木有考虑大端序和小端序?哈哈!
    picasso250
        67
    picasso250  
       Jan 15, 2013
    目测52楼效率最高。log10的方案目测应该比循环除还慢(毕竟循环除是整数除法,而log10应该是double的除法)。
    soulteary
        68
    soulteary  
       Jan 15, 2013
    @Mutoo IEEE754标准的JS你懂的,js的话,查表应该是不错选择。
    sangwei
        69
    sangwei  
       Jan 15, 2013   ❤️ 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  
       Jan 15, 2013
    @013231 有意思
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   852 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 127ms · UTC 21:28 · PVG 05:28 · LAX 14:28 · JFK 17:28
    ♥ Do have faith in what you're doing.