我有一个ValuePair类,其中定义了两个属性:
public class ValuePair: IEquatable<ValuePair>
{
public string value1;
public string value2;
public ValuePair(string v1, string v1)
{
this.value1 = v1;
this.value2 = v2;
}
...
}
我在List中有一些测试数据,如下所示:
List<ValuePair> pairs = new ValuePair<ValuePair>();
pairs.Add(new ValuePair("A","B"));
pairs.Add(new ValuePair("A","C"));
pairs.Add(new ValuePair("B","C"));
pairs.Add(new ValuePair("C","D"));
我的目标是保持对[0]和对[1],因为对&#34; A,B&#34;和&#34; A,C&#34;是唯一的,但要删除对[2]因为关系&#34; B,C&#34;已经在前两个关系中被捕获。对[3]应该保留,因为&#34; C,D&#34;关系是独一无二的。
我有一种感觉,这个问题的解决方案将是递归的,这是我很少有的经验。我开始沿着向ValuePair类添加方法的路径看起来像这样:
public string EqualToEither(ValuePair v)
{
if (v.value1 == this.value1 || v.value1 == this.value2)
return v.value1;
else if (v.value2 == this.value1 || v.value2 == this.value2)
return v.value2;
else
return string.Empty;
}
我已经开始尝试在这样的函数中使用上面的方法,但是我对下一步做什么感到困惑:
for (int i = 0; i < pairs.Count; i++)
{
for (int j = pairs.Count - 1; j >= 0; j--)
{
if (pairs[j].EqualToEither(pairs[i]) != string.Empty)
{
pairs[j].EqualToEither(pairs[i]);
}
else
{
continue;
}
}
}
我觉得我很亲密,但仍然无法得到它。有人可以提供一些指导吗?如果我以完全错误的方式接近这个,请告诉我,谢谢!
答案 0 :(得分:2)
我最近必须解决类似的问题,这是我如何解决它:
在我看来,通过将相互关联的元素组合在一起,最好地体现了及物性。
对于每对,您必须验证它是否已属于某个组(两个值都已在该组中),或者它是否扩展了组的关系(只有一个值属于该组)。
如果它不属于任何组,它将成为一个新组。
如果两个值都属于不同的组,则必须合并它们。
如上所述,这与生成树密切相关。
一种解决方案可能是使用HashSets来表示关系的传递性(在我的情况下我没有使用HashSets,有很多可能的解决方案)。 每个HashSet都代表一组相互关联的元素。
使用HashSet的示例实现:
List<ValuePair> pairs = new List<ValuePair>();
pairs.Add(new ValuePair("A", "B"));
pairs.Add(new ValuePair("A", "C"));
pairs.Add(new ValuePair("B", "C"));
pairs.Add(new ValuePair("C", "D"));
List<ValuePair> uniquePairs = new List<ValuePair>();
// this list is not really needed if all you care about
// is getting the resulting groups
List<HashSet<string>> sets = new List<HashSet<string>>();
foreach (ValuePair pair in pairs)
{
int value1Set = -1;
int value2Set = -1;
for (int i = 0; i < sets.Count; i++)
{
HashSet<string> set = sets[i];
if (set.Contains(pair.value1))
value1Set = i;
if (set.Contains(pair.value2))
value2Set = i;
}
if (value1Set == -1 && value2Set == -1)
{
// we have a new set
sets.Add(new HashSet<string> {pair.value1, pair.value2});
}
else if (value1Set == -1)
{
sets[value2Set].Add(pair.value1);
}
else if (value2Set == -1)
{
sets[value1Set].Add(pair.value2);
}
else
{
if (value1Set == value2Set)
{
// duplicate entry, skip the add
continue;
}
// merge the sets at value1Set and value2Set
foreach (string value in sets[value2Set])
{
sets[value1Set].Add(value);
}
sets.RemoveAt(value2Set);
}
uniquePairs.Add(pair);
}