如何解决删除彼此相邻的字符串中的一对字符
在一次面试中,我遇到了一个问题,我找不到动态输入的逻辑。
输入:abbcaddaee
如果给出了这个输入,我们必须删除一对字符,例如
abbcaddaee
。粗体值将被删除,输出为acaa
,那么我们也必须为此做同样的事情,然后acaa
。最终输出为 ac
。
同样必须执行 n
次迭代才能删除这些相同的 char
对。
输入:aabbbcffjdddd
→ aabbbcffjdddd
→ bcj
解决方法
我会在这里使用正则表达式替换:
String input = "aabbbcffjdddd";
String output = input.replaceAll("(.)\\1","");
System.out.println(output); // bcj
正则表达式模式 (.)\1
匹配任何单个字符后跟同一个字符一次。我们用空字符串替换这些匹配项,有效地删除它们。
在下面的解决方案中,我使用递归方法来给你想要的结果。
对于模式:
1st Capturing Group (.)
. matches any character (except for line terminators)
\1 matches the same text as most recently matched by the 1st capturing group
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
private static Pattern p = Pattern.compile("(.)\\1");
public static void main(String[] args) {
System.out.println(removePairChar("abbcaddaee"));
System.out.println(removePairChar("aabbbcffjdddd"));
}
public static String removePairChar(String input) {
Matcher matcher = p.matcher(input);
boolean matchFound = matcher.find();
if(matchFound) {
input = input.replaceAll(p.pattern(),"");
return removePairChar(input);
}
return input;
}
}
输出:
ac
bcj
,
您可以使用 regexp 和一个 do-while 循环:
String str = "abbcaddaee";
do {
System.out.println(str);
} while (!str.equals(str = str.replaceAll("(.)\\1","")));
输出:
abbcaddaee
acaa
ac
说明:
-
regexp
(.)\\1
- 后跟相同字符的任何字符; -
str = str.replaceAll(...)
- 删除所有重复项并替换当前字符串; -
!str.equals(...)
- 检查当前字符串与自身的不等式,但没有重复项。
另见:Iterate through a string and remove consecutive duplicates
,基本思想是使用Stack。在这种情况下,我们将有 O(n) 复杂度而不是 while + replaceAll
- 循环遍历字符代码,如果堆栈中不存在字符代码,则推送它
- 如果栈头等于当前字符码,则弹出它
import java.util.Optional;
import java.util.Stack;
public class Main {
public static void main(final String... params) {
System.out.println(Main.normalize("abbcaddaee"));
System.out.println(Main.normalize("aabbbcffjdddd"));
}
private static String normalize(final String input) {
final int length = Optional.ofNullable(input).map(String::length).orElse(0);
if (length < 2) {
return input;
}
Stack<Integer> buf = new Stack<Integer>();
input.codePoints().forEach(code -> {
if (buf.isEmpty() || buf.peek() != code) {
buf.push(code);
} else {
buf.pop();
}
});
return buf.stream().collect(
StringBuilder::new,StringBuilder::appendCodePoint,StringBuilder::append).
toString();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。