为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1058
题目描述
塔子哥最近接到导师的一个任务,需要他帮忙去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。
但是塔子哥现在忙于其他事情没有时间做这个,你能帮他一下吗?
任务的条件约束如下:
- 不考虑关键词起始和结束位置为空格的场景;
- 单词的的开始和结束下标保证涵盖一个完整的单词,即一个坐标对开始和结束下标之间不会有多余的空格;
- 如果有单引号,则用例保证单引号成对出现;
- 关键词可能会重复;
- 文本字符长度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]
题目思路
直接模拟这个过程就可以了,在删除时用一个记录删除掉的下标,其目的是为了处理最后的关键词的坐标
同时为了方便处理我们将关键词的坐标用三个捆绑变量存储下来,分别是l, r, i
,分别表示坐标的左右区间,和关键词的原本序号(自己设定的)。同时,根据题意,我们在单引号之间不能删空格,固可以使用一个变量haveq
左右引号的情况
在修改关键词坐标时,我们先将关键词的坐标按左区间的大小进行排序,然后遍历关键词坐标,用类似队列的思想,记录小于当前关键词左区间的删除掉的空格的下标,这样子处理的好处是时间复杂度是 O ( n ) O(n) O(n),具体看代码
最后输出时记得将关键词坐标按原本的序号排好序再输出
C++代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1e5 + 5;
char s[N];
struct keyword{
int l, r, i;
};
int main() {
gets(s);
vector<keyword> keywords;
int l, r, cnt = 0;
while (~scanf("%d %d,", &l, &r)) keywords.emplace_back(l, r, ++cnt);
int haveq = false, n = strlen(s);
vector<int> del_index;
for (int i = 0; i < n; ++i) {
if (s[i] == ' ' && s[i + 1] == ' ' && !haveq) { // 删除
del_index.push_back(i);
continue;
} else if (s[i] == '\'') {
haveq = !haveq;
}
putchar(s[i]);
}
puts("");
sort(keywords.begin(), keywords.end(), [](keyword& a, keyword& b) {
return a.l < b.l;
});
int indx = 0, vlen = del_index.size(), def = 0;
for (auto& [l, r, i] : keywords) {
while (indx < vlen && del_index[indx] < l) {
indx += 1;
def += 1; // 记录偏移量
}
l -= def, r -= def;
}
sort(keywords.begin(), keywords.end(), [](keyword& a, keyword& b) {
return a.i < b.i;
});
for (auto [l, r, i] : keywords) {
printf("[%d,%d]", l, r);
}
return 0;
}
Python代码
def take_l(keyword):
return keyword[0]
def take_i(keyword):
return keyword[2]
s = str(input())
kw = list(map(str, input().split(',')))
keywords = []
cnt = 0
for tmp in kw:
cnt += 1
arr = tmp.split(' ')
l, r, i = int(arr[0]), int(arr[1]), cnt
keywords.append([l, r, i])
n = len(s)
s += '\0'
del_index, haveq, ans = [], False, ''
for i in range(n):
if s[i] == ' ' and s[i + 1] == ' ' and not haveq:
del_index.append(i)
continue
elif s[i] == '\'':
haveq = not haveq
ans += s[i]
keywords.sort(key = take_l)
indx, vlen, deff = 0, len(del_index), 0
for lri in keywords:
while indx < vlen and del_index[indx] < lri[0]:
indx += 1
deff += 1
lri[0] -= deff
lri[1] -= deff
keywords.sort(key=take_i)
print(ans)
for lri in keywords:
print('[' + str(lri[0]) + ',' + str(lri[1]) + ']', end='')
Java代码
import java.util.*;
class keyword {
public int l;
public int r;
public int i;
public keyword(){}
public keyword(int l, int r, int i) {
this.l = l;
this.r = r;
this.i = i;
}
}
class cmpl implements Comparator<keyword> {
public int compare(keyword a, keyword b) {
if (a.l < b.l)
return -1;
return 1;
}
}
class cmpi implements Comparator<keyword> {
public int compare(keyword a, keyword b) {
if (a.i < b.i)
return -1;
return 1;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
int n = s.length(), cnt = 0;
String[] kw = scanner.nextLine().split(",");
List<keyword> keywords = new ArrayList<>();
for (String tmp : kw) {
String[] str = tmp.split(" ");
int l = Integer.valueOf(str[0]).intValue();
int r = Integer.valueOf(str[1]).intValue();
keywords.add(new keyword(l, r, ++cnt));
}
s += '\0';
List<Integer> del_index = new ArrayList<>();
Boolean haveq = false;
String ans = "";
for (int i = 0; i < n; i++) {
if (s.charAt(i) == ' ' && s.charAt(i + 1) == ' ' && !haveq) {
del_index.add(i);
continue;
} else if (s.charAt(i) == '\'') {
haveq = !haveq;
}
ans += s.charAt(i);
}
keywords.sort(new cmpl());
int indx = 0, def = 0, vlen = del_index.size();
for (keyword lri : keywords) {
while (indx < vlen && del_index.indexOf(indx) < lri.l) {
indx += 1;
def += 1;
}
lri.l -= def;
lri.r -= def;
}
keywords.sort(new cmpi());
System.out.println(ans);
for (keyword lri : keywords) {
System.out.print("[" + lri.l + "," + lri.r + "]");
}
}
}
Js代码
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
input += data;
return;
});
process.stdin.on('end', () => {
input = input.split('\n')
let s = input[0]
let tmp = input[1].split(',')
let keywords = []
let cnt = 0
for (let kw of tmp) {
cnt += 1
let num = kw.split(' ').map(Number)
keywords.push([num[0], num[1], cnt])
}
let n = s.length
s += '\0'
let del_index = new Array()
let haveq = false
let ans = ''
for (let i = 0; i < n; i++) {
if (s[i] == ' ' && s[i + 1] == ' ' && !haveq) {
del_index.push(i)
continue
} else if (s[i] == '\''){
haveq = !haveq
}
ans += s[i]
}
keywords.sort((a, b) => {
if (a[0] < b[0])
return -1
return 1
})
let indx = 0
let vlen = del_index.length
let def = 0
for (let lri of keywords) {
while (indx < vlen && del_index[indx] < lri[0]) {
indx += 1
def += 1
}
lri[0] -= def
lri[1] -= def
}
keywords.sort((a, b) => {
if (a[2] < b[2])
return -1
return 1
})
ans += '\n'
for (let lri of keywords) {
ans += '[' + lri[0] + ',' + lri[1] + ']'
}
console.log(ans)
})
题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册用户名: 塔子哥学算法) 进行删除。