P1914 小书童——凯撒密码(简单的Scanner函数讲解(nextLine()和next()函数))
题目:
蒟蒻虽然忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串(由不超过 50 个小写字母组成)中每个字母向后移动 n 位形成的。z 的下一个字母是 a,如此循环。他现在找到了移动前的原文字符串及 n,请你求出密码。
解题思路:
题目不是很难,但是需要注意一个地方,就是ASCALL码是0-127,如果你要是用s.charAt(i) 来遍历字符串,然后使用 (char)s.charAt(i)+n 来改变字符串中的字符的话,那一定是错的了,肯定会乱码。因为 ‘a’ 的字符编码是97,那么随便一加就会造成溢出了。
所以我们需要这样处理:
int a=(str.charAt(i)-'a'+n)%26+'a';
str.charAt(i)-‘a’+n 的意思是先减去字符 a ,这样他就变成了一个整数,再加上n,此时若是加上字符a 的话,那么它就变成了目标字符了,但是他还是可能会溢出(假如str.charAt(i)-‘a’+n大于26的话),所以我们这时候需要在对它进行取余运算,这样就可以保证他是永远小于等于26的,此时在加上字符a 的话就不会溢出了。
————————————————————————————
本题解题代码:
import java.util.Scanner;
/*蒟蒻虽然忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串
(由不超过 50 个小写字母组成)中每个字母向后移动 n 位形成的。z 的下一个字母是 a,
如此循环。他现在找到了移动前的原文字符串及 n,请你求出密码。*/
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
String str = input.next();
int len = str.length();
for (int i = 0; i < len; i++) {
int a=(str.charAt(i)-'a'+n)%26+'a';
System.out.print((char)a);
//这里会直接进行字符的拼接
}
}
}
————————————————————————————
————————————————————————————
这里有一个新手很容易犯的错误
就是关于Scanner函数的输入问题啊,关于字符串的输入啊,有的人可能就顺着编译器提示的nextLine() 直接就写进去了,然后发现死活输入不了啊
这是因为nextLine()是会读取到你输入的空格符号,就相当于,你上一个输入的是整型,准备回车输入字符串是,突然发现程序突然强制结束了,就像下面这段代码
这里如果是next()而不是nextLine()的话,就可以正常输入了,如最后的代码
Scanner input=new Scanner(System.in);
int a=input.nextInt();
String s=input.nextLine();
System.out.println(a);
System.out.println(s);
输出:
1 //这是输入
1 //这是输出
进程已结束,退出代码为 0
这里大家可以看到啊 我还没开始输入字符串s呢,他就直接输出了,s的输入就被吞了啊
nextLine()方法的结束符只有Enter键,不会过滤输入文字前的空格和其他键值代码的部分截取
—————————————————————————————
这里前面已经输入了一个整型,想要在读取下一个输入的话,那就必须要用空格或者回车来控制下一个s的输入了,不过nextLine()又会捕捉到空格,所以nextLine()就会直接输出它所捕捉到的空格或者回车了,自然就无法在进行后面的字符串输入了
而next()方法在读取输入内容时,会过滤掉有效字符前面的无效字符,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其过滤掉;只有在读取到有效字符之后
——————————————————————
虽然说next()很好用啊,但是也是会出现问题,让我们来看下面这段代码
//输入
Scanner input=new Scanner(System.in);
String s1=input.nextLine();
String s2=input.next();
System.out.println(s1);
System.out.println(s2);
// A code block
var foo = 'bar';
输出:
aa bb cc //输入
aa bb cc //输入
aa bb cc //输出
aa //输出
进程已结束,退出代码为 0
这里我们看到啊同样的输入,但是后面的next()的输出bb cc却被吞了,这里就是因为next()方法读取到空白符就结束l
总结一下啊
next()方法读取到空白符就结束l;
nextLine()读取到回车结束也就是“\r”;