ACM-JAVA中使用StreamTokenizer输入纯数字字符串
本文最后更新于:December 8, 2021 pm
积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。
目录
今天做到了一道题,需要读入数字字符串,结果发现用StreamTokenizer不能输入,输出永远都是null。然后就搜了一下,现在整理记录一下。
解决办法
先把解决办法说出来。后面就是讲原理。
1 |
|
大概说一下。两个参数,第二个参数做题时需要写到9。因为不写到9,那么当字符串全是9时,任然会输出null。现在是5,那么输入全是6及其后面数字的字符串就会输出null。还有一点就是,虽然现在只写到了5,但是只要纯数字字符串中有一个在5前面的数字出现,那么5后面的数字也可以出现。也就是,只要在纯数字字符串中出现了范围内的数字,那么再写范围外的数字一样会输出。如下:
1 |
|
只能用于输入字符串,如果在正常输入数字时没有删除(注释),或者是放在输入数字的语句前面,则数字不能正常输入。
前知
ordinaryChar(int ch) - 指定字符在这个tokenizer中保持原义,即只会把当前字符认为普通的字符,不会有其他的语义。
ordinaryChars(int low, int hi) - 指定范围内的字符保持语义,同上
wordChars(int low, int hi) - 字符low与hi之间的所有字符都被当作为单词的要素。 一个单词是由一个单词要素后面跟着0个或者更多个单词要素或者数字要素。
上面的三个方法需要知道,因为后面就需要用到。在这也列一些其他的基本方法,了解就好。
commenChar(int ch) - 指定某个字符为注释字符,此字符之后直到行结尾都被stream tokenizer忽略。
eolIsSignificant(boolean flag) - 决定一个行结束符是否被当作一个基本的符号处理,如果是true,则被当作一个基本符号,不当作普通的分隔符,如果是false,则保持原义,即当作普通的分隔符。
lineno() - 返回当前流所在的行号。
lowerCaseMode(boolean flag) - 决定是否读取一个单词时是否转变成小写。
nextToken() - 分析下一个。
ordinaryChar(int ch) - 指定字符在这个tokenizer中保持原义,即只会把当前字符认为普通的字符,不会有其他的语义。
ordinaryChars(int low, int hi) - 指定范围内的字符保持语义,同上
parseNumbers() - 当stream tokenizer遭遇到一个单词为双精度的浮点数时,会把它当作一个数字,而不是一个单词。
pushBack() - 回退,会引起下一个nextToken方法返回当前值。
quoteChar(int ch) - 指定当前字符为当前tokenizer中的分隔符,在两个符号之间被当作一个字符串解析。
resetSyntax() - 重置语法表使所有的字符都被认为是“ordinary”。
slashSlashComments(boolean flag) - 如果为true,则/与/之间的都被认为是注释,反之,不是。
slashStartComments(boolean flag) - 如果为true,则//之后到行结尾的所有都被认为是注释,反之,不是。
whitespaceChars(int low, int hi) - 字符low与hi之间的所有字符都被当作为空格符,即被认识为tokenzier的分隔符。
wordChars(int low, int hi) - 字符low与hi之间的所有字符都被当作为单词的要素。 一个单词是由一个单词要素后面跟着0个或者更多个单词要素或者数字要素。
源码解释
StreamTokenizer源码和解释:
1 |
|
原因
StreamTokenizer类的使用,这个类的读入非常迅速。但当输入的字符串为数字时,该串不会被读取。原因是,sval读取的是被定界符所包围的单词,单词是由一个单词要素后面跟着0个或者更多个单词要素或者数字要素组成的,而数字不是单词要素。所以我们得先将数字转化为单词要素后再读入。最开始的解决办法就是这么处理的。
拓展
在上面的源码中,要注意区分whitespaceChars和quoteChar,他们两个都是指定分隔符,但是他们两个指定的分隔符是有区别的,whitespaceChars指定的分隔符是空白分隔符。
在用StreamTokenizer做算法题的时候主要就用quoteChar和wordChars两个方法。
quoteChar:用来设置分隔符。
whitespaceChars:用来设置空白分隔符。
wordChars:用来设置单词要素。
指定单词要素
StreamTokenizer默认将/作为注解符,/后面的东西都不会被解析。如果想读取/,就可以直接用
st.wordChars(‘/‘, ‘/‘);
这个方法将/作为一个普通的单词要素,这样/就可以作为一个普通的字符被读取解析了。
如果不想用空格作为分隔符了,也可以用这个方法,这样就可以读入有空的字符串了
st.wordChars(‘ ‘, ‘ ‘);
指定分隔符
如果想设置别的字符作为分隔符,可以使用quoteChar方法来设置
如想让a作为分隔符
st.quoteChar(‘a’);
但是最好还是用
st.whitespaceChars(‘a’, ‘a’);
这个来设置分割符,因为:
使用StreamTokenizer时要注意它默认设置是有很多字符不是单词要素的,所以会读取解析不了,如有需要需要自己用wordChars方法手动设置。我们可以简单的理解为StreamTokenizer只能读取26个英文字母、汉字、数字(只是简单的理解,他其实还可以读入别的字符,只是那些字符在算法题中几乎用不到)。其他的符号都是不可以读入的,需要我们自己用wordChars()方法设置。
本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/ff2ca664.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!