【问题标题】:Combination without repetition无重复组合
【发布时间】:2010-02-28 13:36:53
【问题描述】:

我有收藏List<Car>

如何将此集合中的每个项目与其他项目进行比较而不重复。

例如:

  1. 迭代:

这辆车是奥迪,第二辆车是宝马

bool IsSimilar(Car secondCar)
{
  if(this.Name==secondCar.Name) return true;
  return false;
}

这是不允许的:

n 次迭代

这辆车是宝马,第二辆车是奥迪

bool IsSimilar(Car secondCar)
{
  if(this.Name==secondCar.Name) return true;
  return false;
}

更清晰:

List<Car> car=new List<Car>();
List<Pair> pairs=new List<Pair>();
pairs.Cars=new List<Car>();

foreach(Car car in cars)
{
  foreach(Car secondCar in cars)
  {
    if(secondCar!=car)
    {
      if(car.Name==secondCar.name && car.Owner==secondCar.Owner)
      {
        Pair pair=new Pair();
        pair.Cars.Add(car);
        pair.Cars.Add(secondCar);
        pairs.Add(pair);
      }
    }
  }
}

我只是不想比较汽车两次(你知道第一次迭代比较汽车 1 和汽车 2,下一个汽车 2 是基础汽车,汽车 1 是第二汽车)

对不起我糟糕的英语

【问题讨论】:

  • 不确定你想要什么。您能否通过比较来解释您的意思(检查是否相等,对其进行排序,...)。输出应该是什么样的,您期望比较的输出是什么。
  • 不清楚您要做什么。您是否正在尝试创建一个没有重复的排序列表? - 如果是,您是否尝试过使用 LINQ?
  • 我想搜索具有相同属性的项目。如果我有 100 个项目,我想使用这样的方法: foreach(Car car in cars) { foreach(Car secondCar in cars) { if(secondCar!=car) { car​​1.IsSimilar(car2); } } } 但是没有重复,所以如果我在我不想再做一次之前比较汽车 1 和汽车 2。方法 IsSimilar 不会返回 bool,而是执行以下操作: List pairs=new List(Pair)
  • 也许将其命名为组合并不是一个好主意...它引入了混乱...
  • 还有——如果 Car1 与 Car3 相似,那么是否一定意味着 Car3 与 Car1 相似?

标签: c# algorithm combinations


【解决方案1】:

不要循环遍历集合,循环遍历索引

for (i = 0; i < length(cars); i++) {
    for (j = i+1; j < length(cars); j++) {
        <do comparison>
    }
}

【讨论】:

  • 不,不是这个。看:i=0,j=1,我们有 car1 和 car2。 i=1,j=0,我们有 car2 和 car 1。我不想重复相同的工作(检查对象的属性,因为它在之前的迭代中已经完成)
  • 当 i = 1 时,j 将从 i + 1 = 1 + 1 = 2 开始,因此您不会两次比较事物。当 i = 1 时,j 永远不会为 0。
  • @phenevo,使用 sirlark 的方法,你永远不可能有 i=1 和 j=0,因为 j 的开始总是比 i 的当前值高 1。
  • 是的,对不起(咖啡昨天结束了:))
【解决方案2】:

这是从列表中获取唯一组合的简单方法。

for(int i = 0; i < list.Count; i++)
    for(int j = i + 1; j < list.Count; j++)
        // perform operation

【讨论】:

  • 不,不是这个。看:i=0,j=1,我们有 car1 和 car2。 i=1,j=0,我们有 car2 和 car 1。我不想重复相同的工作(检查对象的属性,因为它在之前的迭代中已经完成)
  • @phenevo:当 i=1 时,j 将从 2 开始,永远不会为 0。这就是重点。
【解决方案3】:

我将重复其他人所说的话并向他们解释您的 cmets(这是错误的):

for (int i = 0; i < N; i++) {
    for (int j = i+1; j < N; j++) {
        <do something>
    }
}

您对这种技术的评论是“不,不是这个。看:i=0,j=1 我们有 [...]。i=1,j=0 我们有 [. ..]".

您错过的是j 总是从i+1 开始。因此,您提到的i=1 and j=0永远不会出现这种情况!

【讨论】:

    猜你喜欢
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多