题目如下:
本题要求你实现一个程序,自动检查你朋友给你发来的信息里有没有 chi1 huo3 guo1
。
输入格式:
输入每行给出一句不超过 80 个字符的、以回车结尾的朋友信息,信息为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。当读到某一行只有一个英文句点 .
时,输入结束,此行不算在朋友信息里。
输出格式:
首先在一行中输出朋友信息的总条数。然后对朋友的每一行信息,检查其中是否包含 chi1 huo3 guo1
,并且统计这样厉害的信息有多少条。在第二行中首先输出第一次出现 chi1 huo3 guo1
的信息是第几条(从 1 开始计数),然后输出这类信息的总条数,其间以一个空格分隔。题目保证输出的所有数字不超过 100。
如果朋友从头到尾都没提 chi1 huo3 guo1
这个关键词,则在第二行输出一个表情 -_-#
。
———————————————————————————————————————————
以下为我自己的思路:
在11/8日晚上的java课上,我学到了String类的一些函数调用,这一题可以通过java中String类的boolean contains函数和boolean equals函数来解。
首先,我们要统计输入行数和判断循环结束,在这一题中,判断结束的标志为单行只输入“.”,在输入不为“.”时,行数计数器countline++,同时用contains函数判断输入的字符串是否有“chi1 huo3 guo1”的子串,若有,且第一次出现,则将countline的值赋值给firstdis,若不是第一次出现,则countdis++,具体代码实现如下:
import java.util.*; import java.util.*;
public class Main
{
public static void main(String[] args) {
String inner;
Scanner reader=new Scanner(System.in);
int countline=0,firstdis=0,countdis=0;
while(reader.nextLine().equals(".")!=true){//判断是否某一行为结束标志“。”,不是则继续循环
countline++;
if(reader.nextLine().contains("chi1 huo3 guo1")){
if(firstdis==0)
firstdis=countline;//记录第一次出现关键词
countdis++;
}
}
System.out.println(countline);
if(countdis==0){
System.out.println("-_-#");
}else{
System.out.print(firstdis+" "+countdis);
}
}
}
运行结果:
结果未输出
在输入结束符号“.”后并未输出结果,在检查并调试代码时,发现java中的reader.nextLine每次调用时都需要重新输入内容,在原本代码的一次循环中输入了两行数据(while里读一行,if里又读一行),且判断是否结束的行(while)与判断是否有关键词的行(if)不是同一行,因此出现了输入结束符但是没有被while内的语句判false的情况,导致不输出结果,就算输出结果,显然结果一定也是错乱的。
debug思路:
为了保证while和if内的字符串为同一串,我们先将reader.nextline的内容赋值给一个具体的字符串变量inner,用inner字符串作为循环判断和关键词判断的条件,为了保证每次循环时inner都读取到内容,使用do.....while句式,debug后的代码如下:
import java.util.*; import java.util.*;
public class Main
{
public static void main(String[] args) {
String inner;
Scanner reader=new Scanner(System.in);
int countline=0,firstdis=0,countdis=0;
/*while(reader.nextLine().equals(".")!=true){//判断是否某一行为结束标志“。”,不是则继续循环
countline++;
/*if(reader.nextLine().contains("chi1 huo3 guo1")){
if(firstdis==0)
firstdis=countline;//记录第一次出现关键词
countdis++;
}*///nextline()不应该再调用一次;
//}
do{
countline++;
inner=reader.nextLine();
if(inner.contains("chi1 huo3 guo1")){
if(firstdis==0){
firstdis=countline;
}
countdis++;
}
}while(inner.equals(".")==false);
System.out.println(countline);
if(countdis==0){
System.out.println("-_-#");
}else{
System.out.print(firstdis+" "+countdis);
}
}
}
测试结果:
结果依旧错误,但判断关键词部分正确
在调试过程中发现,当输入结束符时,由于do.....while句式的特点,countline先自增再判断是否结束,因此结束符的那一行也被算入输入行中,导致了统计输入行数比预期结果多1的情况
debug思路:
将inner赋值放在循环体外面,然后while循环,循环题末尾inner更新下一行内容,以便下一次while判断是否结束输入,具体代码如下:
import java.util.*; import java.util.*;
public class Main
{
public static void main(String[] args) {
String inner;
Scanner reader=new Scanner(System.in);
int countline=0,firstdis=0,countdis=0;
/*while(reader.nextLine().equals(".")!=true){//判断是否某一行为结束标志“。”,不是则继续循环
countline++;
/*if(reader.nextLine().contains("chi1 huo3 guo1")){
if(firstdis==0)
firstdis=countline;//记录第一次出现关键词
countdis++;
}*///nextline()不应该再调用一次;
//}
/*do{
countline++;
inner=reader.nextLine();
if(inner.contains("chi1 huo3 guo1")){
if(firstdis==0){
firstdis=countline;
}
countdis++;
}
}while(inner.equals(".")==false);*///结束符也被算入输入行数
inner=reader.nextLine();
while(inner.equals(".")==false){
countline++;
if(inner.contains("chi1 huo3 guo1")){
if(firstdis==0){
firstdis=countline;
}
countdis++;
}
inner= reader.nextLine();
}
System.out.println(countline);
if(countdis==0){
System.out.println("-_-#");
}else{
System.out.print(firstdis+" "+countdis);
}
}
}
测试结果:
结果正确
PTA验证答案是否通过:
总结:
首先,Scanner读取数据的时候调用一次scanner就需要输入一次数据,每次调用的时候内容是不一样的,如果要将Scanner某次读入的数据多次用于判断,要先将Scanner读到的内容赋值给其他变量。
其次,循环结束的判断条件应该优于循环体,若先进行操作再进行判断,很容易出现已经结束却仍然操作的情况