我想在列表中找到所有重复项,并将其更改为下一个:
{"a", "b", "c", "a", "b"}
{"a1", "b1", "c", "a2", "b2"}
我知道如何在列表中找到副本,但是我很难为每个相同的字符串添加出现次数。
答案 0 :(得分:2)
使用Map<String, List<Integer>>
,它将包含每个元素所在的索引列表。创建此类映射后,只需检查哪个元素包含多个索引,然后根据需要更新每个元素。
String[] arr = { "a", "b", "c", "a", "b" };
Map<String, List<Integer>> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(arr[i])) {
map.get(arr[i]).add(i);
} else {
List<Integer> list = new ArrayList<>();
list.add(i);
map.put(arr[i], list);
}
}
for (Map.Entry<String, List<Integer>> entry : map.entrySet()) {
if (entry.getValue().size() > 1) {
int counter = 1;
for (int i : entry.getValue()) {
arr[i] += counter++;
}
}
}
System.out.println(Arrays.toString(arr));
输出:[a1, b1, c, a2, b2]
答案 1 :(得分:1)
这是JAVA 8 lambdas和溪流。
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
/**
* Created by joshua on 3/17/14.
*/
public class FindDuplicates {
public static boolean isUnique(String x, List<String> list) {
return 1 == list.stream().filter(s -> x.equals(s)).count();
}
public static void main(String[] args) {
Map<String, Integer> seen = new HashMap<String, Integer>();
List<String> list = Arrays.asList("a", "b", "c", "a", "b");
Stream<String> finalStream = list.stream().map(x -> {
int times = seen.getOrDefault(x, 0) + 1;
seen.put(x, times);
return x + times;
}).map(x -> isUnique(x.substring(0,1), list)? x.substring(0,1) : x);
System.out.println(Arrays.asList(finalStream.toArray()));
}
}
答案 2 :(得分:0)
类似于PShemo的回答,但有点不同。
public class FindDuplicate {
public static final String ONE = "1";
public static void main(String args[]){
String[] lists = {"a", "b", "c", "a", "b"};
HashMap<String, PlaceHolder> dupCounts = new HashMap<>();
for (int i = 0; i < lists.length; i++) {
PlaceHolder placeHolder = dupCounts.get(lists[i]);
if ( placeHolder != null){
placeHolder.setCount(placeHolder.getCount() +1) ;
lists[i] = lists[i].concat( placeHolder.toString());
}else{
placeHolder = new PlaceHolder();
placeHolder.setCount(1);
placeHolder.setFirstPosition(i);
dupCounts.put(lists[i], placeHolder);
}
}
for (Map.Entry<String, PlaceHolder> entry: dupCounts.entrySet()){
if (entry.getValue().getCount() > 1){
int position = entry.getValue().getFirstPosition();
lists[position] = lists[position].concat(ONE);
}
}
for (String string : lists) {
System.out.println(string);
}
}
}
class PlaceHolder{
int count;
int firstPosition;
/**
* @return the count
*/
public int getCount() {
return count;
}
/**
* @param count the count to set
*/
public void setCount(int count) {
this.count = count;
}
/**
* @return the firstPosition
*/
public int getFirstPosition() {
return firstPosition;
}
/**
* @param firstPosition the firstPosition to set
*/
public void setFirstPosition(int firstPosition) {
this.firstPosition = firstPosition;
}
@Override
public String toString(){
return count+"";
}
}
答案 3 :(得分:0)
我最初想的是这有点复杂。
我的第一个想法是简单地遍历List
并使用Map<String, Integer>
来计算每个字符的出现次数。在计数期间,您可以输出与运行计数连接的当前字符。这个代码很简单,但结果是:
{"a1", "b1", "c1", "a2", "b2"}
因为我们无法知道将再次看到哪些角色。
因此我们需要对数据进行一些预处理。首先,我们计算每个字符的出现次数:
final List<String> orig = Arrays.asList("a", "b", "c", "a", "b");
final Map<String, Integer> counts = new HashMap<>();
for (final String value : orig) {
final Integer count = counts.get(value);
if (count == null) {
counts.put(value, 1);
} else {
counts.put(value, count + 1);
}
}
计数现在包含:
{b=2, c=1, a=2}
新的,我们不能简单地向后循环原始数组并在这里减少计数,因为我们无法知道我们是否计数为1,因为我们之前输出了一些值,或者因为这是唯一的值
我的解决方案是复制count
地图并将其称为seens
。在这里,当我们生成输出时,我们会看到它们的值。
final List<String> result = new LinkedList<>();
final Map<String, Integer> seens = new HashMap<>(counts);
for (final String value : orig) {
final Integer count = counts.get(value);
if (count == 1) {
result.add(value);
} else {
final Integer seen = seens.get(value);
result.add(value + (count - seen + 1));
seens.put(value, seen - 1);
}
}
System.out.println(result);
所以我们再次遍历原始数组并为每个项目
counts
中的值为1
,则只输出值counts
中的值大于1
,则从seens
count - seen + 1
计算我们看到的商品的数量,即项目总数减去(总数减去我们目前为止所见的数量)。value + number
seens