记录查重算法

记录查重算法

有个文件,有很多条如下的记录:
insert into special values(999678,'10099',0,0,50,'2008-08-08','2099-01-01');
要对其中第二个字段查重,如果拷贝多一份,一条条地遍历,效率非常低下;如果用哈希,效率还是非常高的,目前有点小问题,还没实现;
不知道各位高手还有没有其它好点的算法,谢谢。

用 hash 有什么问题?


QUOTE:
原帖由 dl0622 于 2008-10-11 23:04 发表
有个文件,有很多条如下的记录:
insert into special values(999678,10099,0,0,50,2008-08-08,2099-01-01);
要对其中第二个字段查重,如果拷贝多一份,一条条地遍历,效率非常低下;如果用哈希,效率还是非常 ...

方法是有的,但是在 perl 中当然还是 hash 最方便,但是 hash 内存占用比较大。
看有多少条记录,我在 1G 内存的机器上用 50W key 的 hash 是没问题的。
我写了一个,不过是有问题的,请大家指教:
1、第二行为啥出错?参数个数是2时一样提示出错,晕了。
2、我写的第二个循环是得不到正确的重复数据的,因为所有项都定义了hash,所以每隔一行$count就会等于2,会把很多不重复的打印到文件上去, 请大家指教一下该怎么修改,谢谢!

#!/usr/bin/perl
die qq/usage: perl $0 <sp_no> <files>\n/ unless @ARGV != 2;
unlink"pick_all_same.sql";
my $sp_no = shift;
my $data_file = shift;
keys %hash = 100*10000;

open SP_NO, $sp_no or die $!;
open RS, ">>pick_all_same.sql" or die $!;
while ($line=<SP_NO>)
{
    chomp($line);
    @fields = split (/'/,$line);
    $hash{$fields[1]} = $fields[1];
}
close SP_NO;

open FH, $data_file or die $!;
my $count = 0;
while ($line2=<FH>)
{
    chomp($line2);
    @fields2 = split (/'/,$line2);
    if (defined $hash{$fields2[1]})
    {
        $count = $count+1;
        if($count == 2)
        {
            print RS ($line2."\n");
            $count = 0;
        }
    }
}
close FH;

也就是说$fields[1]既是键又是值,如果相同的值出现了两次,我就打印该行记录到文件中,该怎么弄?
太长了,你不就是要检查第二个字段是否有重复么?
#!/usr/bin/perl

use warnings;
use strict;

my %records;

my $your_data_file = 'filename';

open(FILE, $your_data_file) or die $!;
while (<FILE>) {
    (undef, my $record) = split(',');

    if (defined $records{$record})
    { print $.; next; }

    $records{$record} = 1;
}
close FILE;




QUOTE:
原帖由 dl0622 于 2008-10-12 13:20 发表
我写了一个,不过是有问题的,请大家指教:
1、第二行为啥出错?参数个数是2时一样提示出错,晕了。

@ARGV == 2;
思路太好了,谢谢!
1、另外问问这句什么意思?undef指的是什么?左表达式对应的是右表达式的开始两项吗?    (undef, my $record) = split(',');
2、$.是什么意思?($.应该改为$_吧,不过我还是想知道$.是什么意思)

帮忙解答楼上第一个问题吧,谢谢~!
你应该多看看小骆驼:)
1。 undef 在此地有占位作用,你可以理解为一个无用的变量,这句可以写为 (my $xxxx, my $record) = split(','); 但是 $xxxx在此毫无意义(我们并不关心这个),所以没有必要浪费资源赋值给一个多余的$xxxx,so Perl 有这样的占位符号出现,程序根本不关心这个位置的数值,而直接抛弃。
2 。 关于 Perl 的特殊符号,本版的精华中有,小骆驼中也有, $. 是表示 行数