我正在使用program表明
有一个字符串,由小写英文字母组成。在一个操作中,我们可以删除具有相同值的任何一对相邻字母。
例如,字符串“aabcc”在操作后将变为“aab”或“bcc”。
结果应尽可能减少。为此,我们必须多次重复上述操作。
示例:
case 1:
Input - aaabccddd
Output - abd
这里的操作顺序如下:
aaabccddd → abccddd
abccddd → abddd
abddd → abd
您可以参考上面的链接了解更多详情。
我尝试使用List来解决问题,但我认为这不是正确的方法:
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String data = scan.next();
scan.close();
String[] dataArr = data.split("");
List<String> elements = Arrays.asList(data.split(""));
for(int i=0; i< elements.size()-1; i++) {
if(elements.get(i).equals(elements.get(i+1))) {
elements.remove(i);
elements.remove(i+1);
}
}
System.out.println(elements);
}
}
我收到的错误为:java.lang.UnsupportedOperationException
请帮助我解决这个问题的正确方法。
答案 0 :(得分:7)
Arrays#asList
创建不可修改的列表,请查看文档:
返回由指定数组支持的固定大小列表。
您无法从中删除元素。尝试:
List<String> elements = new ArrayList(Arrays.asList(data.split("")));
答案 1 :(得分:6)
Maroun Maroun's answer描述了代码中异常的具体原因。
比拆分列表更简单的解决方案是按字符顺序遍历字符串:
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < str.length()) {
if (i + 1 < str.length() && str.charAt(i) == str.charAt(i + 1)) {
i += 2;
} else {
sb.append(str.charAt(i));
i += 1;
}
}
String result = sb.toString();
答案 2 :(得分:3)
既然我们已经帮助太多而且提问者已经得到答案,请允许我提供我的解决方案:
StringBuilder result = new StringBuilder(input.length());
for (int ix = 0; ix < input.length(); ix++) {
char ch = input.charAt(ix);
if (endsWith(ch, result)) {
removeLastChar(result);
} else {
result.append(ch);
}
}
String output = result.toString();
我一次性完成所有工作,我认为它不会太复杂(尽管它不是最少代码行的解决方案)。
我使用两种辅助方法:
private static boolean endsWith(char ch, StringBuilder buf) {
return buf.length() > 0 && buf.charAt(buf.length() - 1) == ch;
}
private static void removeLastChar(StringBuilder buf) {
buf.setLength(buf.length() - 1);
}
答案 3 :(得分:1)
除了@MarounMaroun的修复,你需要在删除迭代列表中的值时要小心。
for(int i=0; i< elements.size()-1; i++) {
if(elements.get(i).equals(elements.get(i+1))) {
elements.remove(i);
elements.remove(i+1); // not the index you think it is
}
}
由于您首先删除了索引i
,因此您认为位于i+1
的元素现在已移回i
。根据经验,在更接近开头的项目之前,更容易删除列表中的项目。你可以写:
for(int i=0; i< elements.size()-1; i++) {
if(elements.get(i).equals(elements.get(i+1))) {
elements.remove(i+1);
elements.remove(i);
}
}
或者你可以写:
for(int i=0; i< elements.size()-1; i++) {
if(elements.get(i).equals(elements.get(i+1))) {
elements.remove(i);
elements.remove(i);
}
}
答案 4 :(得分:0)
最简单的方法(上次我解决了问题)是使用正则表达式
// Somehow read input and store it in a String input
String regex = "(.)\\1";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(input);
while (m.find()) {
input = m.replaceAll("");
m = r.matcher(input);
}
// check length, do other things and print
谢谢@ OleV.V。用于指出字符串转义错误