Ruby 字符串压缩,有木有更优雅方式?

administrator · 2013年06月09日 · 最后由 lostleaf 回复于 2013年06月17日 · 4527 次阅读

要求:

input will only contain the characters a-z

Example:

"aaabbac" -> "a3b2ac" "aaaaa" -> "a5" "" -> ""

我的方法是:

def zip_code(s)
  return "包含不合要求字符串" if s =~ /[^a-z]/
  ('a'..'z').each {|c| s.scan(/#{c}{2,}/).sort_by{|e| e.size}.reverse.each{|cha| s.gsub!(cha, "#{c}#{cha.size}") } }
  s
end

有点腻害……我写了一大堆分支和变量 不过你的这个方法的思路好像哪里不对 如果可以把字符串的不同字符取出来 代替 a...z 就好了

每次这样处理压缩文本字符,然后用的时候再解析出来,这种功能自己做有点吃力而且很难做好吧; 原始需求是什么

最最早文本存储为了压缩空间是自定义文件格式/存储格式,前多少是字符格式,中间几位是二进制,后面什么格式;然后数据定长变长的;这种 ruby 原生没这套东西。

另外我记得有直接处理 zip 文件的。

#2 楼 @as181920 没有原始需求,只是一道题目。

一个 hash 变量的 key 是字母,value 是出现次数

@see Enumerable#chunk

或者用带 block 的 gsub。用 /(.)\1+/ 去匹配

正则替换的解法:

"aaabbac".gsub(/(([a-z])\2*)/) {|s| $1.length > 1 ? $2 + $1.length.to_s : $2}

正则解法 3 ...

'aaabbac'.gsub /(?<=([a-z]))\1+/, &:size

#8 楼 @luikore cool, 但是数字少算了 1 个哦!

#10 楼 @qhwa 哦对...

'aaabbac'.gsub(/(?<=([a-z]))\1+/){|x| x.size + 1}

#11 (?<=exp) 猛然想到曾经用过 叫叫... 零宽断言? 这个概念字面让人很不懂 晦涩 #7 \1 \2 是什么意思 \1 匹配第一个 () 里面的内容 \2 匹配第二个 () 的内容么

#12 楼 @shooter 叫做 "往后看" (左边是后右边是前)

#11 楼 @luikore 我勒个去 这正则我看了半个小时

'a'..'z' , '1'..'9' , 35 个字符 35.to_s(2) => "100011" 6 位

8 位的数据用 6 位存放,可以再压缩 75%

11 楼 @luikore

对师父的正则进行改写. 不用断言, 似乎更清晰一些. $1 是第一个匹配, $& 是所有匹配.

'aaabbac'.gsub(/([a-z])(\1+)/) { $1+$&.size.to_s }

一部分灵感, 来自于当年 @hooopo 的经典回帖. http://ruby-china.org/topics/2504 五楼.

#13 楼 @luikore

叫做 "往后看" (左边是后右边是前)

师父的解释, 是基于: 默认正则的 back track 特性而言的吧? 和直觉上正好相反, 我编辑器针对这个设定了快捷键, 用的是: <, 有前的含义, 称作 前置断言 是不是更形象一些?

#16 楼 @zw963 如果你沿着字符串走路, 那 (?<=) 就是向后看啊...

如果用"往后看", "后"就是背后的后, 不是以后的后. (往左看可能好点, <= 左箭头已经很形象了...) 如果用"前置断言"这个词, "前"就是以前的前, 不是前面的前.

如果看英文 look backward / forward 就不会费解...


和回溯不是一回事, 基于 DFA 的正则表达式就不用回溯.

#17 楼 @luikore

我这个前是相对于被修饰的 (匹配的) 那个字符串而言的.

(?<=aaa) bbb, 这个 (?<=aaa) 是对 bbb 的前置断言. 我是这样理解的, 这里的 (?<=aaa) 是用来验证 bbb 前面 有什么东西, 所以自然而言联想出来这个叫法.

#17 楼 @luikore

才明白, 你讲的前, 是相对于这个来说的. 哈哈

刚发现, 楼主竟然是这么个用户名, 是不是不合适? 尤其对于用惯 Windows 的用户, 还以为是管理员.

@zw963 那我这个用户名呢? 哈哈

#21 楼 @root

...... 网站管理员一般不会用 root 的.

我想, 你一定是个马甲...

@zw963 我不是马甲,这个账号是个马甲...... 😄

我想起来一个动态规划算法,把压缩后的字符串再压缩。。。。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号