免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: yccpp
打印 上一主题 下一主题

新手求一个算法 [复制链接]

论坛徽章:
8
技术图书徽章
日期:2013-09-30 08:51:28技术图书徽章
日期:2013-12-11 09:26:39白羊座
日期:2013-12-27 15:27:13金牛座
日期:2014-01-06 09:13:05天蝎座
日期:2014-01-21 14:23:28酉鸡
日期:2014-05-09 16:51:12卯兔
日期:2014-08-11 16:49:1515-16赛季CBA联赛之八一
日期:2017-08-14 23:24:57
11 [报告]
发表于 2015-02-05 09:09 |只看该作者
把文件内容按大小排个序
再把文件分割,分别运行这个程序
最后把结果和在一起,再运行一次
回复 10# yccpp


   

论坛徽章:
0
12 [报告]
发表于 2015-02-05 10:10 |只看该作者
#!/usr/bin/perl

use strict;
use warnings;

#if success output to outputNumber.txt;
if (@ARGV < 1)
{
        print "usage:mergeData.pl inputfile\n";
        exit(1);
}

my %datasHash;

open my $fileHandle, "<", $ARGV[0] or die "open $ARGV[0] failed$!";
while(my $lineData = <$fileHandle>)
{
        chomp $lineData;
        if($lineData =~ /^\s+$/)
        {
                next;
        }
        $lineData =~ s/^\s+//;
        $lineData =~ s/\s+$//;
        my @wordArray = split /\s+/, $lineData;
        my @exitsKey;
        my @notExitsKey;
        foreach(@wordArray)
        {
                if( exists $datasHash{$_})
                {
                        push @exitsKey,$_;
                }
                else
                {
                        push @notExitsKey,$_;
                }
        }
       
        if (@exitsKey == 0)
        {
                foreach(@wordArray)
                {
                        $datasHash{$_} = \@wordArray;
                }
        }
        else {
                my @mergeArray = @notExitsKey;
               
                for(my $index = 0; $index < @exitsKey; $index++)
                {
                        my $ref1 = $datasHash{$exitsKey[$index]};
                       
                        @mergeArray = (@$ref1, @mergeArray);
                       
                        @$ref1 = ();
                }
               
                foreach(@mergeArray)
                {
                        $datasHash{$_} = \@mergeArray;
                }
        }
}

my %refHash;
open my $outHandle, ">", "outputNumber.txt" or die "failed open outputNumber.txt $!";
foreach (keys %datasHash)
{
        my $ref1 = $datasHash{$_};
        if ( ! exists $refHash{$ref1})
        {
                my @result = join " ",@$ref1;
                #print @result, "\n";
                print $outHandle @result,"\n";
                $refHash{$ref1} = 1;
        }
}

论坛徽章:
0
13 [报告]
发表于 2015-02-05 10:12 |只看该作者
初学Perl代码不够简练,多多指教!

论坛徽章:
8
技术图书徽章
日期:2013-09-30 08:51:28技术图书徽章
日期:2013-12-11 09:26:39白羊座
日期:2013-12-27 15:27:13金牛座
日期:2014-01-06 09:13:05天蝎座
日期:2014-01-21 14:23:28酉鸡
日期:2014-05-09 16:51:12卯兔
日期:2014-08-11 16:49:1515-16赛季CBA联赛之八一
日期:2017-08-14 23:24:57
14 [报告]
发表于 2015-02-05 12:03 |只看该作者
这个应该会快一些
  1. my %hash_all;
  2. while (<DATA>) {
  3.         chomp;
  4.         my @data = split /\s+/,my $line =$_;
  5.         push @{$hash_all{$data[0]}},$data[1];
  6.         push @{$hash_all{$data[1]}},$data[0];
  7. }

  8. my %out_data;

  9. while (my ($key,$value) = each %hash_all) {
  10.         my @all = @{$value};
  11.         BEGIN:
  12.         my %hash;
  13.         @hash{@all} = @all;
  14.         my $num_r = keys %hash;
  15.         for my $cell (keys %hash) {
  16.                 if ($hash_all{$cell}) {
  17.                         push @all,@{$hash_all{$cell}};
  18.                 }
  19.         }
  20.         @hash{@all} = @all;
  21.         my $num_l = keys %hash;
  22.         if ($num_l ne $num_r) {
  23.                 goto BEGIN;
  24.         }
  25.         my $new_line = join "\t",sort keys %hash;
  26.         print "$new_line\n" if !$out_data{$new_line}++;
  27. }


  28. __DATA__
  29. 22875    30588     
  30. 22875    34747         
  31. 22912    34851
  32. 22963    35901      
  33. 22969    30588
  34. 30588    40791
  35. 30609    39143      
  36. 30609    40808
复制代码

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
15 [报告]
发表于 2015-02-05 16:50 |只看该作者
谢谢laohai8080 和xiumu2280 的热心帮助。 xiumu2280的新代码快了不止一些,附件中的数据几秒就处理完了,非常感谢。我有两个问题想请教您,第一个问题是能否让处理的结果按每行数据的多少从大到小排序,比如输出的结果如下
22875    30588   34747 22969  40791
30609    39143   40808
22912    34851
22963    35901
第二个问题是自己对您的代码理解不深,从输出结果看,不是从第一行的数据开始排列的,好像比较随机,能不能请xiumu2280帮忙解读一下。谢谢。

论坛徽章:
0
16 [报告]
发表于 2015-02-05 16:50 |只看该作者
回复 8# xiumu2280
  1. @hash{@{$new}} = @{$new};
  2.                 if ($hash{$ori->[0]} || $hash{$ori->[1]}) {
  3.                         push @{$new},@{$ori};
复制代码
这段代码可以解释一下吗 @hash{@$new}}表示什么呢
   

论坛徽章:
8
技术图书徽章
日期:2013-09-30 08:51:28技术图书徽章
日期:2013-12-11 09:26:39白羊座
日期:2013-12-27 15:27:13金牛座
日期:2014-01-06 09:13:05天蝎座
日期:2014-01-21 14:23:28酉鸡
日期:2014-05-09 16:51:12卯兔
日期:2014-08-11 16:49:1515-16赛季CBA联赛之八一
日期:2017-08-14 23:24:57
17 [报告]
发表于 2015-02-06 09:02 |只看该作者
这是哈希切片  用来给数组去重回复 16# chenyuluoyan沉鱼落


   

论坛徽章:
8
技术图书徽章
日期:2013-09-30 08:51:28技术图书徽章
日期:2013-12-11 09:26:39白羊座
日期:2013-12-27 15:27:13金牛座
日期:2014-01-06 09:13:05天蝎座
日期:2014-01-21 14:23:28酉鸡
日期:2014-05-09 16:51:12卯兔
日期:2014-08-11 16:49:1515-16赛季CBA联赛之八一
日期:2017-08-14 23:24:57
18 [报告]
发表于 2015-02-06 09:07 |只看该作者
因为这次是存的哈希,而遍历哈希的时候,是不像数组一样有顺序的。
如果你想这样从大到小的排列
可以对得到的数据进行二次处理,把这次得到的数据按大小排序就好了。
回复 15# yccpp


   

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
19 [报告]
发表于 2015-02-06 20:52 |只看该作者
谢谢xiumu2280,涨姿势了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
20 [报告]
发表于 2015-02-08 15:36 |只看该作者
回复 18# xiumu2280


    那有没有办法让数据输出就是按照读入的顺序呢? 我的意思是比如输出时的键值按照按照他给的数据键对应后面依次为第一次出现该键的值,第二次出现该键的值。 因为如果后面的数据不是数字,而是一些无规律的字母,比如地名,是没有办法再处理的。 特别是当数据非常大的时候。 求指教!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP