abusizhishen
V2EX  ›  算法

面试时遇到的一道算法题

  •  
  •   abusizhishen · Mar 18, 2018 · 6287 views
    This topic created in 3151 days ago, the information mentioned may be changed or developed.

    写算法实现从字符串中提取整数。
    如 'a1b2c3d4'需要提取为 1234,这里的 1234 是整数不是字符串 要求:
    1.不能有隐式类型转换。
    2.尽可能优化。

    3.延伸思考,如果提取出的数字超过最大值怎么办?如最大为 123,超过这个数时如何处理?

    39 replies  •  2018-03-22 23:51:25 +08:00
    sean10
    sean10
    Mar 18, 2018 via Android
    1
    这块转换不太懂,stringstream 转换的可以吗?
    seaswalker
    seaswalker
    Mar 18, 2018 via iPhone
    2
    倒序遍历字符串,判断 ASCII 码,如果是数字,减去字符 0,乘以 10/00/1000 等等,相加?
    JRyan
    JRyan
    Mar 18, 2018
    3
    @seaswalker 这样是不是有隐式类型转换?
    abusizhishen
    abusizhishen
    OP
    Mar 18, 2018 via Android
    4
    @seaswalker 思路可以
    abusizhishen
    abusizhishen
    OP
    Mar 18, 2018 via Android
    5
    @seaswalker 判断 ASC 太麻烦,还有没有简单点的?
    MinonHeart
    MinonHeart
    Mar 18, 2018 via iPhone
    6
    正则+显示转换
    deepjia
    deepjia
    Mar 19, 2018 via iPhone
    7
    直接每个字符哈希表映射一下完事
    lance6716276
    lance6716276
    Mar 19, 2018 via Android
    8
    延伸 4 适配给定编码的不同编码的字符串(我没想出自己的这个问题在 C 下要怎么弄
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    9
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    10
    @deepjia 接近了
    lhx2008
    lhx2008
    Mar 19, 2018 via Android
    11
    怎么样算隐式和显示啊,parseInt 算显示还是隐式?
    lhx2008
    lhx2008
    Mar 19, 2018 via Android
    12
    感觉还是 3 楼的思路,直接减'0'比 map 简单吧,倒序遍历,减出来如果小于 10 就加进 sum,然后 sum * 10,下一个循环。然后每次检查是不是比 123 大。
    lhx2008
    lhx2008
    Mar 19, 2018 via Android❤️1
    13
    但是 char 减 char 最后还是先转了 int,如果这样也算隐式的话就只能用 map 了
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    14
    @lhx2008 不能用 paseint,必须自己写程序识别
    blless
    blless
    Mar 19, 2018 via Android
    15
    我写过类似的 直接用 unicodedata.numeric 判断的 unicode 自带符号 数字 大小写之类的判断 理论上没有进行类型转换 只是字符编码区间的归类
    blless
    blless
    Mar 19, 2018 via Android
    16
    理论上我觉得用自带的归类判断应该是最优的 正则底层其实还是用字符归类做的
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    17
    @lhx2008 不能直接拿来减,这不还是隐式转换么,另外不能直接和 123 比较,因为如果加起来的值大于了系统存储的最大值 123,就已经出错了
    pkookp8
    pkookp8
    Mar 19, 2018 via Android
    18
    for i in strings:
    if i > '0' and i < '9'
    sum = sum * 10 + i
    这样?
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    19
    @blless 看起来可以
    geelaw
    geelaw
    Mar 19, 2018
    20
    /* assume C, therefore character literals are ints. */
    unsigned asDigit(int ch)
    {
    if (ch >= '0' && ch <= '0' + 10) return ch - '0';
    return -1u;
    }
    int parseAsUInt(char const *input, unsigned upperBound, unsigned *presult)
    {
    unsigned result = 0;
    unsigned const threshold10 = upperBound / 10, threshold1 = upperBound % 10;
    unsigned current;
    if (!input) return 0;
    for (; (int)*input; ++input)
    {
    if ((current = asDigit((int)*input)) == -1u) continue;
    if (result > threshold10) return 0;
    if (result == threshold10 && current > threshold1) return 0;
    result = result * 10u + current;
    }
    if (presult)
    *presult = result;
    return 1;
    }

    脑补的
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    21
    @pkookp8 隐式转换哦
    geelaw
    geelaw
    Mar 19, 2018
    22
    @geelaw 呃……显然我的意思是 if (ch >= '0' && ch < '0' + 10) 才对
    MeteorCat
    MeteorCat
    Mar 19, 2018 via Android
    23
    ASCII 判断一下就行了
    MeteorCat
    MeteorCat
    Mar 19, 2018 via Android
    24
    muduo 库里面有个字符串转数字的方法,你看下是不是这样
    https://github.com/chenshuo/muduo/blob/master/muduo/base/LogStream.cc
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    25
    @geelaw 没看懂😂
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    26
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    27
    预定义一个数组
    abusizhishen
    abusizhishen
    OP
    Mar 19, 2018 via Android
    28
    $arr=["0"=>0,"1"=>1,"2"=>2,...]
    array_key_exists()
    markx
    markx
    Mar 19, 2018
    29
    不能隐式类型转换, 可以显式转换?
    binux
    binux
    Mar 19, 2018 via Android❤️3
    30
    @abusizhishen 这不叫算法题,这叫猜猜看我想什么。
    lhx2008
    lhx2008
    Mar 19, 2018 via Android
    31
    @binux 脱了裤子放屁哈哈,增加空间复杂度时间复杂度
    ctro15547
    ctro15547
    Mar 19, 2018
    32
    #python
    s = 'a1a2a3a4'
    i = int(''.join(filter(lambda k: k.isdigit(),list(s))))
    print i
    #1234

    延伸 3,如果只比 123 小就输出的话,写个判断 大于 123 的 除以 100,即 12.34 ,19.37 这种

    还可以先排个序,输出:范围内最大或最小的数,43.21 ,97.31

    是我理解错了吗,总感觉前面讨论的我都听不懂。。。
    bzw875
    bzw875
    Mar 19, 2018
    33
    'a1b2c3d4'.replace(/[^\d]/g, '')
    i_have_to_pee
    i_have_to_pee
    Mar 19, 2018
    34
    楼主这么萌,你们不要欺负他。
    Bryan0Z
    Bryan0Z
    Mar 19, 2018 via Android
    35
    讲道理,两个 for 循环搞定啊…像我大一时候做的题目
    SourceMan
    SourceMan
    Mar 19, 2018❤️1
    36
    这不是算法题
    这叫:茴香豆的茴有几种写法
    Kisesy
    Kisesy
    Mar 19, 2018
    37
    看起来简单的问题,实际上非常难,因为限制了隐式类型转换,而不少语言,从字符串里取元素时,会隐式转成整数,所以连字符串遍历都不能写,就别说实现了(滑稽
    snowonion
    snowonion
    Mar 22, 2018
    38
    -- Haskell (GHC 8.2.2)
    -- 使用了尽量初级的语言特性……

    extractInt :: String -> Int
    extractInt str = strToInt (filter isDigit str)

    strToInt :: String -> Int
    strToInt str = sum ( zipWith (*) (map (10^) [0..]) (reverse (strToDigits str) ) )

    strToDigits :: String -> [Int]
    strToDigits str = map (subtract (fromEnum '0') . fromEnum) str

    isDigit :: Char -> Bool
    isDigit ch = fromEnum '0' <= ascii && ascii <= fromEnum '9' where
    ascii = fromEnum ch

    >> 如果提取出的数字超过最大值怎么办?如最大为 123,超过这个数时如何处理?

    你想处理成什么样?
    (注意不是“你想怎么处理”)
    snowonion
    snowonion
    Mar 22, 2018
    39
    Oi,为什么程序员聚居的 V2EX 吃缩进这么熟练啊! Try:
    ```
    isDigit :: Char -> Bool
    isDigit ch = fromEnum '0' <= ascii && ascii <= fromEnum '9' where
    ascii = fromEnum ch
    ```
    这里有两个空格缩进 ascii = fromEnum ch
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2991 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 60ms · UTC 10:52 · PVG 18:52 · LAX 02:52 · JFK 05:52
    ♥ Do have faith in what you're doing.