【问题标题】:Set intersection and difference with linked lists in C用C中的链表设置交集和差集
【发布时间】:2013-12-09 09:20:17
【问题描述】:

我正在尝试获取两个集合的交集和差异,每个集合都由这种形式的单链表表示

struct node{
    unsigned n;
    struct node *next;
};

我已经在之前的任务中编写了这个函数,它计算列表中元素的数量并确定某个元素是否包含在列表中。

int cardinality(struct node *s){
    struct node *tmp = s;
    int count = 0;

    while(tmp != NULL){
    tmp = tmp->next;
    count++;
    }

    return count;
}

int contains(struct node *s, int v){ /* returns 0 if in list, 1 if not in list */
    struct node *tmp = s;
    int contains = 1;

    while(tmp->next != NULL){
    if(tmp->n == v){
        contains = 0;
        break;
        } else{
        if(tmp == NULL) break;
        tmp = tmp->next;
    }
    }
    return contains;
}

现在我必须编写以下函数,但我不知道该怎么做。 我是否应该遍历一个列表并为列表中的每个元素循环遍历第二个列表以检查第二个列表中是否包含/不包含(差异)?对于这项任务来说,这似乎很复杂,必须有一种更简单的方法来做到这一点。 希望你能帮助我

void intersection(struct node *s1, struct node *s2, struct node **result){

}

void difference(struct node *s1, struct node *s2, struct node **result){

}

【问题讨论】:

  • 这两个函数为什么无效?对我来说,使用返回值而不是丑陋的第三个参数来报告结果似乎更合乎逻辑。
  • @wildplasser 实际上,要设置列表,您可以使用assign 函数,因此如果有人想用intersection 的结果覆盖列表,则可以是assign(&list, intersection(a, b))。这些函数基本上做了两个任务:计算一些集合操作和破坏性分配。
  • 不,该方法对于任务来说并不太复杂。您确实必须遍历一个列表,然后查找第二个列表中的每个项目。您可以为intersectiondifference 编写一个通用例程,它需要一个额外的布尔参数来指示是保留匹配项还是拒绝。那么intersectiondifference 只是包装器。
  • 好消息是:如果对列表进行排序,操作真的很简单。顺便说一句:OP 没有说是否允许更改两个“源”列表。

标签: c singly-linked-list set-intersection set-difference


【解决方案1】:

接下来实施这些:

// Copy one node s, giving the copy a NULL next pointer.
struct node *copy_one(struct node *s);

// Add the given node s to an existing list.
void add(struct node *s, struct node **existing);

这些对许多用途都很有用,但在这里您将编写它们:

add(copy_one(s), &existing_list);

建立你的结果。

现在相交的算法是:

set result empty
for all elements e in s1
   if e->val is contained in s2
       add a copy of e to result

对于区别s1 - s2,是

set result empty
for all elements e in s1
   if e is _not_ contained in s2
       add a copy of e to result

我会让你计算出 C。我给你一个完整的答案没有乐趣。

请注意,选择链表来表示集合对于学习 C 和链表来说很好,但通常不是最佳选择,因为它会导致大集合的性能下降。

【讨论】:

    【解决方案2】:

    我是否应该循环遍历一个列表以及列表循环中的每个元素 通过第二个列表来检查它是否是/不是(差异) 包含在第二个?

    如果您要将集合表示为未排序的链表,可以。还有更多 可用于实现集合操作的高效数据结构和算法 (例如排序数组),但如果这是家庭作业,你可能会被链表困住。

    对于这个任务来说这似乎太复杂了,必须有一个更简单的方法来做 这个。

    这是 C。您需要自己习惯处理大量低级细节,因为该语言在内置数据结构和算法方面没有提供太多功能。但是几个嵌套循环真的没什么大不了的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-16
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      相关资源
      最近更新 更多