#nop vim: set filetype=tt:; /* 本文件属于 PaoTin++ 的一部分。 PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp ) 享有并保留一切法律权利 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。 */ #nop 本文件是 xtintin 的一部分,实现了一些常用算法; ///=== { // #@ algo.Diff <字符串1> <字符串2> // 如果两个字符串参数中,其中一个是另一个插入了一个子串的结果,则本函数可计算并返回该子串。 // // EXAMPLE: @algo.Diff{一二三四五六七八;一二三四PaoTin++五六七八} // RESULT: PaoTin++ // }; #func {algo.Diff} { #local str1 {%1}; #local str2 {%2}; #list str1 {tokenize} {$str1}; #list str2 {tokenize} {$str2}; #local size1 {&str1[]}; #local size2 {&str2[]}; #if { $size1 < $size2 } { #local tmp {$str1}; #local str1 {$str2}; #local str2 {$tmp}; #local tmp {$size1}; #local size1 {$size2}; #local size2 {$tmp}; }; #local idx {}; #loop {1} {$size2} {idx} { #local ch1 {$str1[$idx]}; #local ch2 {$str2[$idx]}; #if { "$ch1" != "$ch2" } { #break; }; }; #local begin {$idx}; #local end {}; #math end {$size1 - $size2 + $begin - 1}; #local diff {}; #loop {$begin} {$end} {idx} { #local ch {$str1[$idx]}; #cat diff {$ch}; }; #return {$diff}; }; ///=== { // #@ algo.ParseVertLayout <竖排文字串> // 将竖排文字重新排版成横排,方便做匹配。 // 结果是一个列表,其中的每个元素代表一行转换后的文本。 // 为方便计算对齐,其中竖排文字串要求用竖线定出每行的左右边界,且一个汉字必须对应两个空格。 // // EXAMPLE: // #nop 需要将每一行竖排文字都拼接到一起,左右两边用竖线定界(重要); // #local vert {|谁 纵 千 救 眼 三 将 闲 事 十 银 赵 侠| // |能 死 秋 赵 花 杯 炙 过 了 步 鞍 客 | // |书 侠 二 挥 耳 吐 啖 信 拂 杀 照 缦 客| // |阁 骨 壮 金 热 然 朱 陵 衣 一 白 胡 | // |下 香 士 槌 后 诺 亥 饮 去 人 马 缨 行| // |, , , , , , , , , , , , | // |白 不 洹 邯 意 五 持 脱 深 千 飒 吴 | // |首 惭 赫 郸 气 岳 觞 剑 藏 里 沓 钩 | // |太 世 大 先 素 倒 劝 膝 身 不 如 霜 | // |玄 上 梁 震 霓 为 侯 前 与 留 流 雪 | // |经 英 城 惊 生 轻 嬴 横 名 行 星 明 | // |。 。 。 。 。 。 。 。 。 。 。 。 |}; // // #local lines {\@algo.ParseVertLayout{\$vert}}; // #local lineNo {}; // #foreach {*lines[]} {lineNo} { // #echo {%s} {\$lines[\$lineNo]}; // }; // // OUTPUT: // 侠 客 行 // 赵客缦胡缨,吴钩霜雪明。 // 银鞍照白马,飒沓如流星。 // 十步杀一人,千里不留行。 // 事了拂衣去,深藏身与名。 // 闲过信陵饮,脱剑膝前横。 // 将炙啖朱亥,持觞劝侯嬴。 // 三杯吐然诺,五岳倒为轻。 // 眼花耳热后,意气素霓生。 // 救赵挥金槌,邯郸先震惊。 // 千秋二壮士,洹赫大梁城。 // 纵死侠骨香,不惭世上英。 // 谁能书阁下,白首太玄经。 // }; #func {algo.ParseVertLayout} { #local text {%0}; #replace text {| |} {|}; #replace text {^|} {}; #replace text {|$} {}; #local ch {}; #local lines {}; #local state {left}; #local colNo {1}; #local newline {|}; #parse {$text} {ch} { #switch {"$state/$ch"} { #case {"left/ "} { #local state {right}; }; #case {"right/ "} { #local state {left}; #local lines[$colNo] {$lines[$colNo] }; #math colNo {$colNo + 1}; }; #case {"%*/$newline"} { #math colNo {1}; #local state {left}; }; #case {"left/%*"} { #local lines[$colNo] {$lines[$colNo]$ch}; #math colNo {$colNo + 1}; }; #default { errLog find BUG; #return {}; }; }; }; #local output {}; #loop {&lines[]} {1} {colNo} { #replace {lines[$colNo]} {%+1..s$} {}; #if { {$lines[$colNo]} == {%*%+1..S%*} } { #list output add {{$lines[$colNo]}}; }; }; #return {$output}; };