HDACM 1029
关于这一题,我们要认识一下:
java.io.StreamTokenizer
因为按习惯是采用
Scanner sc = new Scanner(System.in)
这种方式去从控制台接收参数的,但是对于百万数据来说,采用这个函数来接收速度是远远不够的。
那么开始认识 StreamTokenizer类
StreamTokenizer
类获取输入流并将其解析为“标记”,允许一次读取一个标记。解析过程由一个表和许多可以设置为各种状态的标志控制。该流的标记生成器可以识别标识符、数字、引用的字符串和各种注释样式。
从输入流读取的每个字节都被视为一个字符,范围在 '\u0000'
到 '\u00FF'
之间。字符值用于查找该字符的五个可能属性:空白、字母、数字、字符串引号 和注释字符。每个字符都可以有零个或多个这样的属性。
另外,一个实例还有四个标志。这些标志指示:
- 行结束符是作为标记返回,还是被视为仅用于分隔标记的空白。
- 是标识还是跳过 C 样式注释。
- 是标识还是跳过 C++ 样式注释。
- 是否将标识符的字符转换为小写字母。
典型的应用程序首先构造此类的一个实例,建立一个语法表,然后重复循环,调用该循环的每个迭代中的 nextToken
方法,直到返回值TT_EOF
。
常用方法:
double navl ——> 如果当前标记是一个数字,则此字段将包含该数字的值。
String sval ——> 如果当前标记是一个文字标记,则此字段包含一个给出该文字标记的字符的字符串。
static int TT_EOF ——>指示已读到流末尾的常量。
static int TT_EOL ——->指示已读到行末尾的常量。
static int TT_NUMBER——->指示已读到一个数字标记的常量。
static int TT_WORD ——-> 指示已读到一个文字标记的常量。
int ttype ——–> 在调用 nextToken() 方法之后,此字段将包含刚读取的标记的类型。
想更深入的了解StreamTokenizer类可以查看API 或者百度相关知识。
对了,我还采用了MAP集合来存储数据,因为题目题意是求众数,所以采用map集合来做,map集合的原理是一个key值对应一个value值,在同一个map集合中每个key值都是唯一的。所有每当输入一个数时,把输入的数当做key值,然后调用get函数获取其value值,如果为null 则说明这个数时第一个数,否则就把value值+1,在把键值对放入map集合中,这样就可以了。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.HashMap;
import java.util.Map;public class Main {public static void main(String[] args) {StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));try {while(in.nextToken() != StreamTokenizer.TT_EOF){int n = (int)in.nval;int max = 0;int ans = 0;Map<Integer, Integer> map = new HashMap<Integer, Integer>();for (int i = 0; i < n; i++) {in.nextToken();int num = (int)in.nval;if (map.get(num)==null) {map.put(num, 1);continue;}int value = map.get(num)+1;if (max<value) {max = value;ans = num;}map.put(num, value);}System.out.println(ans);}} catch (IOException e) {e.printStackTrace();}}
}