免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 7341 | 回复: 24
打印 上一主题 下一主题

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

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-02-03 16:22 |只看该作者 |倒序浏览
本帖最后由 yccpp 于 2015-02-03 16:24 编辑

本人接触perl时间不长,只是知道它很强大。想用它进行数据的重新排列组合,向大神求一算法。原始数据是多行两列的数据,想把有公共数据的行写成一行且公共数据只出现一次。关键是公共数据不是固定的,下面是一个小例子,第一行和第二行的第一列有相同数22875,而第一行第二列的数据30588又出现在了第五行和第六行,需要把这些数据写成一行,如果没有公共数据,就按原始数据写出。整个数据文件见附件。非常感谢您的帮助!

原始数据
22875    30588     
22875    34747         
22912    34851
22963    35901      
22969    30588
30588    40791
30609    39143      
30609    40808

重新排列后
22875    30588   34747  22969  40791  
22912    34851  
22963    35901
30609    39143   40808

number.zip

78.96 KB, 下载次数: 21

数据

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
2 [报告]
发表于 2015-02-03 22:23 |只看该作者
  1. #!/usr/bin/perl -w

  2. my (%hash,$n);
  3. while(<DATA>){
  4.         chomp;
  5.         $n ++;
  6.         my $k;
  7.         my @row = (split);
  8.         map{$k = (exists $hash{$_}) ? $hash{$_} : $k}@row;
  9.         $k ||= $n;
  10.         map{$hash{$_} = $k}@row;
  11. }
  12. $n = 1;
  13. foreach my $key(sort {$hash{$a} <=> $hash{$b}} keys %hash){
  14.                 if($hash{$key} eq $n){
  15.                         print $key."\t";
  16.                 }else{
  17.                         print $/.$key."\t";
  18.                         $n = $hash{$key}
  19.                 }
  20. }
  21. __DATA__
  22. 22875    30588     
  23. 22875    34747         
  24. 22912    34851
  25. 22963    35901      
  26. 22969    30588
  27. 30588    40791
  28. 30609    39143      
  29. 30609    40808
复制代码
友情提示,上面这个做法是有问题的

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
3 [报告]
发表于 2015-02-03 23:25 |只看该作者
谢谢huang6894, 我试试。

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
4 [报告]
发表于 2015-02-04 00:21 |只看该作者
我试了一下,好像是有点问题,如果运行给出的一小段数据,结果是正确的,如果是附件中的数据,结果有点问题,有些行只有一个数据,至少应该是两个的,请问huang6894,在您给出的程序中如何实现文件的输入输出。谢谢。

论坛徽章:
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
5 [报告]
发表于 2015-02-04 11:36 |只看该作者
本帖最后由 xiumu2280 于 2015-02-04 11:38 编辑
  1. my @data = map {[split]}<DATA>;

  2. my @out_data;

  3. foreach my $new (@data) {
  4.         my %hash;
  5.         foreach my $ori (@data) {
  6.                 @hash{@{$new}} = @{$new};
  7.                 if ($hash{$ori->[0]} || $hash{$ori->[1]}) {
  8.                         push @{$new},@{$ori};
  9.                 }
  10.         }
  11.         @hash{@{$new}} = @{$new};
  12.         push @out_data,join "\t",sort keys %hash;
  13. }

  14. my %hash;
  15. @hash{@out_data} = @out_data;
  16. for my $line (keys %hash) {
  17.         print "$line\n";
  18. }


  19. __DATA__
  20. 22875    30588     
  21. 22875    34747         
  22. 22912    34851
  23. 22963    35901      
  24. 22969    30588
  25. 30588    40791
  26. 30609    39143      
  27. 30609    40808
复制代码

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
6 [报告]
发表于 2015-02-04 17:14 |只看该作者
xiumu2280,谢谢你的帮助,我试试你的代码。

论坛徽章:
0
7 [报告]
发表于 2015-02-04 17:35 |只看该作者
回复 5# xiumu2280
大神my @data = map {[split]}<DATA>;中括号什么意思啊 为什么换成括号或去掉括号就不可以了呢 而
  1. my @data = map {[split]}<DATA>;

  2. my @out_data;

  3. foreach my $new (@data) {
  4.         print $new;
  5. }
  6.       


  7. __DATA__
  8. 22875    30588     
  9. 22875    34747         
  10. 22912    34851
  11. 22963    35901      
  12. 22969    30588
  13. 30588    40791
  14. 30609    39143      
  15. 30609    40808
复制代码
这样会报错
而把中括号去了或换成圆括号就可以了 这是为什么呢

   

论坛徽章:
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
8 [报告]
发表于 2015-02-04 17:42 |只看该作者
my @data = map {[split]}<DATA>;  这个是二维数组

涉及到引用的知识  可以百度  perl引用

下面也是相同的原因,变成()之后,@data是普通数组,所以简单的foreach又可以了

你可以用Data:umper模块 ,看一看数据结构,就明白了
回复 7# chenyuluoyan沉鱼落


   

论坛徽章:
0
9 [报告]
发表于 2015-02-04 20:42 |只看该作者
回复 8# xiumu2280
明白了 谢谢大神


   

论坛徽章:
2
拜羊年徽章
日期:2015-03-03 16:15:432015年亚洲杯之韩国
日期:2015-03-12 20:29:56
10 [报告]
发表于 2015-02-04 21:56 |只看该作者
谢谢大神,计算结果是正确的。数据量小时,计算很快,我试了一下几百组数据,结果都是对的且挺快的,当数据量较大时,比如我附件中的数据,有1万多行,程序已经运行好几个小时了,还没有结果,等待中。再次谢谢xiumu2280 。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP