华为OD机试 - 去除多余空格

题目描述

去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。

条件约束:

1,不考虑关键词起始和结束位置为空格的场景;

2,单词的的开始和结束下标保证涵盖一个完整的单词,即一个坐标对开始和结束下标之间不会有多余的空格;

3,如果有单引号,则用例保证单引号成对出现;

4,关键词可能会重复;

5,文本字符长度length取值范围:[0, 100000];

输入描述

输入为两行字符串:

第一行:待去除多余空格的文本,用例保证如果有单引号,则单引号成对出现,且单引号可能有多对。

第二行:关键词的开始和结束坐标,关键词间以逗号区分,关键词内的开始和结束位置以单空格区分。

输出描述

输出为两行字符串:

第一行:去除多余空格后的文本

第二行:去除多余空格后的关键词的坐标开始和结束位置,为数组方式输出。

用例

输入

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中间多余的空格进行删除

输入

Life is painting a picture, not doin '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之间有多余的空格,但是因为有成对单引号,不去除多余空格

题面来源于伏城之外老哥,本人借助老哥的思想写的一种解法,不一定正确,不正确可以告诉我

package com.itheima.华为机考;

import java.util.*;

/**
 * @author guts
 * @Date 2023/2/26 15:16
 * @Version 1.0
 *去除多余空格
 */
public class HW067_2 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            String s = sc.nextLine();
            int[][] ranges = Arrays.stream(sc.nextLine().split(","))
                    .map(o -> Arrays.stream(o.split(" ")).mapToInt(Integer::parseInt).toArray())
                    .toArray(int[][]::new);
            char[] chars = s.toCharArray();
            //用来保存字符
            Stack<Character> stack=new Stack<>();
            //表示已经遇到了左边的单引号
            boolean quota=false;
            //表示当前索引处之前有多少需要删除的空格
            int[] needDel=new int[s.length()];
            for (int i = 0; i < chars.length; i++) {
                //避免空指针,其实0号元素为0,如果不特殊处理,要删除的数量跟前面一样
                if(i>1)needDel[i]=needDel[i-1];
                char c = chars[i];
                //如果不是空格的话,看下是不是单引号,单引号表示要进行变号处理
                if(c!=' '){
                    if(!quota&&c=='\'')quota=true;
                    else if (quota&&c=='\'')quota=false;
                    //不管是字母还是单引号还是逗号,都要入栈
                    stack.push(c);
                }else {
                    //当前字符是空格,栈顶是空格,且不在单引号的范围内,就舍弃该空格,并且needDel[i]=needDel[i-1]+1;
                    if(!quota&&!stack.isEmpty()&&stack.peek()==' ')needDel[i]=needDel[i-1]+1;
                    //如果是单引号范围内就入栈
                    else stack.push(c);
                }
            }
            //返回的数组
            ArrayList<List<Integer>> resList=new ArrayList<>();
            for (int[] range : ranges) {
                //最开始的起始索引和结束索引
                int start = range[0];
                int end = range[1];
                //needDel[start]表示在start索引处应该删除的空格,也就是start和之间的删除空格数量
                //记录使用needDel是为了降时间复杂度
                resList.add(Arrays.asList(start-needDel[start],end-needDel[start]));
            }
            StringBuilder sb=new StringBuilder();
            while(!stack.isEmpty()){
                sb.append(stack.pop());
            }
            System.out.println(sb.reverse().toString());
            System.out.println(resList);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值