免费注册 查看新帖 |

Chinaunix

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

请教 如何最快的将数组中符合条件的元素全部重新赋值? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-17 14:22 |只看该作者 |倒序浏览
比如一个数组很大,含上百万个元素,现在想将其中值等于5的元素全部重新赋值为6,而且这个操作要重复多次,应该如何操作才最省资源?

论坛徽章:
0
2 [报告]
发表于 2006-07-17 14:59 |只看该作者
没试过 不知道怎么才能快 等待高手回复...

为什么那么大要存在数组里面
或者可以想到其他方式 比如存在文件里面然后利用模式匹配



  1. 29.2.93. map

  2. map BLOCK LIST
  3. map EXPR, LIST
  4. 这个函数为 LIST 里的每一个元素计算 BLOCK 或者 EXPR(在本地把 $_ 设置为每个元素)并且返回由每次计算的结果组成的列表。它在列表环境里计算 BLOCK 或者 EXPR,因此 LIST 里的每个元素都可以映射成零个,一个,或者更多个返回值里的元素。这些东西都填充到一个列表中去了。比如:


  5.    @words = map { split ' ' } @lines;

  6. 把一个行组成的列表分裂成一个单词列表。但是通常在输入值和输出值之间是一一映射的:


  7.    @chars = map chr, @nums;
  8. 把一个数字列表转换成对应的字符。而下面是一个一对二映射的例子:


  9.    %hash = map { genkey($_) => $_ } @array;

  10. 它只是下面程序的一种有趣的写法:



  11.    %hash = ();
  12.    foreach $_ (@array) {
  13.       $hash{genkey($_) } = $_;
  14.    }

  15. 因为 $_ 是一个到该列表数值的别名(隐含引用),所以这个变量可以用于修改数组的元素。这样做是允许并且是有用的,不过,如果 LIST 不是一个命名数组,那么它可能导致非常奇怪的后果。这种情况下使用一个普通的 foreach 循环可能更清晰一些。又见 grep;map 和 grep 的不同在于:map 返回一个由所有成功计算 EXPR 后得到的结果组成的列表,而 grep 返回一个由所有对 EXPR 计算为真的 LIST 的值组成的列表。

复制代码

论坛徽章:
0
3 [报告]
发表于 2006-07-17 15:11 |只看该作者
[quote]原帖由 aaronvox 于 2006-7-17 14:59 发表
没试过 不知道怎么才能快 等待高手回复...

为什么那么大要存在数组里面
或者可以想到其他方式 比如存在文件里面然后利用模式匹配


用模式匹配不是更慢?现在是由足够的内存,但是因为需要操作的数据太多了,导致效率很低。
我试过用最笨的办法,就是套两层循环来做
结果慢得无法忍受

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2006-07-17 15:25 |只看该作者
这样就可以了:
  1. map { $_ = 5 if $_ == 6 } @array;
复制代码

如果需要重复操作的话,
  1. @indexes = grep { $array[$_] == 6 } 0..$#array;
  2. # 然后每次都这么来一下:
  3. map { $array[$_] = 5 } @indexes;
复制代码

这应该是 Perl 里面最快的方法了。
如果你还觉得不够快,请尝试着:
1,改变思路;
2,将需要提高速度的部分用 C 来写。

论坛徽章:
0
5 [报告]
发表于 2006-07-17 15:35 |只看该作者
原帖由 flw 于 2006-7-17 15:25 发表
这样就可以了:
  1. map { $_ = 5 if $_ == 6 } @array;
复制代码

如果需要重复操作的话,
[code]@indexes = grep { $array[$_] == 6 } 0..$#array;
# 然后每次都这么来一下:
map { $array[$_] = 5 } @indexe ...


多谢,我来试试

不过不太乐观,数据是在太大了
看来要准备用C重写了

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2006-07-17 15:44 |只看该作者
是否想过改变一下思路?

论坛徽章:
0
7 [报告]
发表于 2006-07-17 15:49 |只看该作者
原帖由 flw 于 2006-7-17 15:44 发表
是否想过改变一下思路?


琢磨一天了。似乎没想到更好的解决办法

关键是这个操作太简单了,想不出能对它作什么变化

论坛徽章:
0
8 [报告]
发表于 2006-07-17 15:52 |只看该作者
原帖由 flw 于 2006-7-17 15:25 发表
这样就可以了:
  1. map { $_ = 5 if $_ == 6 } @array;
复制代码



这个操作比
foreach $_  (@array) {
             $_ = 5 if $_ == 6
         }

能快多少呢?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2006-07-17 16:02 |只看该作者
原帖由 geshutian 于 2006-7-17 15:52 发表


这个操作比
foreach $_  (@array) {
             $_ = 5 if $_ == 6
         }

能快多少呢?

map 应该比 foreach 要快一些。
我猜测 map 是一个操作符,而 foreach 则是流程控制。

PS:操作简单固然是不好化简,可是程序的整体结构未必就不能化简。
如果你什么都不说,那我只能祝福你了。呵呵!Good luck!

论坛徽章:
0
10 [报告]
发表于 2006-07-17 16:14 |只看该作者
原帖由 flw 于 2006-7-17 16:02 发表

map 应该比 foreach 要快一些。
我猜测 map 是一个操作符,而 foreach 则是流程控制。

PS:操作简单固然是不好化简,可是程序的整体结构未必就不能化简。
如果你什么都不说,那我只能祝福你了。呵呵!Good ...



呵呵,是不知道怎么才能说清楚,修改整体结构的话牵扯的东西太多,不是我能控制的了。而且时间上来不及了。
多谢了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP