V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
m
V2EX  ›  问与答

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

  •  
  •   m · 2013-01-14 17:19:15 +08:00 · 6429 次点击
    这是一个创建于 4361 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如变量值为:
    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
    m
        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
    取对数的效率太低了吧,还有一个问题,对数产生的是浮点数,而%取余是整型运算,误差就不说了。
    Mutoo
        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  
       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   ·   实用小工具   ·   3466 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.