资讯专栏INFORMATION COLUMN

[算法] 电话号码分身 (小米2017 秋招真题)[JavaScript]

ivan_qhz / 745人阅读

摘要:仔细分析可以发现,字符在这五个数字的英文中,只存在于字符只存在于中,以此类推。

题目描述

继MIUI8推出手机分身功能,MIUI计划推出一个电话号码分身得功能:首先将电话号码中的每个数字加上8取个位,然后使用对应得大写字母代替 ("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"), 然后随机打乱这些字母,所生成得字符串即为电话号码对应得分身。

例子:
输入 => 输出
EIGHT => 0
ZEROTWOONE => 234
OHWETENRTEO => 345
OHEWTIEGTHENRTEO => 0345

这道题是输入一个字符串,映射到一个数字串。
映射题我的习惯是先尝试用字典的方式做,那么接下来开始做这道题:

10个数字与其英文单词一一对应,那么这些词能不能做些文章呢?

我们可以发现,在这十个数字的英文单词中,字符 Z 只存在于 ZEROW 只存在于 TWO,以此类推。
所以现在一旦在字符串中发现 Z,我们就可以说存在 0
我们在这里把 Z 称作 特征字符, ZERO 称作 字符值, 0 称为 数字值
那么,我们可以得到一组映射:

{
    Z: ["ZERO", 0],
    W: ["TWO", 2],
    U: ["FOUR", 4],
    X: ["SIX", 6],
    G: ["EIGHT", 8]
}

因此0, 2, 4, 6, 8已经处理好了,现在还剩下 1, 3, 5, 7, 9
仔细分析可以发现,字符O在这五个数字的英文中,只存在于ONE;字符F只存在于FIVE中,以此类推。
那么,我们又可以得到一组映射:

{
    O: ["ONE", 1],
    T: ["THREE", 3],
    F: ["FIVE", 5],
    S: ["SEVEN", 7]
}

为什么这里没有9的映射呢?因为 NINEN, I, E1, 3, 5, 7中都有出现,这里我们就先空着。

注意
这里的两个映射关系是不可以合并的,想想为什么?

那么这些映射关系有什么用呢?这里就要用到字典(dict)啦。
我们可以把输入的字符串,转换为一个字典结构,key 是字符, value 是这个字符在整个字符串中出现的次数。

例如:

"OHEWTIEGTHENRTEO"

var dict = {
    E: 4,
    T: 3,
    O: 2,
    H: 2,
    I: 1,
    G: 1,
    W: 1,
    N: 1,
    R: 1
}

然后我们遍历这个字典:

[{
    Z: ["ZERO", 0],
    W: ["TWO", 2],
    U: ["FOUR", 4],
    X: ["SIX", 6],
    G: ["EIGHT", 8]
},{
    O: ["ONE", 1],
    T: ["THREE", 3],
    F: ["FIVE", 5],
    S: ["SEVEN", 7]
}].map(map => {
    Object.keys(dict).map(key => {
        /** 检查当前字符是否在映射表中
         * 在的话检查字典中当前字符的数量是否仍然大于0
         */
        map[key] && dict[key] > 0 &&
        /**
         * 把映射关系中的字面值取出并拆解为一个字符数组,
         * 遍历这个字符数组,将字典中该字符的计数减去1,即消化了这个字面值
         */
        map[key][0].split("").map(char => dict[char] -= 1) &&
        // 把消化的数字值打出来
        console.log(map[key][1])
    })
})

/**
 * 2
 * 8
 * 1
 * 3
 */

可是题目说明 OHEWTIEGTHENRTEO 的输出值应该是 0345呀,哪里出错了呢?

注意题目中的一句话

首先将电话号码中的每个数字加上8取个位

也就是说,我们打出来的值还需要对这个 加8取个位 进行逆向。
有几种方法,一是在打印时对 map[key][1] 进行处理:

num => num - 8 >= 0 ? num - 8 : num + 2

或者,我这里用了偷懒的办法,还记得我们映射表中有个数字值吗?我人工替换了 :P

[{
    Z: ["ZERO", 2],
    W: ["TWO", 4],
    U: ["FOUR", 6],
    X: ["SIX", 8],
    G: ["EIGHT", 0]
},{
    O: ["ONE", 3],
    T: ["THREE", 5],
    F: ["FIVE", 7],
    S: ["SEVEN", 9
}].map(map => {
    Object.keys(dict).map(key => {
        map[key] && dict[key] > 0 &&
        map[key][0].split("").map(char => dict[char] -= 1) &&
        console.log(map[key][1])
    })
})

/**
 * 4
 * 0
 * 3
 * 5
 */

那么现在只需要把输出值进行一下正序排序即可:

var output = [];

[{ Z: ["ZERO", 2], W: ["TWO", 4], U: ["FOUR", 6], X: ["SIX", 8], G: ["EIGHT", 0]
},{ O: ["ONE", 3], T: ["THREE", 5], F: ["FIVE", 7], S: ["SEVEN", 9}].map(map => {
    Object.keys(dict).map(key => {
        map[key] && dict[key] > 0 &&
        map[key][0].split("").map(char => dict[char] -= 1) &&
        output.push(map[key][1])
    })
})

/* 
 * 还记得我们把 9 的处理留空了吗?现在要补上啦~
 * 9 的英文 NINE 你只需要随意检查前边过滤后的字典是否还存在 N I E 任意一个字符即可
 * 我选择的是判断 E
 * 输入的9对应的输出应该是1,还记得为什么吗?
 */
//if (dict["E"] && dict["E"] > 0) output.push(1)

/**
 * 2017.09.19 08:36 更新:
 * 之前只判断了是否还存在9,但是忘了多个9同时存在的情况,那么需要做如下改进:
 */
 dist["E"] && // 检查是否还存在特征字符 E,在经过前面的映射关系过滤后,还剩下几个E,就还有几个9
 (output = output.concat(Array(dist["E"]).fill(1))) //纯js技巧,快速生成指定大小的数组并填充一个值

output.sort()
console.log(output) // 0 3 4 5

虽然说本文标题有个 [算法] 前缀,不过这个写法完全没考虑什么复杂度之类的东西 ORZ

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91901.html

相关文章

  • 2017-09-19 前端日报

    摘要:前端日报精选与实现让你的网站秒配证书借助实现元素滚动自动环绕的刘海大型架构设计腾讯大会图文笔记中文翻译种高效缩写法个人文章个节省开发者时间的实用工具库与资源简书通用类和结构与样式分离众成翻译性能调优之调试篇一知乎专栏进阶系列 2017-09-19 前端日报 精选 VirtualDOM与diff(Vue实现)让你的网站秒配 HTTPS 证书借助CSS Shapes实现元素滚动自动环绕iP...

    Leo_chen 评论0 收藏0
  • 求职攻略 | Datawhale助力秋招最强战甲

    摘要:秋招变夏招,还没准备好团队成员收割机牵头,带领名成员历时个月,整理了一份机器学习算法工程师求职面经。但如果之前并没有意识到这一问题也没关系,为你呈现一份小而美的面经。这部分内容包含了逻辑题目及概率题目两方面的内容。 秋招变夏招,还没准备好?Datawhale团队成员offer收割机牵头,带领14名成员历时2个月,整理了一份机器学习算法工程师求职面经:Daily-interview。一份...

    CKJOKER 评论0 收藏0
  • Android-Java面试

    摘要:好不容易在月号这天中午点左右接到了来自阿里的面试电话。这里会不断收集和更新基础相关的面试题,目前已收集题。面试重难点的和的打包过程多线程机制机制系统启动过程,启动过程等等扫清面试障碍最新面试经验分享,此为第一篇,开篇。 2016 年末,腾讯,百度,华为,搜狗和滴滴面试题汇总 2016 年未,腾讯,百度,华为,搜狗和滴滴面试题汇总 各大公司 Java 后端开发面试题总结 各大公司 Jav...

    TalkingData 评论0 收藏0

发表评论

0条评论

ivan_qhz

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<