亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2592 | 回復(fù): 9
打印 上一主題 下一主題

[探討]字符串匹配算法擴(kuò)展算法 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2013-04-27 13:51 |只看該作者 |倒序?yàn)g覽
my $str = 'if a then b do f end end'

=>
{
   0 => 'if a then b do f end end',
   1 => 'do f end',
}

注意這里面不只是只有 if ... end 的結(jié)構(gòu),還有 do .. end 的結(jié)構(gòu),這些結(jié)構(gòu)都是可嵌套的。

如果你的算法是優(yōu)秀的,那么試試能不能擴(kuò)展一下,可以計(jì)算多種結(jié)構(gòu)的嵌套。

我發(fā)布的算法,已經(jīng)有解決方案了,只是想把這些有用的算法需求,分享給大家,娛樂一下:

前面發(fā)布的一個(gè)算法需求很簡單,但得到的代碼已經(jīng)非常復(fù)雜了。實(shí)際的需求更加復(fù)雜。

一個(gè)最簡單的語言中,可嵌套的結(jié)構(gòu)除了循環(huán),判斷語句,還有數(shù)據(jù)結(jié)構(gòu),函數(shù)定義。這些結(jié)構(gòu)要是一起來的話,您的算法要怎么擴(kuò)展呢?

也許我的算法讓大家很受打擊,但真實(shí)的需求就是這樣的。

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2013-05-02 23:36 |只看該作者
本帖最后由 Perlvim 于 2013-05-03 18:26 編輯

String::NestMatch 模塊的 nest_match 方法可以處理:

它接受一個(gè)首尾字符串散列作為參數(shù),不但可以處理單字符為標(biāo)志的結(jié)構(gòu),也能處理多字符為標(biāo)志的結(jié)構(gòu),能夠處理任意深度。使用了最基本的字符串替換算法,可以在 sed, awk, Lua, 等算法簡單的語言中實(shí)現(xiàn)。

測(cè)試代碼:
  1. #!perl

  2. use 5.014;
  3. use YAML qw(Dump);
  4. use String::NestMatch qw(nest_match);

  5. my $str = 'if a then if b then if c then d end end end if f then g end';
  6. say(Dump(nest_match($str, { if => 'end'})));
  7. my $text = "<table><tr><td>aaa</td></tr></table>";
  8. say(Dump(nest_match($text, { '<tr>' => '</tr>', '<td>' => '</td>' })));
  9. my $str1 = 'if a then for b in c end end';
  10. say(Dump(nest_match($str1, { 'if' => 'end', 'for' => 'end' })));
復(fù)制代碼
輸出:
  1. >perl -w test_nest_match.pl
  2. ---
  3. 1:
  4.   - if a then if b then if c then d end end end
  5.   - if f then g end
  6. 2:
  7.   - if b then if c then d end end
  8. 3:
  9.   - if c then d end

  10. ---
  11. 1:
  12.   - '<tr><td>aaa</td></tr>'
  13. 2:
  14.   - '<td>aaa</td>'

  15. ---
  16. 1:
  17.   - if a then for b in c end end
  18. 2:
  19.   - for b in c end

  20. >Exit code: 0    Time: 0.549
復(fù)制代碼
模塊源代碼:
  1. package String::NestMatch;

  2. use Exporter;
  3. our @ISA = qw(Exporter);
  4. our @EXPORT_OK = qw(nest_match);

  5. use 5.010;
  6. use strict;
  7. use warnings;
  8. use YAML qw(Dump);

  9. my $count = 127;
  10. my $id_char = {};
  11. my $char_id = {};

  12. sub apply_id_char {
  13.   my $id = shift;
  14.   $count++;
  15.   my $char = chr($count);
  16.   $id_char->{$id} = $char;
  17.   $char_id->{$char} = $id;
  18.   return $char;
  19. }

  20. sub char_id_in_text {
  21.   my ($text, @id) = @_;
  22.   foreach my $id (@id) {
  23.     if (length($id) == 1) {
  24.       $char_id->{$id} = $id;
  25.       $id_char->{$id} = $id;
  26.       next;
  27.     }
  28.     next if (exists $id_char->{$id});
  29.     my $char = apply_id_char($id);
  30.     if ($id =~ /^\w+$/) {
  31.       $text =~ s/\b$id\b/$char/g;
  32.     }
  33.     elsif ($id =~ /\w$/) {
  34.       $text =~ s/\Q$id\E\b/$char/g;
  35.     }
  36.     elsif ($id =~ /^\w/) {
  37.       $text =~ s/\b\Q$id\E/$char/g;
  38.     }
  39.     else {
  40.       $text =~ s/\Q$id\E/$char/g;
  41.     }
  42.   }
  43.   return $text;
  44. }

  45. sub nest_match {
  46.   my ($str, $rule) = @_;
  47.   my $match_start = {};
  48.   my $start_end_id = {};
  49.   while (my ($start_str, $end_str) = each %$rule) {
  50.     $str = char_id_in_text($str, $start_str, $end_str);
  51.     # say $str;
  52.     my $start_char = $id_char->{$start_str};
  53.     my $end_char   = $id_char->{$end_str};
  54.     if (exists $match_start->{$start_char}) {
  55.       $match_start->{$start_char}{$end_char} = 1;
  56.     }
  57.     else {
  58.       $match_start->{$start_char} = { $end_char => 1 };
  59.     }
  60.   }
  61.   # default depth
  62.   my $depth = 0;
  63.   my $depth_chars = { 0 => [] };
  64.   # according depth to save matched string
  65.   my $depth_match_str = { };
  66.   my $depth_start_char = { 0 => '' };
  67.   my $expect_end_chars = {};

  68.   my @text_chars = split //, $str;
  69.   foreach my $char (@text_chars) {
  70.     if (exists $expect_end_chars->{$char}) {
  71.       push @{$depth_chars->{$depth}}, $char_id->{$char};
  72.       my $depth_str = join '', @{ $depth_chars->{$depth} };
  73.       if (exists $depth_match_str->{$depth}) {
  74.         push @{$depth_match_str->{$depth}}, $depth_str;
  75.       }
  76.       else {
  77.         $depth_match_str->{$depth} = [ $depth_str ];
  78.       }
  79.       $depth = $depth - 1;
  80.       push @{ $depth_chars->{$depth} }, $depth_str;
  81.       my $current_start_char = $depth_start_char->{$depth};
  82.       if ($depth == 0) {
  83.         $expect_end_chars = {};
  84.       } else {
  85.         $expect_end_chars = $match_start->{$current_start_char};
  86.       }
  87.       if (exists $match_start->{$char}) {
  88.         $depth = $depth + 1;
  89.         $depth_chars->{$depth} = [ $char_id->{$char} ];
  90.         $expect_end_chars = $match_start->{$char};
  91.         $depth_start_char->{$depth} = $char;
  92.       }
  93.     }
  94.     else {
  95.       if (exists $match_start->{$char}) {
  96.         $depth = $depth + 1;
  97.         $depth_chars->{$depth} = [ $char_id->{$char} ];
  98.         $expect_end_chars = $match_start->{$char};
  99.         $depth_start_char->{$depth} = $char;
  100.       }
  101.       else {
  102.         push @{ $depth_chars->{$depth} }, $char;
  103.       }
  104.     }
  105.   }
  106.   $count = 127; $id_char = {}; $char_id = {};
  107.   return $depth_match_str;
  108. }

  109. 1;
復(fù)制代碼

論壇徽章:
7
戌狗
日期:2013-12-15 20:43:38技術(shù)圖書徽章
日期:2014-03-05 01:33:12技術(shù)圖書徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16賽季CBA聯(lián)賽之青島
日期:2016-03-17 20:36:13
3 [報(bào)告]
發(fā)表于 2013-05-03 08:46 |只看該作者
3Q~這種算法很好

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2013-05-03 10:40 |只看該作者
回復(fù) 2# Perlvim


這是哪里的module,CPAN上沒查到,perlvim自己寫的?

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2013-05-03 14:52 |只看該作者
回復(fù) 4# routesf


    我試了一下,括號(hào)似乎處理不了,類似這樣的
my $str3 = q(
interfaces {
    fxp0 {  
    unit 0 {
        family inet {
        address 192.168.83.16/24;
        }      
    }      
    }      
}      
);
say(Dump(nest_match($str3, { '{' => '}' })));

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2013-05-03 18:13 |只看該作者
是的,代碼算法有問題,已經(jīng)更正。在第29行到30行之間增加一行:
$id_char->{$id} = $id;

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2013-05-06 11:46 |只看該作者
用調(diào)試的方式,好好學(xué)習(xí)了一下。
一個(gè)字符,一個(gè)字符的處理,這樣效率是否有問題?在兩個(gè)關(guān)鍵字之間的字符串能否一起處理呢。

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2013-05-06 12:55 |只看該作者
回復(fù) 7# followcn
所有字符串的算法,其實(shí)都是一個(gè)一個(gè)的處理。否則怎么知道到達(dá)了邊界?正則表達(dá)式看似很快,也是一個(gè)一個(gè)字符的處理。如果有分支和分組的話,一個(gè)字符要處理好幾次。所以分支的處理,分開后反而效率更高:

/branch1/ && /branch2/  => /branch1|branch2/


   

論壇徽章:
0
9 [報(bào)告]
發(fā)表于 2013-05-07 15:32 |只看該作者
本帖最后由 followcn 于 2013-05-07 15:34 編輯

可能是我的意思表達(dá)的不清楚,例如對(duì)下例中someting的處理
模塊中對(duì)something這樣的詞要循環(huán)9次,進(jìn)行判斷。
if somethting end

論壇徽章:
0
10 [報(bào)告]
發(fā)表于 2013-05-07 18:37 |只看該作者
如果想把類似的單詞先替換成一個(gè)字節(jié)的字符,讓掃描的時(shí)候,只掃描一次,這個(gè)算法就快多了。
你提醒了我,可以在將關(guān)鍵字替換成單字節(jié)字符的同時(shí),將其他的單詞一起替換成單字節(jié)字符。

這樣,就快多了
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP