华为机试_在线编程_牛客网
1.字符串最后一个单词的长度
描述
对于给定的若干个单词组成的句子,每个单词均由大小写字母混合构成,单词间使用单个空格分隔。输出最后一个单词的长度。
输入描述:
在一行上输入若干个字符串,每个字符串代表一个单词,组成给定的句子。
除此之外,保证每个单词非空,由大小写字母混合构成,且总字符长度不超过 103103 。输出描述:
在一行上输出一个整数,代表最后一个单词的长度。
示例1
输入:
HelloNowcoder复制输出:
13复制说明:
在这个样例中,最后一个单词是 "HelloNowcoder""HelloNowcoder" ,长度为 1313 。示例2
输入:
A B C D复制输出:
1
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别String line = in.nextLine();//hasNext 判断是否还有内容 用于无长度输入//nextLine 获取一行StringString[] words = line.split(" "); //以空格分隔String last = words[words.length - 1 ];System.out.println(last.length());}
}
2.HJ2 计算某字符出现次数
描述
对于给定的由大小写字母、数字和空格混合构成的字符串 s ,统计字符 c 在其中出现的次数。具体来说:
∙ ∙若 c 为大写或者小写字母,统计其大小写形态出现的次数和;
∙ ∙若 c 为数字,统计其出现的次数。
保证字符 c 仅为大小写字母或数字。输入描述:
第一行输入一个长度 1≦length(s)≦1031≦length(s)≦103 ,由大小写字母、数字和空格混合构成的字符串 s 。保证首尾不为空格。
第二行输入一个字符 c ,代表需要统计的字符。输出描述:
在一行上输出一个整数,代表字符 c 在字符串 s 中出现的次数。
示例1
输入:
HELLONowcoder123 o复制输出:
3复制说明:
由于 o 为小写字母,因此统计其小写形态出现的次数和,即 33 。示例2
输入:
H E L L O Nowcoder123 1复制输出:
1
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String s = in.nextLine();String a = in.nextLine();//临时char c = 0;if(a.trim().isEmpty()){//判断第二行是否为空格System.out.println("error");return;}c = a.charAt(0);int count = 0;if(Character.isLetter(c)){//判断字母for(char ch : s.toCharArray()){if(Character.toLowerCase(c) == Character.toLowerCase(ch)) count++;//转小写统计字母数}System.out.println(count);return;}if(Character.isDigit(c)){//判断数字for(char ch : s.toCharArray()){if(c == ch) count++;}System.out.println(count);return;}System.out.println("error");}
}
Tips
hasNext()
用途:检查是否有更多的“单词”或“部分”可以读取。
怎么工作的:它会跳过空格、换行符等空白字符,找到下一个完整的“单词”或“部分”。这里的“单词”是指由空格或其他分隔符分开的文本片段。
适用场景:当你想逐个读取输入中的单词或特定分隔符分隔的部分时使用。比如,从一个句子中逐个读出单词。hasNextLine()
用途:检查是否还有完整的行可以读取。
怎么工作的:它根据换行符(按下回车键产生的)来判断一行的结束。每次调用都会读取直到遇到换行符为止的所有内容作为一个整体。适用场景:当你想逐行读取输入时使用。例如,从一篇文章或者用户输入的多行文本中一行一行地读取内容。
简单例子
假设输入是:
Hello World
How are you?使用 hasNext() 和 next(),你会依次得到 "Hello" 和 "World" 作为两个独立的读取结果,然后是 "How", "are", "you?"。
使用 hasNextLine() 和 nextLine(),你会首先得到 "Hello World" 作为一个整体,然后是 "How are you?",每个都是单独的一次读取结果。每次调用
nextLine()
都会消耗掉输入流中的当前行,并将扫描器的内部指针移动到下一行。因此,随着每一行被读取和处理,程序能够继续检查并处理后续的行,直到所有输入都被读取完毕。当没有更多的行可供读取时(比如达到文件末尾或输入流关闭),hasNextLine()
将返回false
,循环结束。
3.明明的随机数
描述
对于明明生成的 n 个 11 到 500 之间的随机整数,你需要帮助他完成以下任务:
∙ ∙删去重复的数字,即相同的数字只保留一个,把其余相同的数去掉;
∙ ∙然后再把这些数从小到大排序,按照排好的顺序输出。
你只需要输出最终的排序结果。输入描述:
第一行输入一个整数 n (1≦n≦1000),代表明明生成的数字个数。
此后 n 行,第 i 行输入一个整数ai (1≦ai≦500),代表明明生成的随机整数。输出描述:
输出若干行,每行输出一个整数,代表输入数据排序后的结果。第一行输出最小的数字。
示例1
输入:
3
2
2
1复制输出:
1
2
1.使用TreeSet自动排序并去重
import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();// 读取n值Set<Integer> numbers = new TreeSet<>();// 使用TreeSet自动排序并去重// 循环读取n个数for (int i = 0; i < n; i++) {int num = scanner.nextInt();if(num >= 1 && num <= 500) { // 确保数字在指定范围内numbers.add(num);}}// 输出排序后的结果for (Integer number : numbers) {System.out.println(number);}}
}
2.只用数组
错误的去重手法,不应该直接在原数组上进行判断,应该先判断有多少重复的个数,然后以该数创建数组,数组固定大小
//去重
int uniqueIndex = 0;
int[] uniqueNumbers = new int[n];
for(int i = 0;i < n;i++){//i=3
boolean isUnique = true;
for(int j = 0;j < i ;j++){//j=0 1 2 分别和i的下标数组数判别
if(numbers[i] == numbers[j]){//如果相同 该i处存在重复 标记
isUnique = false;
break;
}
}
if(isUnique){//如果是真就将该值放入数组
numbers[uniqueIndex++] = numbers[i];
}
}
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();// 读取n值int[] numbers = new int[n];for(int i=0;i<n;i++){//循环取值放到数组内numbers[i] = scanner.nextInt();}//去重//1.计算重复个数 用索引当作数int uniqueCount = 0;boolean[] adds = new boolean[500];for(int num : numbers){if(!adds[num]){adds[num] = true;uniqueCount++;}}//2.进行数组去重int[] uniqueNumbers = new int[uniqueCount];int uniqueIndex = 0;for(int i = 0;i < n;i++){//i=3boolean isUnique = true;for(int j = 0;j < i ;j++){//j=0 1 2 分别和i的下标数组数判别if(numbers[i] == numbers[j]){//如果相同 该i处存在重复 标记isUnique = false;break;}}if(isUnique){//如果是真就将该值放入数组uniqueNumbers[uniqueIndex++] = numbers[i];}}//排序for(int i = 0;i < uniqueCount - 1;i++){for(int j = 0;j < uniqueCount - i - 1;j++){if(uniqueNumbers[j] > uniqueNumbers[j+1]){int temp = uniqueNumbers[j];uniqueNumbers[j] = uniqueNumbers[j + 1];uniqueNumbers[j + 1] = temp;}}}// 输出排序后的结果for(int num:uniqueNumbers){System.out.println(num);}}
}
4.字符串分隔
描述
对于给定的由小写字母和数字混合构成的字符串 s ,你需要按每 8 个字符换一行的方式书写它,具体地:
∙ ∙书写前 8 个字符,换行;
∙ ∙书写接下来的 8 个字符,换行;
∙ ∙……
∙ ∙重复上述过程,直到字符串被完全书写。
特别地,如果最后一行不满 8 个字符,则需要在字符串末尾补充 0 ,直到长度为 8 。输入描述:
在一行上输入一个长度 1≦length(s)≦100 ,由小写字母和数字混合构成的字符串 s 。
输出描述:
输出若干行,每行输出 8 个字符,代表按题意书写的结果。
示例1
输入:
hellonowcoder
复制输出:
hellonow
coder000复制说明:
在这个样例中,字符串长度为 1313 ,因此需要在第二行末尾补充 33 个 00 。
示例2
输入:
0
复制输出:
00000000
不使用StringBuilder 只用char和String完成
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别String sentence = in.nextLine();int count = 1;int perLineCount = 8;//一行个数for(char ch:sentence.toCharArray()){System.out.print(ch);count++;if(count > perLineCount){System.out.print("\n");count = 1;}}int remainder = sentence.length()%8;if(remainder != 0){for(int i = 0;i < perLineCount - remainder;i++)System.out.print("0");}//System.out.println(in.nextLine());}
}
使用StringBuilder
substring(i,i+8) 从i开始(包含i)到i+8结束(不包含i+8)
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String s = scanner.nextLine();// 处理字符串,每8个字符一组int lineCount = 8;for (int i = 0; i < s.length(); i += lineCount) {if (i + lineCount <= s.length()) {// 如果剩余字符大于等于8,则直接打印8个字符System.out.println(s.substring(i, i + lineCount));} else {// 如果剩余字符少于8个,则补充0直到达到8个字符//构造器构造StringBuilder substring从i分割到最后 构造最后一行StringBuilder sb = new StringBuilder(s.substring(i));while (sb.length() < lineCount) {//循环添加直到最后一行=8sb.append('0');}System.out.println(sb.toString());}}}
}
5.进制转换
描述
对于给定的十六进制数,输出其对应的十进制表示。
在本题中,十六进制数的格式为:0x 开头,后跟若干个十六进制数字( 0-9 和 A-F )。其中,A-F 依次代表 10−15 。输入描述:
在一行上输入一个十六进制数 s ,代表待转换的十六进制数。
保证 s 转化得到的十进制数 x 的范围为 1≦x≦231−1 。输出描述:
在一行上输出一个整数,代表 s 对应的十进制数。
示例1
输入:
0xFA93
复制输出:
64147
复制说明:
回忆十六进制转化为十进制的方法:从右往左,将第 i 位乘以 16i ,然后求和。
在这个样例中,0xFA930xFA93 的第 0 位是 3 ,第 1 位是 9 ,第 2 位是 A ,第 3 位是 F ,因此 0xFA93=3×160+9×161+10×162+15×163=64147 。
1.手动计算
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String str = in.next();char[] chars = str.toCharArray();int res = 0,x;for(int i = 2; i < chars.length; i++){//第一第二位0 1 代表6进制 不参与计算char c = chars[i];if(c >= 'A' && c <= 'F' ){//计算ASC码差值x = c - 'A' + 10;//手动转成十进制 例c=F A = 10 F-A=15-10=5}else{x = c - '0';}res = res * 16 + x;//每次迭代中,当前的结果都会乘以16(这是因为每向左移动一位,它的权重就增加16倍),然后加上新转换得到的十进制值x。这样,随着循环的进行,程序逐步构建出完整的十进制数值。}System.out.println(res);}
}
2.使用Interger.parseInt
substring方法
定义:
substring(int beginIndex, int endIndex)
或者substring(int beginIndex)
功能:从原始字符串中截取出一个新的字符串。
当使用一个参数时,
substring(int beginIndex)
提取从索引beginIndex
开始到字符串末尾的所有字符组成的子串。当使用两个参数时,
substring(int beginIndex, int endIndex)
提取从beginIndex
到endIndex-1
索引之间的所有字符组成的子串。在你的例子中,
hex.substring(2)
会从输入的十六进制字符串hex
中提取从索引2开始到字符串结尾的部分,从而去掉表示十六进制数的前缀"0x"。Integer.parseInt方法
定义:
Integer.parseInt(String s, int radix)
功能:将字符串
s
解析为一个按照指定基数radix
表示的整数。
在这个例子中,
radix
设置为16,意味着解析的字符串是一个十六进制数。
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String hex = scanner.nextLine(); // 读取输入// 转换并输出结果int decimal = Integer.parseInt(hex.substring(2), 16); // 去掉"0x"前缀System.out.println(decimal);}
}
6.质数因子
需要除2 除奇数
描述
对于给定的整数 n ,从小到大依次输出它的全部质因子。即找到这样的质数 1,2,⋯ p1,p2,⋯,pk ,使得 n=p1×p2×⋯×pk 。
输入描述:
在一行上输入一个整数n(2≦n≦2×108+14) 代表待分解的整数。
输出描述:
在一行上从小到大输出若干个整数,代表 n 的质因子。
示例1
输入:
180
复制输出:
2 2 3 3 5
复制说明:
在这个样例中 180=2×2×3×3×5 。
示例2
输入:
47
复制输出:
47
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt(); // 读取输入的整数while (n % 2 == 0) {System.out.print(2);System.out.print(" "); // 添加空格分隔符n /= 2;}// 检查奇数是否为因子,从3开始,直到sqrt(n)for (int i = 3; i <= Math.sqrt(n); i += 2) {while (n % i == 0) {System.out.print(i);System.out.print(" "); // 添加空格分隔符n /= i;}}// 如果处理完 n是一个大于2的质数if (n > 2) {System.out.print(n);System.out.print(" "); // 添加空格分隔符}}
}
7.取近似值(Math.round)
描述
对于给定的正实数 x ,输出其四舍五入后的整数。更具体地说,若 x 的小数部分大于等于 0.50.5 ,则输出向上取整后的整数;否则输出向下取整后的整数。
输入描述:
在一行上输入一个小数点后位数不超过 55 位的实数x (0.00001≦x≦20) 。
输出描述:
在一行上输出一个整数,代表 x 四舍五入后的结果。
示例1
输入:
5.5
复制输出:
6
复制说明:
在这个样例中,5.5 的小数部分大于等于 0.5 ,因此输出向上取整后的整数 66 。
示例2
输入:
2.499
复制输出:
2
复制说明:
在这个样例中,2.499 的小数部分小于 0.5 ,因此输出向下取整后的整数 22 。
对于四舍五入 Math提供round方法自动四舍五入 ceil向上取整 floor向下取整
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);double num = in.nextDouble();long num1 = Math.round(num);//使用Math.round自动四舍五入System.out.println(num1);}
}
8.合并表记录(TreeMap)
描述
数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,随后按照索引值的大小从小到大依次输出。
输入描述:
第一行输入一个整数 n(1≦n≦500) 代表数据表的记录数。
此后 n 行,第 行输入两个整数 xi,yi(0≦xi≦11111111; 1≦yi≦105) 代表数据表的第 i 条记录。输出描述:
输出若干行,第 i 行输出两个整数,代表合并后数据表中第 i 条记录的索引和数值。
示例1
输入:
4
0 1
0 2
1 2
3 4复制输出:
0 3
1 2
3 4复制说明:
在这个样例中,第 1,3 条记录索引相同,合并数值为 1+2=3 。
示例2
输入:
2
0 1
0 1复制输出:
0 2
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt();// 使用 TreeMap 自动排序并存储索引和对应的数值总和Map<Integer, Integer> map = new TreeMap<>();for (int i = 0; i < n; i++) {int index = in.nextInt();//读取下一个有效的 int 值int value = in.nextInt();// 如果该索引已存在,则加上当前值;否则添加新索引和值map.put(index, map.getOrDefault(index, 0) + value);//1.如果存在put 方法会用新的值 value 替换旧的值,并返回被替换的旧值。//2.map.getOrDefault(index, 0) 如果index的value不存在默认返回0 存在返回value的值}// 遍历 TreeMap 输出结果for (Map.Entry<Integer, Integer> entry : map.entrySet()) {//注意指定数据类型System.out.println(entry.getKey() + " " + entry.getValue());}}
}
9.提取不重复的整数
描述
对于给定的正整数 n ,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
输入描述:
在一行上输入一个正整数 n(1≦n≦108) 代表给定的整数。
保证 n 的最后一位不为 0 。输出描述:
在一行上输出一个整数,代表处理后的数字。
示例1
输入:
9876673
复制输出:
37689
复制说明:
在这个样例中,先将数字倒序,得到 3766789 ,然后去除重复数字,得到 37689 。
示例2
输入:
12345678
复制输出:
87654321
1.使用字符串StringBuild和去重HashSet
import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// System.out.println("请输入要反转的数字:");String number = sc.nextLine();Set<Character> characters = new HashSet<>();StringBuilder sb = new StringBuilder();for (int i = number.length() - 1; i >= 0 ; i--) {Character ch = number.charAt(i);if (!characters.contains(ch)) {characters.add(ch);sb.append(ch);}}System.out.println(sb.toString());}
}
2.使用ArrayList进行倒序读取 LinkedHashSet(保留顺序)去重
import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);long n = in.nextLong();List<Long> list = new ArrayList<>();//使用ArrayList//按照权重从右往左取值while(n > 0){long digit = n % 10;//余数 也就是最后一个数list.add(digit);n /= 10;//去掉最后一位 385/10 = 38 直接舍去了小数部分}//使用hashSet去重Set<Long> unique = new LinkedHashSet<>(list);for(long out:unique){System.out.print(out);}}
}
10.字符个数统计
描述
对于给定的字符串,统计其中的 ASCII 在 0 到 127 范围内的不同字符的个数。
备注:受限于输入,本题实际输入字符集为 ASCII 码在 33 到 126 范围内的可见字符。您可以参阅下表获得其详细信息(您可能关注的内容是,这其中不包含空格、换行)。输入描述:
在一行上输入一个长度 1≦length(s)≦500 的字符串 s ,代表给定的字符串。
输出描述:
在一行上输出一个整数,代表给定字符串中 ASCII 在 00 到 127 范围内的不同字符的个数。
示例1
输入:
[@A8aA].0
复制输出:
8
import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String sentence = in.nextLine();Set<Character> set = new HashSet<>();//使用hashset去重for(char ch:sentence.toCharArray()){if(ch < 126 && ch > 0 ){set.add(ch);}}System.out.print(set.size());//输出set大小即为不重复字符个数}
}