在少于O(n^2)-C的未排序结构数组中查找重复元素

在少于O(n^2)-C的未排序结构数组中查找重复元素,c,arrays,algorithm,struct,C,Arrays,Algorithm,Struct,结构: struct info{ int id; int time; int x; int y; }; 结构数组将始终遵循以下条件: 时间变量将始终以排序的形式给出,并与相应的id相对应 如果变量:time、x、y相等且id不同,则视为重复 搜索是通过查找两个不同的id值来完成的 示例1:查找配对的副本-001 002 struct info *arr = {{002, 10, 30, 40}, {001, 10, 30, 40}, {001, 15, 45

结构:

struct info{
    int id;
    int time;
    int x;
    int y;
};
结构数组将始终遵循以下条件:

  • 时间变量将始终以排序的形式给出,并与相应的id相对应

  • 如果变量:
    time
    x
    y
    相等且
    id
    不同,则视为重复

  • 搜索是通过查找两个不同的id值来完成的

示例1:查找配对的副本-001 002

struct info *arr = {{002, 10, 30, 40}, {001, 10, 30, 40}, {001, 15, 45, 50}, {001, 20, 23, 37}}
struct info *arr = {{002, 15, 45, 50}, {002, 16, 21, 13}, {001, 10, 30, 40}, {001, 15, 45, 50},}
输出:复制对将位于位置0和1

示例2:查找配对的副本-001 002

struct info *arr = {{002, 10, 30, 40}, {001, 10, 30, 40}, {001, 15, 45, 50}, {001, 20, 23, 37}}
struct info *arr = {{002, 15, 45, 50}, {002, 16, 21, 13}, {001, 10, 30, 40}, {001, 15, 45, 50},}
输出:复制对将位于位置0和3

示例3:查找配对的副本-003 004

struct info *arr = {{004, 6, 47, 52}, {003, 6, 47, 52}, {001, 10, 30, 40}, {002, 15, 45, 50},}
输出:复制对将位于位置0和1


有可能在不到
O(n^2)
的时间内解决这个问题吗?

可能是一个简单的解决方案:对数组进行排序是
O(n*log(n))
,然后查找重复项是一个复杂的单循环
O(n)
。因此,总的来说,
O(n*log(n))
的复杂性比您想要击败的
O(n^2)
要小。希望有帮助。

可能是一个简单的解决方案:对数组排序是
O(n*log(n))
,然后查找重复的条目是一个复杂的单循环
O(n)
。因此,总的来说,
O(n*log(n))
的复杂性比您想要击败的
O(n^2)
要小。希望有帮助。

向哈希表中添加N个元素可以在O(N)中完成,因此可以在O(N)中完成

Perl的工作演示:

#!/usr/bin/perl
use strict;
use warnings qw( all );

my @infos = (
   { id => '002', time => 10, x => 30, y => 40 },
   { id => '001', time => 10, x => 30, y => 40 },
   { id => '001', time => 15, x => 45, y => 50 },
   { id => '001', time => 20, x => 23, y => 37 },
);

my %seen;
for my $i (0..$#infos) {
   my $info = $infos[$i];
   my $key = join(':', $info->{time}, $info->{x}, $info->{y});
   push @{ $seen{$key} }, $i;
}

for my $matches (values(%seen)) {
   next if @$matches == 1;

   print("Duplicates:\n");
   for my $i (@$matches) {
      my $info = $infos[$i];
      printf("  %d %s %d %d %d\n", $i, @$info{qw( id time x y )});
   }
}
输出:

Duplicates:
  0: 002 10 30 40
  1: 001 10 30 40

向哈希表添加N个元素可以在O(N)中完成,因此可以在O(N)中完成

Perl的工作演示:

#!/usr/bin/perl
use strict;
use warnings qw( all );

my @infos = (
   { id => '002', time => 10, x => 30, y => 40 },
   { id => '001', time => 10, x => 30, y => 40 },
   { id => '001', time => 15, x => 45, y => 50 },
   { id => '001', time => 20, x => 23, y => 37 },
);

my %seen;
for my $i (0..$#infos) {
   my $info = $infos[$i];
   my $key = join(':', $info->{time}, $info->{x}, $info->{y});
   push @{ $seen{$key} }, $i;
}

for my $matches (values(%seen)) {
   next if @$matches == 1;

   print("Duplicates:\n");
   for my $i (@$matches) {
      my $info = $infos[$i];
      printf("  %d %s %d %d %d\n", $i, @$info{qw( id time x y )});
   }
}
输出:

Duplicates:
  0: 002 10 30 40
  1: 001 10 30 40

你会用witch变量对数组排序吗?身份证件您推荐的任何排序算法?使用,例如,
qsort
;编写一个自定义比较函数,该函数根据以下组合进行排序:
time
,然后是
x
,然后是
y
,然后是
id
。然后两个时间相等的元素x,y将紧跟在一起;比较
id
s,然后查找重复的元素。您会使用witch变量对数组进行排序吗?身份证件您推荐的任何排序算法?使用,例如,
qsort
;编写一个自定义比较函数,该函数根据以下组合进行排序:
time
,然后是
x
,然后是
y
,然后是
id
。然后两个时间相等的元素x,y将紧跟在一起;比较
id
s,然后查找重复的元素。不确定从何处获得n^2。这里需要线性搜索,每个元素只需O(n)。如果你有内存,在最坏的情况下,你会得到2*n:插入哈希表(+检查)是O(n)不确定你从哪里得到n^2。这里需要线性搜索,每个元素只需O(n)。在pairf的最坏情况下,如果您有内存,您将得到2*n:插入哈希表(+检查)是O(n)是什么,当列表中的每个元素都导致哈希冲突时?例如,当散列函数为
h(element)=0
?@ensc时,会发生拆分或重新灰化。无论采用哪种方式,都会使用一个新的哈希扰动键来保证它不会再次发生。您甚至可以在统计上不可能的情况下重试,即所有元素仍然全部归为一个桶。是的,O(N)实际上只是平均情况,但实际上不可能超过平均情况,除非统计上不可能的情况连续发生两次。即使是一个恶意的代理也不能使O(N)变得更糟糕,如果写得正确的话。因此,无论出于何种目的,它都是O(N)。
。。。当哈希函数为h(element)=0时,则:使用不同的sane哈希函数。(顺便说一句:这种对冲突的恐惧是病态的)比
O(n log(n)
)要好得多;感谢您编辑我的答案。什么是,当列表中的每个元素都导致哈希冲突时?例如,当哈希函数为
h(element)时=0
?@ensc,则会发生拆分或重新灰化。无论采用哪种方式,都会使用新的哈希扰动键来保证它不会再次发生。您甚至可以在统计上不可能的事件中重试,即所有元素仍然都会进入单个存储桶。因此,是的,O(N)实际上只是平均情况,但实际上不可能超过平均情况。只有在统计上不可能的情况连续发生两次的情况下。如果编写正确,即使是恶意代理也不会使O(N)变得更糟。因此,出于所有目的和目的,当哈希函数为h(元素)时,它是O(N)。
=0
然后:使用不同的sane散列函数。(顺便说一句:这种对碰撞的恐惧是病态的)比
O(n log(n)
好得多;谢谢你编辑我的答案。