我有ArrayList<String>
,其中包含以下内容:
2 #3#的 1 #0
1 #0#的 4 #1
9 #2#的 5 #0
4 #2#的 3 #2
1 #1#的 2 #1
输出:6个不同的数字。
我正在尝试编写一个算法来删除突出显示的数字的重复项,以便我可以使用计数器查看所有这些位置中总共有多少不同的数字。
我尝试过很多东西,包括以下一些内容:[Java使用循环从数组中删除重复项] [1],[Java - 删除ArrayList中的重复项] [2],[如何查找重复项中的第一个选项]在Java数组?] [3]等等。我花了至少5-10小时才试图弄清楚我做错了什么,但我不能,所以我转向你。
大多数时候,我在网上找到的解决方案似乎只是简单的工作,但不是我的情况。在其中,当我尝试打印不同的字符时,它总是返回错误的int
数字。
我也尝试过,也尝试将每行数字分成不同的int Array[]
,然后比较,但它不会捕获所有不同的值。
在另一个例子中,我总共有5个不同的数字,因此我不断得到“4个不同”,所以我甚至尝试long n = ArrayList.stream().distinct().count();
只是为了看我是否在做某事错了,但即便是这件事也回归了“4个不同”的数字。
我知道最简单的方法是使用Set
和Map
,但我不希望这样。我想要一个算法。
编辑:
我尝试过的很多事情之一是:
for (int m = 0; m < (size-1); m++){
for (int j = m + 1; j < size; j++){
if (ArrayList.get(j).charAt(0) != ArrayList.get(m).charAt(0)){
continue;
}
current++;
ArrayList.remove(j).charAt(0);
j--;
size--;
}
}
有了这个,我必须使用另一个ArrayList.get().charAt(4)
。
EDIT2:
我找到了以下代码[here] [1],但在这种情况下如何实现?
public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) {
ArrayList <T> uniqueArrayList = new ArrayList<T>();
for (int i = 0; i < myList.size(); i++){
if (!uniqueArrayList.contains(myList.get(i))){
uniqueArrayList.add(myList.get(i));
}
}
return uniqueArrayList;
}
EDIT3:
我找到了一个可能的解决方案,但它给了我一个IndexOutOfBoundsException。
我已将数字 2,1,9,4,1 放入Array1
,将 1,4,5,3,2 放入{{1} },但是当我尝试比较它们时,我得到了上面提到的错误。
Array2
w.com/questions/203984/how-do-i-remove-repeated-elements-from-arraylist?rq=1
答案 0 :(得分:3)
算法比你想象的要简单得多:
这是一个完整的例子:
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
public class Duplicates {
public static void main(String[] args) {
List<String> list = Arrays.asList("2#3#1#0",
"1#0#4#1",
"9#2#5#0",
"4#2#3#2",
"1#1#2#1");
System.out.println(
list.stream()
.flatMapToInt(s -> IntStream.of(s.charAt(0), s.charAt(4)))
.distinct()
.count());
}
}
编辑:你似乎想要遵守荒谬的限制,因此既不使用Stream也不使用Set,这些完全有意义。这里的代码只使用列表,但基本上与上面的内容相同,但效率要低得多:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Duplicates {
public static void main(String[] args) {
List<String> list = Arrays.asList("2#3#1#0",
"1#0#4#1",
"9#2#5#0",
"4#2#3#2",
"1#1#2#1");
List<Character> uniqueChars = new ArrayList<>();
for (String s : list) {
Character c0 = s.charAt(0);
Character c4 = s.charAt(4);
if (!uniqueChars.contains(c0)) {
uniqueChars.add(c0);
}
if (!uniqueChars.contains(c4)) {
uniqueChars.add(c4);
}
}
System.out.println(uniqueChars.size());
}
}
答案 1 :(得分:2)
计算不同数量的突出显示位置并不困难。您可以使用称为频率数组的辅助数组来获得预期结果。
使用频率数组尝试这个简单的算法我认为它适用于您的情况:
ArrayList<String> numlist=new ArrayList<String>();
int freq[] = new int [10];
numlist.add("2#3#1#0");
numlist.add("1#0#4#1");
numlist.add("9#2#5#0");
numlist.add("4#2#3#2");
numlist.add("1#1#2#1");
for(int i = 0; i < numlist.size(); i++){
String row = numlist.get(i);
int numValue1 = Character.getNumericValue(row.charAt(0));
int numValue2 = Character.getNumericValue(row.charAt(4));
freq[numValue1]++;
freq[numValue2]++;
}
int count = 0;
for(int i = 0; i < 10; i++){
if(freq[i] > 0){
count++;
}
}
System.out.println(count + " different numbers");
<强>输出强>:
6 different numbers
答案 2 :(得分:1)
位掩码的另一个选项:
public static void main(String[] args) {
List<String> arrayList = Arrays.asList("2#3#1#0", "1#0#4#1", "9#2#5#0", "4#2#3#2", "1#1#2#1");
int mask = 0;
for(String s : arrayList) { // Place the bits
mask = mask | (1 << Character.getNumericValue(s.charAt(0))) | (1 << Character.getNumericValue(s.charAt(4)));
}
int counter = 0;
for(int i = 0; i < 32; i++) { // count the bits
counter += (mask & (1 << i)) == 1 << i ? 1 : 0;
}
System.out.println(counter);
}
输出:
6
这依赖于代码执行结束时的位掩码:
1000111110
这可能比大多数解决方案更快,因为它不依赖于传统的数据结构。
答案 3 :(得分:0)
嗯,一个好的做法总是将问题分成更小的部分:
例如,一个好的设计将是一个包含这些成员的类:
digits
:这是一个int数组的实例变量,用于包含每个数字重复的次数。它必须预先设定为允许的最大数字(我猜是 9 )。differentDigits
:是一个包含不同数字位数的实例变量。processList
:此方法将收到列表以进行浏览,并为每个项目调用processItem
。processItem
:此方法应接收项目字符串并根据指定的格式解析数字(例如,通过StringTokenizer
),并为每个所需的数字调用storeDigit
。< / LI>
storeDigit
:此方法应接收一个int并使用它来索引实例数组digits
,并递增索引位置。如果索引位置为0,则还应增加differentDigits
。