【问题标题】:What is the ideal way to make a unique list of values in C?在 C 中创建唯一值列表的理想方法是什么?
【发布时间】:2011-04-04 00:24:36
【问题描述】:

假设我们有

typedef struct {
  int value1;
  int value2;
} values_t;

values_t* values;

values[i].value1values[i].value2 对填充,它们可能是唯一的,也可能不是唯一的。

我们要填充

values_t* values_unique;

仅适用于 values 中的 unique 对,按照它们首先出现在 values 中的顺序。

在 C 中执行此操作的理想方法是什么?

编辑:假设它们是正确分配的指针;以上只是伪代码。

【问题讨论】:

  • values_t values 不是数组。
  • values[i].value1 将是一个编译错误。您可以发布您拥有的实际代码吗?
  • 是的,抱歉,假设它们是正确分配的指针;以上只是伪代码。

标签: c


【解决方案1】:

您可能使用值的散列,维护散列和相应值的列表,并且只向 values_unique 数组添加一个新对(问题 does 最初没有声明为一个数组),如果它没有通过哈希找到。如果列表很大,使用散列而不是顺序搜索整个列表的速度会非常显着。

【讨论】:

  • 是的,抱歉,假设它们是正确分配的指针;以上只是伪代码。
  • 如果你的哈希实现非常简单,每次你在新列表中追加一个值v,你可以在你的哈希表中添加一个从h(v)到元组索引位置的映射你已经添加了。然后在检查v2是否已经在列表中时,在哈希中找到h(v2)并使用索引位置找到v,然后您可以将其与v2进行比较以确定它们是否相同。跨度>
【解决方案2】:

大概是这样的(很久没用C写代码了,也没有测试过代码):

#include<stdlib.h>
#include<stdio.h>

typedef struct {
  int value1;
  int value2;
} values_t;
values_t* values;
size_t values_size = 100;
values_t* values_unique;
size_t values_unique_size;
int valcmp(const values_t* a, const values_t* b)
{
    //a < b -> -1
    //a == b -> 0
    //a > b -> 1
    return (a->value1 == b->value1) ? ((a->value2 == b->value2) ? 0 : ((a->value2 < b->value2) ? -1 : 1)) : ((a->value1 < b->value1) ? -1 : 1);
}
int main(void)
{
    values = malloc(values_size * sizeof(values_t));
    values_unique = malloc(values_size * sizeof(values_t));
    //fill the values table
    memcpy(values_unique, values, values_size * sizeof(values_t));
    qsort(values_unique, values_size, sizeof(values_t), valcmp);
    int i;
    //hopefully values_size > 0
    for(i = 1, values_unique_size = 1; i < values_size; ++i)
        if(valcmp(&values_unique[i], &values_unique[values_unique_size - 1]) != 0)
            values_unique[values_unique_size] = values_unique[i];
}

在 c++ 中也一样:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

vector<pair<int,int> > V, V_unique;

int main()
{
    V_unique = V;
    sort(V_unique.begin(), V_unique.end());
    V_unique.resize(unique(V_unique.begin(), V_unique.end()) - V_unique.begin());
}

【讨论】:

    【解决方案3】:

    我知道建议一种不同的语言是相当烦人的,但使用 C++ stl 将是微不足道的。

    set<values_t> mySet();
    
    for(int i=0; i < number_of_values; i++)
    {
        mySet.insert(values[i]);
    }
    
    values_t * values_unique = new values_t[mySet.size()];
    
    int j=0;
    
    for(set<values_t>::iterator i = mySet.begin(); mySet.end() != i; i++)
    {
        values_unique[j] = *i;
        j++
    }
    

    【讨论】:

    • 这缺少一个比较器/operator&lt; 用于values_t。另外,为什么不直接使用基于集合输入迭代器的构造函数和std::copy() 而不是手动插入/复制?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2021-05-16
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多