m
V2EX  ›  问与答

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

  •  
  •   m · Jan 14, 2013 · 7586 views
    This topic created in 5052 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
    explon
    Jan 14, 2013❤️1
    1
    截取第一字节啊
    NemoAlex
    NemoAlex
    Jan 14, 2013
    2
    不同语言的写法不同,楼主想要哪种
    m
    m
    OP
    Jan 14, 2013
    3
    @explon 变量是个Integer,有没不转为string后再判断的数学方法
    m
    m
    OP
    Jan 14, 2013
    4
    @NemoAlex 算法是一样的吧?我用的java,哪种语言都可以
    itommy
    itommy
    Jan 14, 2013 via iPhone
    5
    %10 = 1 ?
    m
    m
    OP
    Jan 14, 2013
    6
    @itommy 这个。。。100%10=0
    m
    m
    OP
    Jan 14, 2013
    7
    我忘了说似乎是挺重要的一点
    1111=false
    12000=false
    1230=false
    101=false

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

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

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

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

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

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



    比如1024 得出x为1.024 真 咳咳
    Air_Mu
    Air_Mu
    Jan 14, 2013
    25
    修正下 应该是如果大于10就除以10 直到其小于等于10
    Air_Mu
    Air_Mu
    Jan 14, 2013
    26
    再修:
    如果100<=x*100<110就返回真
    blacktulip
    blacktulip
    Jan 14, 2013❤️1
    27
    。。。。。。

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

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

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

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

    循环除10则略傻

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

    前几天来晚了哭泣 ...

    _________@________.__
    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
    m
    OP
    Jan 14, 2013
    47
    @Sunyanzi 我已经精尽人亡挤不出码了,产量极其有限啊!只能发感谢了
    Sunyanzi
    Sunyanzi
    Jan 14, 2013
    48
    @m 喔喔那好吧 ... 果然来晚了就是来晚了 ...

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

    javascript:

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