免费注册 查看新帖 |

Chinaunix

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

请教文本处理:123与321合并为123 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2005-05-16 11:36 |只看该作者

请教文本处理:123与321合并为123

怒剑,有两个问题,
1、首先文本不是按循序单调递增排列
@tmp=("$a$c$b","$b$a$c","$b$c$a","$c$b$a","$c$a$b"; 这个是你对文本内容的推测,况且如果元素组成各异的情况下是6种情况(C3)
2、 print sort($a,$b,$c),",$hash{$key}\n"; 不明白什么用意?为什么要sort?如果元素里面103是最小值,sort得到什么?

论坛徽章:
0
32 [报告]
发表于 2005-05-16 11:56 |只看该作者

请教文本处理:123与321合并为123

照这个程序输出的文本写罢

#!/usr/bin/perl
($count=shift) || ($count=1);
my $number=0;
while($number < $count) {
   print sprintf("%03d\n",int(rand($count)+1));
   $number++;
}
exit 0;

论坛徽章:
0
33 [报告]
发表于 2005-05-16 12:43 |只看该作者

请教文本处理:123与321合并为123

1、103不是最小值啊,最小值是013,我产生的文本是最多可能情况,应该是0-9三位数的全排列,至于你用随机数产生也是一样的,程序都可以执行的
我只是在输出时排序,而不是排序好以后计算,跟你方法不一样,
2、至于你说的6种情况,也不是一定的,比如555就只有一种情况,558就只有三种情况,这一点要注意的。我的程序中我之所以列举了5种,那是因为"$a$b$c"这一种情况已经出现在$key中了,我把它省略了。
3、我的程序可以适应随机情况的,我只是用一种特例来测试的。

论坛徽章:
0
34 [报告]
发表于 2005-05-16 13:56 |只看该作者

请教文本处理:123与321合并为123

($a,$b,$c)=split(//,$key);
       @tmp=("$a$c$b","$b$a$c","$b$c$a","$c$b$a","$c$a$b";
       foreach (@tmp) {
               $keys{$_}++ if (exists$hash{$_}) ;


你这段代码得到的结果是错误的,因为你假设了三个组成元素是不相同的(即使不相同也应该是6而不是5),所以结果出入会非常大

论坛徽章:
0
35 [报告]
发表于 2005-05-16 14:06 |只看该作者

请教文本处理:123与321合并为123

superdoctor,你搞错了,你可以执行一下试试,看看结果对不对!我没有假设$a,$b,$c是不相同的哦!我后面的循环就是来测试到底有几个存在的,因为我省略了一个"$a$b$c",而这个就是"$key",所以我不需要列举出来
,你仔细看看

论坛徽章:
0
36 [报告]
发表于 2005-05-16 17:16 |只看该作者

请教文本处理:123与321合并为123

怒剑,如果取得的一个值是111的话,根据你
($a,$b,$c)=split(//,$key);
      @tmp=("$a$c$b","$b$a$c","$b$c$a","$c$b$a","$c$a$b";
可得
      @tmp=("111",''111","111","111","111";

       foreach (@tmp) {
              $keys{$_}++ if (exists$hash{$_}) ;
时,由于@tmp各元素相等,可证明if (exists$hash{$_}) 全部为真,因此
  $keys{$_}++
所以结果是不可靠的

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
37 [报告]
发表于 2005-05-16 18:52 |只看该作者

请教文本处理:123与321合并为123


  1. #!/usr/bin/perl
  2. open(FF,"in.txt");
  3. while(<FF>;){
  4. chomp;
  5. #--將string 中每個element排序
  6. my $ary = join "", sort {$a <=>;$b } split(//);
  7. #--對排序後的string 加1..
  8. $count{$ary}->;[0]++;
  9. #--記得目前在處理那個string
  10. $rem{$_}++;
  11. #--如果放置相同element的array已經有數據
  12. if(@{$count{$ary}->;[1]}>;0){
  13.    push(@{$count{$ary}->;[1]},$_) if $rem{$_}==1;
  14. }else{
  15.    push(@{$count{$ary}->;[1]},$_) ;
  16. }
  17. }
  18. close(FF);
  19. #--找出每個component中最小的..並將其數據打印出來...
  20. for my $key (keys %count){
  21.    ($min) = sort {$a <=>; $b} @{$count{$key}->;[1]};

  22.    print "$min =>; $count{$key}->;[0] \n";
  23. }

复制代码

好複雜的討論..要是碰到3個以上element可就辛苦了..
上面這個是另一種想法...可能更複雜...不過大家可以參考參考..
也許可以更簡化...但是不管幾個element都一樣...
因為sort完後的string可能不出現..所以才要寫得這麼複雜...

论坛徽章:
0
38 [报告]
发表于 2005-05-17 08:20 |只看该作者

请教文本处理:123与321合并为123

superdoctor你还是没能看懂我的程序啊,我只是用一个临时散列测试存在性,然后下面的一个循环才是真正的计数啊。
apile老大写的程序可以适应多位数,很通用,但是效率方面不太高啊,我读取一个10000行的文本,过很长时间就提示一个“已杀死”的信息,不知是什么原因?不过1000行的数据可以执行,执行时间为0.02s~0.03s之间,我的程序在0.01s~0.02s之间!我个人觉得将分割存储的过程放到读取文件的大循环之外运行效率要高一些,不知apile兄怎么看?我也再来想想怎么写!
另外提醒一下apile兄,一开始已经对关键字排序了,最后的排序就不必要了,只要用一次!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
39 [报告]
发表于 2005-05-17 08:37 |只看该作者

请教文本处理:123与321合并为123

怒劍兄:
最後那個sort是因為前面sort的結果..未必會出現在array中...所以才要
再去找一次最小的..只是確定..其實可以在前面再加個判斷..
可以讓這兒的sort減少到最少...
例如:
數據中可能只有 130 310...sort完後會變成013..但是因為013不存在於array中..所以實際輸出應該是130才對....
另外我早上有改了一下代碼..

  1. open(FF,">;in.txt");
  2. for($i=0;$i<100001;$i++){

  3.   print FF sprintf("%04s",int(rand(10000)))."\n";
  4. }
  5. close(FF);
复制代码

用上面這個代碼產生數據..執行時間....

錯了..應該是2.47秒才對..:)

我的OS是RHEL 3 update 4...P4 1.4GHz CPU...

论坛徽章:
0
40 [报告]
发表于 2005-05-17 09:13 |只看该作者

请教文本处理:123与321合并为123

apile兄,不知你有没有试试1000000的代码?我测试了一下,我的程序执行时间是1.30s,你的程序要用13.92s,当行数继续增多的时候,这个时间差距将拉的更大,因为你每读取一行就要进行分割,排序,压栈,判断等操作,这样文件很大时,消耗的CPU处理能力是很大的,有没有兴趣修改一下程序将这些操作放到后期执行,这样能大大提高效率,我现在还没想到针对可变位数的提高效能的好办法?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP