总结卡哥模版 自己学习
Scanner
类位于 java.util
包下。
在Java中,hasNext()
, hasNextLine()
, 和 hasNextInt()
是 Scanner
类的方法,用于检查输入流中是否有下一个元素、下一行字符串或下一个整数。它们之间的区别如下:
-
hasNext()
: 这个方法用于检查输入流中是否还有下一个元素。它不会跳过任何分隔符,只是简单地检查是否还有非空白字符。如果有下一个元素,则返回true
;否则返回false,hasNext()
方法可以跨行使用。 -
hasNextLine()
: 这个方法用于检查输入流中是否还有下一行字符串。它会跳过当前行末尾的换行符,并等待读取下一行。如果有下一行字符串,则返回true
;否则返回false
。 -
hasNextInt()
: 这个方法用于检查输入流中是否还有下一个整数。它会尝试读取下一个令牌并尝试将其解析为整数。如果成功解析,则返回true
;否则返回false
。注意,它不会跳过任何分隔符。
-
nextlnt()
: 读取整数值,如果输入了非整数类型的数据(如浮点数、字符串等),它会尝试将其转换为整数。如果无法转换,则会抛出异常。通常建议在使用nextInt()
之前使用hasNextInt()
方法进行检查,以避免异常情况。 -
nextFloat()
、nextDouble()
: 类似于nextInt()
,但用于读取浮点数值。 -
next()
: 读取输入直到遇到空格或者换行符(包括空格之前的数据),并将光标停留在同一行。 -
nextLine()
: 读取整行输入,包括空格和除了换行符以外的所有字符,然后将光标定位在下一行。
需要注意的是,next()
和 nextLine()
的使用场景有所不同。如果在使用 next()
后立即使用 nextLine()
,可能会出现意料之外的结果,因为 next()
不会读取换行符,而 nextLine()
会读取换行符并将光标移动到下一行。
1.输入包含一系列的a和b对,通过空格隔开。一对a和b占一行。(多行,每行a b)
import java.lang.*;
import java.util.*;
class Main{
public static void main (String[] args) {
/* code */
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int a = sc.nextInt();
int b = sc.nextInt();
// sc.nextLine();
int sum = 0;
sum = a+b;
System.out.println(sum);
}
}
}
2. 多组数据,每组第⼀⾏为n, 之后输⼊n⾏两个整数 (第一行是一个整数N,表示后面会有N行a和b,通过空格隔开。)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int N = in.nextInt();
// System.out.println();
while(N-->0){
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a+b);
}
}
}
}
3. 若⼲⾏输⼊,每⾏输⼊两个整数,遇到特定条件终⽌(输入中每行是一对a和b。其中会有一对是0和0标志着输入结束,且这一对不要计算。)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int a = in.nextInt();
int b = in.nextInt();
if(a==0 && b==0){
break;
}
System.out.println(a+b);
}
}
}
4. 若⼲⾏输⼊,遇到0终⽌,每⾏第⼀个数为N,表示本⾏后⾯ 有N个数(
每行的第一个数N,表示本行后面有N个数。
如果N=0时,表示输入结束,且这一行不要计算。
)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int sum =0;
int N = in.nextInt();
if(N==0){
break;
}
while(N-->0){
int a = in.nextInt();
sum+= a;
}
System.out.println(sum);
}
}
}
5. 若⼲⾏输⼊,每⾏包括两个整数a和b,由空格分隔,每⾏输出 后接⼀个空⾏。(输入包含若干行,每行输入两个整数a和b,由空格分隔。)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a+b);
System.out.println();
}
}
}
6. 多组n⾏数据,每⾏先输⼊⼀个整数N,然后在同⼀⾏内输⼊M个整数,每组输出之间输出⼀个空⾏。(输入的第一行为一个整数N,接下来N行每行先输入一个整数M,然后在同一行内输入M个整数。)
最后一行之后不用输出空行
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int N = in.nextInt();
while(N-- > 0){
int M = in.nextInt();
int sum = 0;
while(M-- >0){
sum += in.nextInt();
}
System.out.println(sum);
if(N>0)System.out.println();
}
}
}
}
7. 多组测试样例,每组输⼊数据为字符串,字符⽤空格分隔,输出 为⼩数点后两位(有多组测试样例。每组输入数据占一行,由一个或多个大写字母组成,字母之间由空格分隔。)
这句输出使用了 String.format()
方法,它的作用是将一个格式化的字符串返回给调用者,而不是直接打印出来。在这个例子中,"%.2f"
是一个格式化字符串,它指定了输出的格式为保留两位小数的浮点数。sum / (double) res.length
表达式计算了平均值,并将结果作为参数传递给 String.format()
方法。最终,System.out.println()
方法将格式化后的字符串打印到控制台上。这种方法使得输出的结果更具可读性,并且按照指定的格式进行了格式化。
import java.util.Scanner;
import java.lang.*;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNextLine()){
String s = in.nextLine();
String [] res = s.split(" ");
double sum=0;
boolean flag = false;
for(String ress :res){
if(ress.equals("A")){
sum +=4.00;
}
else if(ress.equals("B")){
sum +=3.00;
}
else if(ress.equals("C")){
sum +=2.00;
}
else if(ress.equals("D")){
sum +=1.00;
}
else if(ress.equals("F")){
sum +=0.00;
}
else{
System.out.println("Unknown");
flag = true;
break;
}
}
if(!flag){
System.out.println(String.format("%.2f", sum / (double) res.length));
}
}
}
}
8. 多组测试⽤例,第⼀⾏为正整数n, 第⼆⾏为n个正整数,n=0时,结束输⼊,每组输出结果的下⾯都输出⼀个空⾏
(输入包含多组测试样例。每组测试样例包含一个正整数n,表示小明已经堆好的积木堆的个数。
接着下一行是n个正整数,表示每一个积木堆的高度h,每块积木高度为1。其中1<=n<=50,1<=h<=100。
测试数据保证积木总数能被积木堆数整除。
当n=0时,输入结束。
对于每一组数据,输出将积木堆变成相同高度需要移动的最少积木块的数量。
在每组输出结果的下面都输出一个空行。)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
if(n==0)break;
int [] res =new int [n];
int index = 0;
int sum=0;
while(n-- > 0){
res[index++] = in.nextInt();
sum+=res[index-1];
//System.out.println(sum);
}
int result=0;
sum=sum/res.length; //n在变化最后变为-1不能作为求平均值的除数
//System.out.println(sum);
for(int num:res){
if(num > sum ){
// System.out.println(num);
result+=(num-sum);
}
}
System.out.println(result);
System.out.println();
}
}
}
9. 多组测试数据,每组数据只有⼀个整数,对于每组输⼊数据, 输出⼀⾏,每组数据下⽅有⼀个空⾏。(输入数据有多组。每组占一行,只有一个整整数,保证数字在32位整型范围内。
对于每组输入数据,输出一行,每组数据下方有一个空行。)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in =new Scanner(System.in);
while(in.hasNext()){
int res = in.nextInt();
int sum = 0;
while(res > 0){
if((res%10)%2 ==0){
sum += res%10;
}
res = res /10;
}
System.out.println(sum);
System.out.println();
}
}
}
10. 多组测试数据,每个测试实例包括2个整数M,K(2<=K<=M<=1000,M=0,K=0代表输⼊结束。(注意第三组数据「13 3」结果为什么是19呢, 13/3=4,获得4元奖励。 13%3=1,还剩下1元,4+1=5,5元继续参加奖励规则。 5/3=1,获得1元奖励。 5%3=2,剩下2元,1+2=3,3元继续参与奖励规则。 3/3=1,获得1元奖励。 3%3=0,剩下0元,1+0=1。 1元不能参与剩下奖励。所以一共可以使用的天数是 13+4+1+1=19)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int M = in.nextInt();
int K = in.nextInt();
if(M==0 && K==0){
break;
}
int result = M;
while(M < K){
int num1 = M/K;
result += num1;
int num2 = M % k;
M = num1+num2;
}
System.out.println(result);
}
}
}
11. 多组测试数据,⾸先输⼊⼀个整数N,接下来N⾏每⾏输⼊两 个整数a和b, 读取输⼊数据到Map
(输入包含多组测试数据。每组首先输入一个整数N(N<=10),接下来N行,每行输入两个整数a和b,表示a的父亲是b(1<=a,b<=20)。小明的编号为1,小宇的编号为2。
输入数据保证每个人只有一个父亲。
对于每组输入,如果小宇是小明的晚辈,则输出“You are my younger”,如果小宇是小明的长辈,则输出“You are my elder”,如果是同辈则输出“You are my brother”。)
递归处理小明与小宇之间的关系如果找父亲没有找到关联关系
则将其父亲作为基础继续向上寻找。
import java.util.*;
class Main{
public static void main (String[] args) {
Scanner in =new Scanner(System.in);
Map<Integer,Integer> map= new HashMap<>();
while(in.hasNext()){
int N = in.nextInt();
while(N-- >0){
Integer a = in.nextInt();
Integer b = in.nextInt();
map.put(a,b);
}
Integer c1 = 1;
Integer c2 = 2;
while(true){
Integer p1=map.get(c1);
Integer p2=map.get(c2);
if(p1==p2){
System.out.println("You are my brother");
break;
}
else if(map.get(p1)==p2){
System.out.println("You are my elder");
break;
}
else if(map.get(p2)==p1){
System.out.println("You are my younger");
break;
}
else {
c1=p1;
c2=p2;
}
}
}
}
}
12. 多组测试数据。每组输⼊⼀个整数n,输出特定的数字图形
import java.util.Scanner;
class Main{
public static void main (String[] args) {
Scanner in =new Scanner(System.in);
while(in.hasNextInt()){
int num = in.nextInt();
for(int i=1;i<=num;i++){
for(int j=num-i;j>0;j--){
System.out.print(" ");
}
for(int k=1;k<=i;k++){
System.out.print(k);
}
for(int k=i-1;k>0;k--){
System.out.print(k);
}
System.out.println();
}
for(int i=num-1;i>0;i--){
for(int j=num-i;j>0;j--){
System.out.print(" ");
}
for(int k=1;k<=i;k++){
System.out.print(k);
}
for(int k=i-1;k>0;k--){
System.out.print(k);
}
System.out.println();
}
}
}
}
13. 多⾏输⼊,每⾏输⼊为⼀个字符和⼀个整数,遇到特殊字符 结束
(外层嵌套for循环来处理每一行)
镂空三角形每一行输出位置为1(前面全输出为空格,左边界)以及2*i-1(右边界)
在最后一行 i==n 输出2*n-1个字符
*****注意等腰三角形输出的边界条件
import java.util.Scanner;
class Main{
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String s = in.next();
if(s.equals("@"))break;
char c = s.charAt(0);
int n = in.nextInt();
for(int i=1;i<=n;i++){
for(int j=n-i;j>0;j--){
System.out.print(" ");
}
for(int k=1;k<= 2*i-1 ; k++){
if(k==1 || k==2*i-1 || i==n){
System.out.print(c);
}else{
System.out.print(" ");
}
}
System.out.println();
}
System.out.println();
}
/* code */
}
}
14. 第⼀⾏是⼀个整数n,表示⼀共有n组测试数据, 之后输⼊n⾏ 字符串
(输入的第一行是一个整数n,表示一共有n组测试数据。(输入只有一个n,没有多组n的输入)
接下来有n行,每组测试数据占一行,每行有一个词组,每个词组由一个或多个单词组成;每组的单词个数不超过10个,每个单词有一个或多个大写或小写字母组成;
单词长度不超过10,由一个或多个空格分隔这些单词。)
简单来说就只有一个n,然后n组数据,不会循环读取,可以在该组数据处理完成之后直接break来跳出。
Scanner
类的 hasNext()
方法会检查是否有下一个输入项(token)。如果输入流中还有未读取的输入项(包括空格、换行符等),则返回 true
,否则返回 false
。在默认情况下,hasNext()
方法不会读取回车符,它只检查下一个输入项是否存在。
但是,如果你在使用 hasNext()
方法后紧接着调用了 next()
、nextInt()
或类似的方法来读取下一个输入项,而用户输入的是回车符,那么回车符会被这些方法读取。因此,如果你希望避免回车符被读取,可以在读取输入项之后再调用 nextLine()
方法来读取回车符
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
in.nextLine();
for(int i=0;i < n;i++){
String ress = "";
String s = in.nextLine();
String [] res = s.split("\\s+");
for(int j=0;j<res.length;j++){
ress+=res[j].toUpperCase().substring(0,1);
}
System.out.println(ress);
}
break;
}
}
}
15. 第⼀⾏是⼀个整数n,然后是n组数据,每组数据2⾏,每⾏ 为⼀个字符串,为每组数据输出⼀个字符串,每组输出占⼀⾏
(输入数据首先给出一个整数n,表示测试数据的组数。(整个输入中,只有一个n)然后是n组数据,每组数据2行,每行一个字符串,长度大于0,小于50,并且第一个串的长度必为偶数)
import java.util.Scanner;
class Main{
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int m = in.nextInt();
in.nextLine();
for(int i=0;i<m;i++){
String s1 = in.nextLine();
String s2= in.nextLine();
int n = s1.length();
if(n %2 !=0){
continue;
}
String res="";
for(int k=0;k<n/2;k++){
res+=s1.charAt(k);
}
res+=s2;
for(int j=n/2;j<n;j++){
res+=s1.charAt(j);
}
System.out.println(res);
}
break;
}
}
}
16. 多组测试数据,第⼀⾏是⼀个整数n,接下来是n组字符串, 输出字符串
import java.util.Scanner;
class Main{
public static void main (String[] args) {
/* code */
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
in.nextLine();
for(int i=0 ; i<n ; i++){
String s = in.nextLine();
if(s.length() %2 !=0){
System.out.println("字符串长度非偶数");
continue;
}
char [] c = s.toCharArray();
for(int j=0 ; j<s.length();j+=2){
char temp = c[j];
c[j] = c[j+1];
c[j+1] = temp;
}
for(char ch:c){
System.out.print(ch);
}
System.out.println();
}
break;
}
}
}
17. 多组测试数据,每组测试数据的第⼀⾏为整数N(1<=N<=100),当N=0时,输⼊结束,第⼆⾏为N个正整数, 以空格隔开,输出结果为字符串
(输入包含多组测试数据。
每组测试数据的第一行为整数N(1<=N<=100),当N=0时,输入结束。
第二行为N个正整数,以空格隔开,为出栈序列。)
注意模拟出栈行为的方式,在出栈时将元素前面的所有元素加入到栈中,直到变量与需要出栈的元素相同然后才可以出栈,如果说加入栈的元素数量超过原本给的出栈序列长度长则可以直接返回false无法出现这个出栈序列
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
int N = scanner.nextInt();
if (N == 0) break;
int[] sequence = new int[N];
for (int i = 0; i < N; i++) {
sequence[i] = scanner.nextInt();
}
if (isValidPopSequence(N, sequence)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
public static boolean isValidPopSequence(int N, int[] sequence) {
Stack<Integer> stack = new Stack<>();
int currentPush = 1; // 当前要入栈的数
for (int num : sequence) {
// 将要出栈的数之前的数都入栈
while (stack.isEmpty() || stack.peek() != num) {
if (currentPush > N) return false; // 已经入栈完毕,但还有数需要出栈
stack.push(currentPush++);
}
stack.pop(); // 出栈
}
return true;
}
}
18. ⼀组输⼊数据,第⼀⾏为n+1个整数,逆序插⼊n个整数,第 ⼆⾏为⼀个整数m, 接下来有m⾏字符串,并根据字符串内容输 ⼊不同个数的数据
插入时候需要将list长度(size()))加一,不然在空指针时会直接插入失败。
同时内部使用了list的相关方法remove,get,add,foreach遍历
只有一组数据在最后直接break;
import java.util.Scanner ;
import java.util.LinkedList;
class Main{
public static void main (String[] args) {
LinkedList<Integer> list = new LinkedList<>();
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
for(int i=0 ; i<n ;i++){
int num = in.nextInt();
list.addFirst(num);
}
int m = in.nextInt();
for(int j = 0 ; j< m ;j++){
String s = in.next();
if(s.equals("get")){
int a = in.nextInt();
if(a >=1 && a<=list.size()){
System.out.println(list.get(a-1));
}else{
System.out.println("get fail");
}
}
else if(s.equals("delete")){
int a = in.nextInt();
if(a >=1 && a<=list.size()){
list.remove(a-1);
System.out.println("delete OK");
}else{
System.out.println("delete fail");
}
}
else if(s.equals("insert")){
int a = in.nextInt();
int b = in.nextInt();
if(a >=1 && a<=list.size()+1){
list.add(a-1,b);
System.out.println("insert OK");
}else{
System.out.println("insert fail");
}
}
else if(s.equals("show")){
if(list.isEmpty()){
System.out.println("Link list is empty");
}else{
for(int num : list){
System.out.print( num + " ");
}
System.out.println();
}
}
}
break;
}
}
}
19. 多组测试数据,每⾏为n+1个数字, 输出链表或对应的字符 串
翻转时不需要用虚拟头结点
import java.util.*;
class Main {
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int count = sc.nextInt();
if(count == 0) {
System.out.println("list is empty");
break;
}
ListNode dummyNode = new ListNode(0);
ListNode pre = dummyNode;
while(count-- > 0) {
int num = sc.nextInt();
pre.next = new ListNode(num);
pre = pre.next;
}
show(dummyNode.next);
ListNode head = reverse(dummyNode.next);
show(head);
}
}
public static ListNode reverse(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while(cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
public static void show(ListNode head) {
ListNode cur = head;
while(cur != null) {
System.out.print(cur.val);
if(cur.next != null) {
System.out.print(" ");
}
cur = cur.next;
}
System.out.println();
}
}
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
20. 多组输⼊,每组输⼊包含两个字符串,输出字符串
(输入包括多组测试数据,每组测试数据占一行,第一个为大于等于0的整数n,表示该单链表的长度,后面跟着n个整数,表示链表的每一个元素。整数之间用空格隔开
针对每组测试数据,输出包括两行,分别是删除前和删除后的链表元素,用空格隔开
如果链表为空,则只输出一行,list is empty
)
疑问:删除重复元素如果使用两个指针,pre cur同时操作会怎么样?
import java.util.Scanner;
class Main{
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
if(n == 0){
System.out.println("list is empty");
break;
}
ListNode dummynode = new ListNode(0);
ListNode pre = dummynode;
while(n-- >0){
int num = in.nextInt();
pre.next = new ListNode(num);
pre = pre.next;
}
show(dummynode.next);
ListNode head = cancel(dummynode.next);
show(head);
}
}
public static void show(ListNode head) {
ListNode cur = head;
while(cur != null) {
System.out.print(cur.val);
if(cur.next != null) {
System.out.print(" ");
}
cur = cur.next;
}
System.out.println();
}
public static ListNode cancel(ListNode head) {
ListNode cur = head;
while (cur != null && cur.next != null) {
if (cur.val == cur.next.val) {
cur.next = cur.next.next; // 跳过重复节点
} else {
cur = cur.next; // 继续遍历
}
}
return head;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}