一、自定义底层算法
public static boolean isSeparator(char ch) {
return (ch==' ' || ch==',' || ch=='.' || ch=='\n'
|| ch=='!' || ch=='?' || ch==';');
}
public static void culculateArticle(String str) {
int i, n1, n2, n3;
n1 = n2 = n3 = 0;
for(i=0; i<str.length(); i++)
if(i==0 || MyToolkit.isSeparator(str.charAt(i-1)))
if(str.charAt(i)=='a' || str.charAt(i)=='A')
{
i++;
if(MyToolkit.isSeparator(str.charAt(i)))
{
n1++;
}
else if(str.charAt(i)=='n' || str.charAt(i)=='N')
{
i++;
if(MyToolkit.isSeparator(str.charAt(i)))
{
n2++;
}
}
else if(str.charAt(i)=='t' || str.charAt(i)=='T')
{
i++;
if(str.charAt(i)=='h' || str.charAt(i)=='H')
{
i++;
if(str.charAt(i)=='e' || str.charAt(i)=='E')
{
i++;
if(MyToolkit.isSeparator(str.charAt(i)))
n3++;
}
}
}
System.out.println("a:"+n1+",an:"+n2+",the:"+n3);
}
算法很简单,仅仅使用了遍历。str.charAt(i)即str[i],i指示当前元素。在确定一个冠词之前,要判断当前字符的前一个字符是分隔符,或者当前字符是第一个字符。确定一个词是冠词,要确定前几个词是"a"或"an"或"the",最后一个字符是分隔符。
二、使用StringTokenizer类解析字符串
public static void culculateArticle(String str, String delimit) {
StringTokenizer st = new StringTokenizer(str, delimit);
Map<String, Integer> m = new HashMap<>();
m.put("a", 0);
m.put("an", 0);
m.put("the", 0);
String s;
while (st.hasMoreTokens()) {
s = st.nextToken();
if (s.equalsIgnoreCase("a")) {
m.put("a", m.get("a") + 1);
}
if (s.equalsIgnoreCase("an")) {
m.put("an", m.get("an") + 1);
}
if (s.equalsIgnoreCase("the")) {
m.put("the", m.get("the") + 1);
}
}
System.out.println(m);
}
这是课堂上老师讲的方法,StringTokenizer构造原型为:
StringTokenizer(String str);
StringTokenizer(String str, String delim);
StringTokenizer(String str, String delim, boolean returnDelims);
delimit的意思是分隔符,StringTokenizer st = new StringTokenizer(str, delimit);执行后对象st保存解析后的字符串。由st.hasMoreToken()的返回值可以判断是否还有下一个Token,st.nextToken()返回下一个Token。这里,Token指的是解析后的每一个单词。
Map代表映射,HashMap是哈希映射。Map<String,Integer> m = new HashMap<>();这种写法是为了仿照JAVA程设中的习惯,即:用派生类初始化基类。<>是泛型的知识。Map表示键到值的映射。
m.put("a", 0);等语句来设定映射的值,m.put("a", m.get("a")+1);可以更新映射的值。
三、我的个人总结
自行设计算法是初学者学习程序设计的基本要求,不过学习并熟练使用JAVA提供的类库是时势所趋,这种学习依赖大量的练习、不断的积累。