全网最全面的华为OD机试真题汇总,100%原题题库,不需要开会员即可查看全部内容,更多考题请查看真题库。
真题库:https://www.yuque.com/codernav.com/od
题目:去除多余空格
知识点字符串数组队列
时间限制:2s 空间限制:256MB 限定语言:不限
题目描述:
去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。

条件约束:
1,不考虑关键词起始和结束位置为空格的场景;
2,单词的的开始和结束下标保证涵盖一个完整的单词,即一个坐标对开始和结束下标之间不会有多余的空格;
3,如果有单引号,则用例保证单引号成对出现;
4,关键词可能会重复;
5,文本字符长度length取值范围:[0, 100000];
输入描述:
输入为两行字符串:
第一行:待去除多余空格的文本,用例保证如果有单引号,则单引号成对出现,且单引号可能有多对。
第二行:关键词的开始和结束坐标,关键词间以逗号区分,关键词内的开始和结束位置以单空格区分。
例如:
Life is painting a picture, not doing ‘a sum’.
8 15,20 26,43 45
关键单词为:painting picture sum
输出描述:
输出为两行字符串:
第一行:去除多余空格后的文本
第二行:去除多余空格后的关键词的坐标开始和结束位置,为数组方式输出。
例如:
Life is painting a picture, not doing ‘a sum’.
[8, 15][19, 25][42, 44]
示例1
输入:
Life is painting a picture, not doing ‘a sum’.
8 15,20 26,43 45
输出:
Life is painting a picture, not doing ‘a sum’.
[8, 15][19, 25][42, 44]
说明:
a和picture中间多余的空格进行删除
示例2
输入:
Life is painting a picture, not doing ‘a sum’.
8 15,19 25,42 44
输出:
Life is painting a picture, not doing ‘a sum’.
[8, 15][19, 25][42, 44]
说明:
a和sum之间有多余的空格,但是因为有成对单引号,不去除多余空格
解题思路:
例如:
Life is painting a picture, not doing ‘a sum’.
8 15,20 26,43 45
1、先对文本进行去除多余空格,同时记录多余空格的坐标位置【18】;
2、遍历关键字词的坐标,让他跟多余空格坐标进行比较;
第一个字符[8,15],没有小于8和15的空格位置;
结论:坐标位置不变[8,15]
第二个字符[20,26],小于20和26的只有一个18;
结论:坐标整体向前移动1,坐标为[19,25]
第三个字符[43,45],小于43和45的只有一个18;
结论:坐标整体向前移动1,坐标为[42,44]
以下代码只有170分,没有通过的用例太长了,后面都是省略号,所以无从知晓未通过的实际用例是什么样子的;有三个同学都是170分,没通过的用例也是一样的,感觉又有幺蛾子!
代码实现一:
package com.codernav.demo.hwod.exam;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @title 去除多余空格
* @Description 去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。
* 条件约束:
* 1,不考虑关键词起始和结束位置为空格的场景;
* 2,单词的的开始和结束下标保证涵盖一个完整的单词,即一个坐标对开始和结束下标之间不会有多余的空格;
* 3, ……
* @Author 开发者导航
* @website https://codernav.com
* @date 2023/5/28
*/
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s1 = in.nextLine();
String resStr = "";
//多余空格的坐标集合
ArrayList<Integer> count = new ArrayList<>();
//判断是否在引号内
int flag = 0;
for (int i = 0; i < s1.length() - 1; i++) {
if (s1.charAt(i) == '\'') {
flag++;
}
if (flag % 2 == 0) {
if (s1.charAt(i) == ' ' && s1.charAt(i + 1) == ' ') {
count.add(i);
continue;
}
}
resStr += s1.charAt(i);
}
//处理完对于空格的字符串
resStr += s1.charAt(s1.length() - 1);
String s2 = in.nextLine();
String[] s2_1 = s2.split(",");
//处理完的坐标集合
ArrayList<Integer> resIndex = new ArrayList<>();
for (String s : s2_1) {
String[] t = s.split(" ");
for (int i = 0; i < t.length; i++) {
int tem = Integer.parseInt(t[i]);
resIndex.add(tem - fun(count, tem));
}
}
System.out.println(resStr);
System.out.print("[");
for (int i = 0; i < resIndex.size() - 1; i++) {
System.out.print(resIndex.get(i));
if (i % 2 == 0) {
System.out.print(", ");
} else {
System.out.print("][");
}
}
System.out.println(resIndex.get(resIndex.size() - 1) + "]");
}
//求出之前多余的空格
public static int fun(List<Integer> list, int num) {
int result = 0;
for (Integer integer : list) {
if (integer < num) {
result++;
}
}
return result;
}
}
代码实现二:满分Java实现
package com.codernav.demo.hwod.exam;
import java.util.Scanner;
/**
* @title 去除多余空格
* @Description 去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。
* 条件约束:
* 1,不考虑关键词起始和结束位置为空格的场景;
* 2,单词的的开始和结束下标保证涵盖一个完整的单词,即一个坐标对开始和结束下标之间不会有多余的空格;
* 3, ……
* @Author 开发者导航
* @website https://codernav.com
* @date 2023/5/28
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line1 = scanner.nextLine().trim();
String line2 = scanner.nextLine().trim();
String[] key = line2.split(",");
if (key.length > 3 || key.length == 0) { //这个满分答案的不能大于3,我也不太理解,大家可以先存疑吧
return;
}
//找到关键词
String[] keywords = new String[key.length];
for (int i = 0; i < key.length; i++) {
String[] index = key[i].split(" ");
if (index.length != 2) {
break;
}
int start_index = Integer.parseInt(index[0]);
int end_index = Integer.parseInt(index[1]);
keywords[i] = line1.substring(start_index, end_index + 1);
}
//2 去除空格
String output_str = "";
char[] line1_bytes = line1.toCharArray();
int index = 0;
boolean last_space_flag = false;
boolean last_single_mark_flag = false;
while (index < line1.length()) {
if (line1_bytes[index] == ' ') {
if (last_space_flag && !last_single_mark_flag) {
index++;
continue;
}
last_space_flag = true;
} else {
last_space_flag = false;
}
if (line1_bytes[index] == '\'') {
if (last_single_mark_flag) {
last_single_mark_flag = false;
} else {
last_single_mark_flag = true;
}
}
output_str += (line1_bytes[index]);// System.Text.Encoding.ASCII.GetString(line1_bytes[i]);
index++;
}
System.out.println(output_str);
//3.重新计算关键词的位置
String res = "";
for (int i = 0; i < keywords.length; i++) {
if (keywords[i] == "" || keywords[i] == null) {
break;
}
int pos = output_str.indexOf(keywords[i]);
if (pos == -1) {
break;
}
String key_out_end = "[";
key_out_end += pos;
key_out_end += ", ";
key_out_end += pos + keywords[i].length() - 1;
key_out_end += "]";
res += key_out_end + ",";
}
System.out.println(res.substring(0, res.length() - 1));
}
}
