Poj_1002_java解决

来源:互联网 发布:适合编程的笔记本2017 编辑:程序博客网 时间:2024/06/05 04:24

一、Description

电话号码的标准格式是七位十进制数,并在第三、第四位数字之间有一个连接符。电话拨号盘提供了从字母到数字的映射,映射关系如下:
A, B, 和C 映射到 2
D, E, 和F 映射到 3
G, H, 和I 映射到 4
J, K, 和L 映射到 5
M, N, 和O 映射到 6
P, R, 和S 映射到 7
T, U, 和V 映射到 8
W, X, 和Y 映射到 9
Q和Z没有映射到任何数字,连字符不需要拨号,可以任意添加和删除。 TUT-GLOP的标准格式是888-4567,310-GINO的标准格式是310-4466,3-10-10-10的标准格式是310-1010。 如果两个号码有相同的标准格式,那么他们就是等同的(相同的拨号) 你的公司正在为本地的公司编写一个电话号码薄。

Input

输入的格式是,第一行是一个正整数,指定电话号码薄中号码的数量(最多100000)。余下的每行是一个电话号码。每个电话号码由数字,大写字母(除了Q和Z)以及连接符组成。每个电话号码中只会刚好有7个数字或者字母。

Output

对于每个出现重复的号码产生一行输出,输出是号码的标准格式紧跟一个空格然后是它的重复次数。如果存在多个重复的号码,则按照号码的字典升序输出。如果输入数据中没有重复的号码,输出一行: No duplicates.

二、问题分析

  1. 怎样解决映射关系,把字母转换成数字?
  2. 用什么数据结构存放转换后的数据?
  3. 使得它的内部数据有序,并且易于比较确定重复元素的个数?
  4. 怎样去除“-”字符,并在最后结果中加入?
  5. 用什么数据结构存放结果数据,包含键和值得数据?
  6. 要考虑时间复杂度,不能超时。

三、我的解决思路

  1. 把读入的数据存放到字符串数组中,在依次读取每一个字符串中的字符。这个字符强制转换为整形,再用几个if—else判断AscII码的大小,来确定所表示的数字。
  2. 转换后的数据也是用字符串表示,所以用ArrayList<String>来存放。
  3. 内部有序用到了SetTree()这个中间转换器来转换一下,再把他转换为另一个ArrayList用于比较重复原素。重复元素的比较用了两层循环依次比较。比较耗时。
  4. 连字符的去除和添加用到了字符串的几个操作,substring和replace。
  5. 结果数据本来想用Map来实现的,但还是用StringBuilder来做了一下简单的拼接。这里后来有所改进。
  6. 一开始的时候,总是超时。后来借鉴前辈的经验,改掉了几个循环。详见下面的大神思路。

四、大神思路

  1. 没有用AscII码做转换,而是直接判断字符和数字。再判断数字时,用到了Character.isDigit()(早知道有这个方法可以调用,我就不用AscII码了)。判断字符用if条件判断。
  2. 根本没用什么东西存放转换后的数据,而是直接在一个循环里面一步到位进行后面的操作,节省了时间。
  3. 内部排序用到了TreeMap存储键值对。
  4. 连字符的去除和添加用到了字符串的几个操作,substring和replace。
  5. 最后还是用了Map表示。注意Map添加数据时,如果键相同,则不会重复添加。(我忽略了这点,以为非得要用东西存起来先)。
  6. 只有一个两层循环,时间满足要求。
  7. 先把数据存入到Map里面后,怎样筛选出重复的数据?用到了TreeMap.keySet()方法返回此映射包含的键的 Set 视图。(还有这样的方法,难怪小弟跪了)。
原创粉丝点击