Java 用于保持成对数据频率计数的数据结构?
我有一个记录为100'的表,其中一个字段根据id与一个类似的字段配对。我想知道一个好的数据结构是什么,它可以保持一对出现在一起的次数的频率计数,而不管它们出现的顺序如何 样本数据: ID Feature 5 F1 5 F2 6 F1 6 F2 7 F3 7 F1 7 F2 8 F1 9 F1 10 F1 ID特征 5 F1 5 F2 6 F1 6 F2 7层3 7 F1 7 F2 8 F1 9 F1 10 F1 示例输出为: F1 F2 F3 F1 0 3 1 F2 3 0 1 F3 1 1 0 F1 F2 F3 F1 03 1 F2 30 1 F3 11 0 一种选择是对所有特征进行排序,并使用二维整数数组来表示成对数据,但数组的2/3是无用的/重复的。例如Java 用于保持成对数据频率计数的数据结构?,java,arrays,algorithm,data-structures,Java,Arrays,Algorithm,Data Structures,我有一个记录为100'的表,其中一个字段根据id与一个类似的字段配对。我想知道一个好的数据结构是什么,它可以保持一对出现在一起的次数的频率计数,而不管它们出现的顺序如何 样本数据: ID Feature 5 F1 5 F2 6 F1 6 F2 7 F3 7 F1 7
array[i][i]=0
和array[i][j]=array[j][i]
。考虑到我有数百个特性,这种方法是行不通的
我曾想过使用地图,但后来密钥需要表示一对,例如(F1,F3)。我也希望有其他的解决办法。如果没有,我会用地图
MyPair
,用于存储项目对并覆盖Object#equals(…)
(和Object#hashCode()
)的散列键,以便顺序无关紧要(例如,通过按字典顺序排序)映射
来存储配对的频率计数类MyPair{
公开最终字符串特征1;
公开最终字符串特征2;
公共MyPair(字符串s1、字符串s2){
//顺序特征使比较与顺序无关。
如果(s1)与(s2)比较为空
频率输出(对1,1);
MyPair2=新的MyPair(“F2”、“F1”);
freq.get(pair2);//=>1
这是一个简单的算法。我假设数据最初是经过排序的。它可能没有我想要的那么好,但它必须只显示正确的路径:)
可能是地图?我曾想过使用地图,但后来密钥需要表示一对,例如(F1,F3)。我也希望有其他解决方案。如果没有,我将使用地图。这不是一个好的解决方案。如何高效地打印所有邻居,比如说“F1”?我想我需要遍历频率图。当然,如果你编造了一些不在问题中的东西,那么解决方案当然不会好。。。
Map<MyPair,Integer> freq = new HashMap<MyPair,Integer>();
MyPair pair1 = new MyPair("F1", "F2");
freq.get(pair1); // => null
freq.put(pair1, 1);
MyPair pair2 = new MyPair("F2", "F1");
freq.get(pair2); // => 1
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class NeighborListExample {
static class Pair {
private String feature;
private int cnt = 1;
Pair(String feature) {
this.feature = feature;
}
void incr() {
cnt++;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((feature == null) ? 0 : feature.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (feature == null) {
if (other.feature != null)
return false;
} else if (!feature.equals(other.feature))
return false;
return true;
}
@Override
public String toString() {
return "(" + feature + ", " + cnt + ")";
}
}
static Map<String, List<Pair>> feature2neighbors = new HashMap<>();
private static int getId(Object[][] data, int i) {
return ((Integer) data[i][0]).intValue();
}
private static String getFeature(Object[][] data, int i) {
return data[i][1].toString();
}
private static void processFeatures(String[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (i != j) {
List<Pair> pairs = feature2neighbors.get(array[i]);
if (pairs == null) {
pairs = new LinkedList<>();
feature2neighbors.put(array[i], pairs);
}
Pair toAdd = new Pair(array[j]);
int index = pairs.indexOf(toAdd);
if (index == -1) {
pairs.add(toAdd);
} else {
pairs.get(index).incr();
}
}
}
}
}
static void print(Map<String, List<Pair>> feature2neighbors) {
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, List<Pair>> e : feature2neighbors.entrySet()) {
builder.append(e.getKey()).append(" -> ");
Iterator<Pair> it = e.getValue().iterator();
builder.append(it.next().toString());
while(it.hasNext()) {
builder.append(" ").append(it.next().toString());
}
builder.append("\n");
}
System.out.println(builder.toString());
}
public static void main(String[] args) {
//I assume that data is sorted
Object[][] data = { { 5, "F1" }, //
{ 5, "F2" }, //
{ 6, "F1" }, //
{ 6, "F2" }, //
{ 7, "F3" }, //
{ 7, "F1" }, //
{ 7, "F2" }, //
{ 8, "F1" }, //
{ 9, "F1" }, //
{ 10, "F1" }, //
};
List<String> features = new LinkedList<>();
int id = getId(data, 0);
for (int i = 0; i < data.length; i++) {
if (id != getId(data, i)) {
processFeatures(features.toArray(new String[0]));
features = new LinkedList<>();
id = getId(data, i);
}
features.add(getFeature(data, i));
}
print(feature2neighbors);
}
}
F1 -> (F2, 3) (F3, 1)
F3 -> (F1, 1) (F2, 1)
F2 -> (F1, 3) (F3, 1)