免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2985 | 回复: 9

特定数字如何实现重新排序? [复制链接]

论坛徽章:
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
发表于 2014-11-09 10:27 |显示全部楼层
30可用积分
各位大神,想请教个问题:
对于这样的数据:

  1. __DATA__
  2. a        b        s[1];p[2]        [1]d;[2]t
  3. b        c        s[1];q[2];        [1]d;[2]y;
  4. a        d        c[1,3];        [1]e;[2]t;[3]b;
  5. b        d        p[1];y[2]        [1]d;[2]y2;
  6. e       f       abb     hhh
  7. g       n       .       1
  8. f       n       6[1-4]       [1]e;[2]t;[3]b2;[4]h;
复制代码
第 3 和 第4列的中括号'[]'内的数字是一一对应的,比如第一行中第三列的s[1]对应于第四列的[1]d,我想对[]里面的数字实现在文本的重新排列,比如第一行是[1][2][3],第二行的编码需要从[4]开始,以此类推。现在我想:

1、排除第 3 或者第 4 列任何一列为"."的行(第 6 行),对于其它行,如果第 3 和第 4 列没有[\[0-9]+\]的,在第 3 列后面和第 4 列前面加上[1](第5行);如果第 3 列在一个中括号内有两个数字,需要拆分,如第 3 行c[1,3]=》c[1];c[2];c[3]; 第7行: 6[1-4]=》6[1];6[2];6[3];6[4];

2、对得到的数据的第 3 和第 4 列存进数组实现重新排序,但保证两列的项依旧一一对应,并且整体唯一。

3、同一行中重复出现的,采用合并序号。

  1. __DATA__
  2. s[1];p[2]        [1]d;[2]t  
  3. s[1];q[2];        [1]d;[2]y;         #s[1]和[1]d与第 1 行重复,去重,q[2]、[2]y升序为q[3]、[3]y
  4. c[1,3];        [1]e;[2]t;[3]b;       #c[1,3]; 含两个数字,拆分为c[1](对应[1]e);c[2](对应[2]t);c[3](对应[3]b);,升序为c[4];c[5];c[6]和[4]e;[5]t;[6]b,虽然c在该处重复了3次,不过第 4 列不重复,故而对c实现合并序号,c[4];c[5];c[6] =》 c[4,6]
  5. p[1];y[2]        [1]d;[2]y2;        #p[1]和[1]d与第 1 行重复,去重,y[2]、[2]y2升序为y[7]、[7]y2
  6. abb     hhh             #abb和hhh无序号,且不为“.”,在第 3 列后面和第 4 列前面加上[1],abb[1]、[1]hhh升序为abb[8]、[8]hhh
  7. .       1               #第 3 列为“.”排除这一行
  8. 6[1-4]       [1]e;[2]t;[3]b2;[4]h;          #拆分,升序,合并
复制代码
最终得到两个数组:

数组1(第3列):

  1. s[1]
  2. p[2]
  3. q[3]
  4. c[4,6]
  5. y[7]
  6. abb[8]  
  7. 6[9,12]
复制代码
数组2(第4列):

  1. [1]d
  2. [2]t
  3. [3]y
  4. [4]e
  5. [5]t
  6. [6]b
  7. [7]y2
  8. [8]hhh
  9. [9]e
  10. [10]t
  11. [11]b2
  12. [12]h;
复制代码
这个好难啊,希望各位大哥给点意见

最佳答案

查看完整内容

这个问题引起了大家的极大兴趣。觉得很不错,受益匪浅,谢谢!我的理解 ~ {:2_172:}回复 1# huang6894

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
发表于 2014-11-09 10:27 |显示全部楼层
这个问题引起了大家的极大兴趣。
觉得很不错,受益匪浅,谢谢!
我的理解 ~ {:2_172:}
  1. my ( $V1, @data, %dup );

  2. while (<DATA>) {
  3.     my ( undef, undef, $col3, $col4 ) = split;
  4.     next if grep { /^\.$/ } $col3, $col4;
  5.     my @elem = split /;/, $col3;
  6.     my @exists;
  7.     for my $e (@elem) {
  8.         my ( $K, $v, $v2 ) = split /[\[\],-]/, $e;
  9.         if ( $dup{$K}++ ) {
  10.             push @exists, (0) x ( $v2 ? $v2 - $v + 1 : 1 );
  11.             next;
  12.         }
  13.         $V1 ||= ( $v || 1 );
  14.         if ($v2) {
  15.             my $V2 = $V1 + $v2 - $v;
  16.             push @exists, map { $V1 + $_ } 0 .. $v2 - $v;
  17.             push @{ $data[0] }, "${K}[$V1,$V2]";
  18.             $V1 = $V2 + 1;
  19.         }
  20.         else {
  21.             push @{ $data[0] }, "${K}[$V1]";
  22.             push @exists, $V1++;
  23.         }

  24.     }

  25.     @elem = split /;/, $col4;
  26.     for my $i ( 0 .. $#exists ) {
  27.         next unless $exists[$i];
  28.         my ($k) = $elem[$i] =~ /(\w+)$/;
  29.         push @{ $data[1] }, "[$exists[$i]]$k";
  30.     }

  31. }

  32. print "@$_\n" for @data;

  33. __DATA__
  34. a       b        s[1];p[2]        [1]d;[2]t
  35. b       c        s[1];q[2];       [1]d;[2]y;
  36. a       d        c[1,3];          [1]e;[2]t;[3]b;
  37. b       d        p[1];y[2]        [1]d;[2]y2;
  38. e       f        abb              hhh
  39. g       n        .                1
  40. f       n        6[1-4]           [1]e;[2]t;[3]b2;[4]h;
  41. a       d        c[1,3];A[4];     [1]e;[2]t;[3]b;[4]d;   # ADD
复制代码
回复 1# huang6894


   

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
发表于 2014-11-10 13:08 |显示全部楼层
本帖最后由 ly5066113 于 2014-11-10 13:09 编辑

回复 1# huang6894


数组1:
  1. awk '$3=="."||$4=="."{next}{for(i=1;i<=split($3,a,/[][;]+/);i+=2){if(a[i]&&!b[a[i]]++){if(split(a[i+1],c,/[-,]/)>1){printf "%s[%d,%d]\n",a[i],++n,n+c[2]-c[1];n+=c[2]-c[1]}else printf "%s[%d]\n",a[i],++n}}}' file
复制代码
2的自己改改吧。

论坛徽章:
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
发表于 2014-11-10 13:56 |显示全部楼层
回复 2# ly5066113


    谢谢。。受益匪浅~

论坛徽章:
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
发表于 2014-11-10 13:58 |显示全部楼层
回复 2# pitonas


    我大概能理解大神的意思。。。有一个问题是:假如数据是
  1. a       d        c[1,3];aaaa          [1]e;[2]t;[3]b;
复制代码
这样的时候,拆分为c[1](对应[1]e);c[2](对应[2]t);c[3](对应[3]b);aaaa是额外的不需要添加相关数字

论坛徽章:
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
发表于 2014-11-10 14:02 |显示全部楼层
回复 2# pitonas


    实在对不起。。其实我是想得到:s[1];p[2];q[3];c[4,6];aaaa"楼主注:这是额外的";y[8];abb[9];6[10,13];A[14];和一个数组“[1]d [2]t [3]y [4]e [5]t [6]b [7] [8]y2 [9]hhh [10]e [11]t [12]b2 [13]h [14]d”
walklan 该用户已被删除
发表于 2014-11-10 14:02 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
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
发表于 2014-11-10 14:03 |显示全部楼层
回复 7# walklan


    各位大神好厉害

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
发表于 2014-11-10 15:48 |显示全部楼层
从这个角度上来说: 我还是持观望态度 ~ {:2_168:}

这?
  1.     my $elem4 = ( $col4 =~ tr/;// ) + ( $col4 !~ /;$/ );
  2.     for my $e (@elem) {
  3.         last if @exists >= $elem4;
复制代码
回复 5# huang6894


   

论坛徽章:
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
发表于 2014-11-10 15:50 |显示全部楼层
回复 9# pitonas


    {:2_180:} {:2_180:} O(∩_∩)O好的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP