我有一个包含行的文件 键值
-----+---------------------------
1 1 2 0.39785 0.39785 0.2043 36
1 1 3 0.409604 0.409604 0.180792 24
1 1 4 0.407281 0.407281 0.185438 24
1 1 5 0.404958 0.404958 0.190084 24
1 1 6 0.403399 0.403399 0.193203 24
...
23 34 36 0.414457 0.354921 0.230622 576
..
- 前3个数字是关键并代表比赛,它们是唯一的,它们是升序的 - 浮点值链接到键。例如:第一行的第4个元素(0.39785)属于第1个元素,第6个元素(0.2043)到2个。
我逐行阅读并将其拆分为“”(空格)。 我应该如何存储它(哪个集合/结构)。
假设我想查找“2 1 1”。 当我写的密钥是升序时,不会有像“2 1 1”这样的条目, 只有“1 1 2”,所以首先我必须对它进行排序,但我想得到这些值 在查找的顺序(0.2043 0.39785 0.39785)。
答案 0 :(得分:2)
以下数据结构应满足您的所有要求:
Dictionary<HashSet<int>, Dictionary<int, double>>
使用原始数据中的LINQ创建上述结构的实例应该很容易。
访问应该很简单:
HashSet
(2,1)Dictionary
- &gt;中查找(2,1) ((1,0.39785),(2,0.2043))double
,如2 - &gt; 0.2043 CAVEAT 解决方案只能在int
一行的相同double
- 值上运行 - 值也相同。 (这似乎适用于提供的样本数据)。
编辑创建yourLookup
的代码:
List<List<int>> intList = new List<List<int>>() {
new List<int> () {1, 1, 2},
new List<int> () {1, 1, 3},
...
};
List<List<double>> doubleList = new List<List<double>> {
new List<double>() {0.39785, 0.39785, 0.2043},
new List<double>() {0.409604, 0.409604, 0.180792},
....
};
var dictionaries = intList.Zip(doubleList, (Is, Ds) =>
{ return Is.Zip(Ds, (i, d) => new KeyValuePair<int, double>(i, d)).Distinct()
.ToDictionary(kv => kv.Key, kv => kv.Value); });
var yourLookup = dictionaries.Select(
dictionary => new { hashset = new HashSet<int>(dictionary.Keys), dictionary })
.ToDictionary(x => x.hashset, x => x.dictionary);
答案 1 :(得分:0)
有趣的问题。我创建了这个类:
class Mapper
{
public void Add(int n1, int n2, int n3, double f1, double f2, double f3)
{
int[] intArray = new int[] {n1,n2, n3};
Array.Sort(intArray);
Dictionary<int, double> dict = new Dictionary<int, double>();
dict[n1] = f1;
dict[n2] = f2;
dict[n3] = f3;
myDictionary[string.Join("_", intArray.Select(i=>i.ToString()))] = dict;
}
public Tuple<double, double, double> Find(int n1, int n2, int n3)
{
string key = CreateKey(n1, n2, n3);
if (!myDictionary.ContainsKey(key))
return null;
Dictionary<int, double> found = myDictionary[key];
return new Tuple<double, double, double>(found[n1], found[n2], found[n3]);
}
private string CreateKey(int n1, int n2, int n3)
{
int[] intArray = new int[] { n1, n2, n3 };
Array.Sort(intArray);
return string.Join("_", intArray.Select(i => i.ToString()));
}
private Dictionary<string, Dictionary<int, double>> myDictionary = new Dictionary<string, Dictionary<int, double>>();
}
通过在Add
中添加6元组,它对整数进行排序并将它们连接到唯一键字符串(例如1_1_2)。双打插入查找字典中。一些键可以在这里多次设置,但由于它们的int-&gt;双关联在一行中是相同的,因此无关紧要。
以Find
访问以相应的方式发生。
答案 2 :(得分:0)
[TestMethod]
public void test()
{
var data = new string[]{
"1 1 2 0.39785 0.39785 0.2043 36",
"1 1 3 0.409604 0.409604 0.180792 24",
"1 1 4 0.407281 0.407281 0.185438 24",
"1 1 5 0.404958 0.404958 0.190084 24",
"1 1 6 0.403399 0.403399 0.193203 24"
};
var dic = new FloatLookup(data);
var test1 = dic.GetValues(211).ToArray();
CollectionAssert.AreEquivalent(new float[] { 0.39785F, 0.39785F, 0.2043F }, test1);
var test2 = dic.GetValues(121).ToArray();
CollectionAssert.AreEquivalent(new float[] { 0.39785F, 0.2043F, 0.39785F }, test2);
var test3 = dic.GetValues(611).ToArray();
CollectionAssert.AreEquivalent(new float[] { 0.193203F, 0.403399F, 0.403399F }, test3);
}
class FloatLookup
{
Dictionary<int, KeyValuePair<int, float>[]> dic;
public FloatLookup(string[] data)
{
dic = data.Select(GetKeyValuePair).
ToDictionary(o => o.Key, o => o.Value);
}
public IEnumerable<float> GetValues(int num)
{
return GetValues(GetInts(num));
}
public IEnumerable<float> GetValues(IEnumerable<int> ints)
{
var key = GetKey(ints);
KeyValuePair<int, float>[] kvps = null;
if (!dic.TryGetValue(key, out kvps))
yield break;
foreach (var i in ints)
yield return kvps.First(o => o.Key == i).Value;
}
static KeyValuePair<int, KeyValuePair<int, float>[]> GetKeyValuePair(string line)
{
var items = line.Split(' ');
var ints = new string[] { items[0], items[1], items[2] }.
Select(o => int.Parse(o)).ToArray();
var floats = new string[] { items[3], items[4], items[5] }.
Select(o => float.Parse(o)).ToArray();
var kvps = Enumerable.Range(0, 3).Select(o =>
new KeyValuePair<int, float>(ints[o], floats[o])).Distinct().ToArray();
var key = GetKey(ints);
return new KeyValuePair<int, KeyValuePair<int, float>[]>(key, kvps);
}
static int[] GetInts(int num)
{
return num.ToString().ToCharArray().Select(o =>
int.Parse(o.ToString())).ToArray();
}
static int GetKey(IEnumerable<int> ints)
{
var ret = 0;
var ary = ints.ToArray();
Array.Sort(ary);
var c = 1;
for (int i = ary.GetUpperBound(0); i > -1; i--)
{
ret += ary[i] * c;
c *= 10;
}
return ret;
}