ACM
中对编程语言的感悟
04
级四班 张 祥
对于任何一个编程的人来讲
,
选择一门适合自己的语言都可以用一句话来形容
-----
磨刀不误砍柴工
,
更有一句工欲善其事必先利其器
,
选择了一门适当的语言还得要深刻理解并灵活运用它的特点。
我们这次参加比赛使用的是
Java
语言。按照常理讲,一般的真正的
ACM
高手至少会撑握两到三门语言,比如说
C
语言和
Java
,
C
语言大家都知道,它更接近于机器语言,程序执行起来更快一些,而
Java
的编程与实现更简单,对于很多问题都有现成的数据结构和算法。
由于我自己对
JAVA
稍微熟悉一些,就谈谈
ACM
中
JAVA
的使用吧。对于其它的语言在这里就不多说了。
正如前面所说的,许多问题
JAVA
中都已经有了现成的数据结构和算法。首先看看大数运算方面的问题,
JAVA
中有两个类,
BigInteger
和
BigDecimal
,两个用字符串实现的大整数和大十进制类,它们可以处理任意长度和精度的整数与十进制数,其中的有许多方法高效实现了大整数与大十进制数的各种运算,对于
BigDecimal
还可以设置精度。对于一些大数运算问题就可以直接使用,非常实用。
接下来就是要灵活运用的就是
Java
自身的数据结构类了,包括
collection
接口里的实现类和子类,另外还有
Map
映射抽象类及子类等。在
ACM
中
TreeSet
和
TreeMap
是两个最常用的数据结构类,
TreeSet
和
TreeMap
都能够实现其内容自然排序,
Set
不允许其中的元素重复,
Map
能实现键到值的映射。这两个类配合泛型的使用,使用起来将十分方便和有用。
Arrays
是
JAVA
中的数组排序类,可以实现到
Object
类数组的快速排序,并且还可以进行二分查找,当然在使用二分查找的时候肯定是要先排序的啦。
JAVA
中实现数据的输入也非常方便,一般有两种方式,文件输入和标准控制台输入;输出同样有两种,文件输出和标准控制台输出。我们参加的这次比赛就是文件输入和标准控制台输出。对于
Java5
和
JDK1.4
的输入也有少许差别,
Java5
有一个简单的
Scanner
类,对于少量的数据输入建议使用
Scanner
类,而对于大量数据输入的话还是建议采用
BufferedReader
类,对于
JDK1.4
就只有全部使用
BufferedReader
了。输出的话,一定要把
File ,FilerWrite,PrintWrite
三个类的细节搞清楚。这里也不多讲,列出这几个输放输出的具体使用实例吧:
输入:
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
BufferedReader input = new BufferedReader(new FileReader(“1.txt”));
Scanner input = new Scanner(System.in) ;
输出:
System.out.println();
System.out.printf();
System.out.print()
PrintWrite output = new PrintWrite(new FileWrite(“1.txt”));
在处理输入与输出的时候也常常很讲究技巧性,尤其是在
ACM
这样很讲究编程技巧性的编程比赛中显得更为突出。
ACM
中还会经常遇到字符串的处理方面的问题:
StringBuffer
和
StringBuilder
这两个类有很多用用的方法可供使用,然后大家还可以注意一下
String
类和
StringBuffer
类的区别和特点,对于要进行大量变化的字符串处理建议使用
StringBuffer
类,而不是经常变化的字符串建议使用
String
类,它们特点取决于
Java
中对
String
和
StringBuffer
的内存分配不相同的原因了。大家可以编写一些测试程序来测试一下它们的特点和区别。另外字符串处理中经常可能要用到的是另外一个知识了,那就是正则表达式了,如果能够很好的撑握正则表达式的用法,那么字符串处理可以说你已经完成一半的任务了。如果正则表达式没有完全撑握,
StringBuilder
就是它的一个替代品。另外
StringTokenizer
也是一个很有用的工具,在这里就不多谈了,大家可以编几个测试类多试试。
格式化处理,一方面
Java5
之后就已经有了一个
printf
()方法,它跟
C
语言里的格式化输出有相同的功能和用法。另外
java.text.Format
类及其子类有更丰富的方法与功能,大家可以查看一下它的
API
文档。
下面是我们写的一些测试程序
,
大家可以参考一下
//StringBuffer
方法测试
import
java.lang.StringBuffer;
public
class
StringBufferTest {
public
static
void
main(String[] args) {
StringBuffer str =
new
StringBuffer(
"abc"
);
StringBuffer str2 = str;
str = str2.append(str.reverse());
System.
out
.println(str);
//cbacba
str.insert(1,
"aaaaaa"
);
System.
out
.println(str);
//caaaaaabacba
System.
out
.println(str.charAt(1));
//a
System.
out
.println(str.lastIndexOf(
"ba"
));
//10
}
}
//BufferedReader
方法测试
import
java.io.BufferedReader;
import
java.io.IOException;
import
java.io.InputStreamReader;
public
class
BufferedReaderTest {
public
static
void
main(String[] args) {
BufferedReader buff =
new
BufferedReader(
new
InputStreamReader(System.
in
));
String test;
StringBuffer stringBuff =
new
StringBuffer();
try
{
while
(!(test = buff.readLine()).equals(
""
)){
stringBuff.append(test);
}
}
catch
(IOException e) {
e.printStackTrace();
}
System.
out
.println(stringBuff);
}
}
//Map TreeMap
方法测试
import
java.util.*;
public
class
TreeMapTest {
public
static
void
main(String[] args){
TreeMap<String, Integer> map =
new
TreeMap<String, Integer>();
map.put(
"1L"
, 20);
map.put(
"2LR"
, 30);
map.put(
"1R"
,100);
map.put(
"3LLL"
, 20);
map.put(
"3LLR"
,20);
map.put(
"2LL"
, 22);
map.put(
"2LL"
, 20);
System.
out
.println(
"Key
的长度
:"
+map.size());
System.
out
.println(
"Key
的长度
:"
+map.keySet().size());
System.
out
.println(
"map.get():"
+map.get(
"1L"
));
Map newMap = map.tailMap(
"2LL"
);
System.
out
.println(newMap.toString());
System.
out
.println(map.toString());
System.
out
.println(map.subMap(
"1L"
,
"2RR"
).toString());
//{1L=20, 1R=100, 2LL=20, 2LR=30}
while
(!map.isEmpty())
System.
out
.println(map.remove(map.firstKey()));
}
}
//printf()
测试
public
class
Test4 {
public
static
void
main(String[] args){
int
[][] a={{1,2},{2,2,2,3},{3}};
Object[] arg =
new
Object[]{
"Hello"
,
"world"
};
Object[] c =
new
Object[]{3,2,1};
int
[] d={1,1,1};
// System.out.printf("%d %d %d/n",(Object)d);
System.
out
.printf(
"{%s %s %s}/n"
,1,2,3);
System.
out
.printf(
"%d %d %d/n"
,c);
System.
out
.printf(
"%s/n"
,
"Hello"
,
"world"
);
System.
out
.printf(
"%s %s/n"
, arg);
System.
out
.printf(
"%s/n"
,
new
Object[]{arg});
System.
out
.printf(
"%s/n"
,(Object)arg);
assert
false
:1;
}
}
//文件读写,在一个"CRC校验"
题中用到的
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Number6 {
public static void main(String[] args) throws IOException {
BufferedReader input = new BufferedReader(new FileReader("in2_6.txt"));
PrintWriter output = new PrintWriter(new FileWriter("out2_6.txt",true));
String s = input.readLine(),rs;
while(!(s==null || s.equals("#"))){
int t = 0,crc = 0;
for(int i=0;i<s.length();i++){
t = (t*256+s.charAt(i))%34943;
}
crc = (34943-(t<<16)%34943)%34943;
rs = Integer.toHexString(crc).toUpperCase();
while(rs.length()<4)rs = 0+rs;
output.println(rs);
s = input.readLine();
}
output.close();
}
}
总的来讲
,
做
ACM
题
,
最重要的是要对语言的语法特性及细节问题多测试
,
试了才知道效果。要想在比赛中取得好成绩,就必须多做题,做题是唯一的王道。