algo.tin 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #nop vim: set filetype=tt:;
  2. /*
  3. 本文件属于 PaoTin++ 的一部分。
  4. PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
  5. 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
  6. */
  7. #nop 本文件是 xtintin 的一部分,实现了一些常用算法;
  8. ///=== {
  9. // #@ algo.Diff <字符串1> <字符串2>
  10. // 如果两个字符串参数中,其中一个是另一个插入了一个子串的结果,则本函数可计算并返回该子串。
  11. //
  12. // EXAMPLE: @algo.Diff{一二三四五六七八;一二三四PaoTin++五六七八}
  13. // RESULT: PaoTin++
  14. // };
  15. #func {algo.Diff} {
  16. #local str1 {%1};
  17. #local str2 {%2};
  18. #list str1 {tokenize} {$str1};
  19. #list str2 {tokenize} {$str2};
  20. #local size1 {&str1[]};
  21. #local size2 {&str2[]};
  22. #if { $size1 < $size2 } {
  23. #local tmp {$str1};
  24. #local str1 {$str2};
  25. #local str2 {$tmp};
  26. #local tmp {$size1};
  27. #local size1 {$size2};
  28. #local size2 {$tmp};
  29. };
  30. #local idx {};
  31. #loop {1} {$size2} {idx} {
  32. #local ch1 {$str1[$idx]};
  33. #local ch2 {$str2[$idx]};
  34. #if { "$ch1" != "$ch2" } {
  35. #break;
  36. };
  37. };
  38. #local begin {$idx};
  39. #local end {};
  40. #math end {$size1 - $size2 + $begin - 1};
  41. #local diff {};
  42. #loop {$begin} {$end} {idx} {
  43. #local ch {$str1[$idx]};
  44. #cat diff {$ch};
  45. };
  46. #return {$diff};
  47. };
  48. ///=== {
  49. // #@ algo.ParseVertLayout <竖排文字串>
  50. // 将竖排文字重新排版成横排,方便做匹配。
  51. // 结果是一个列表,其中的每个元素代表一行转换后的文本。
  52. // 为方便计算对齐,其中竖排文字串要求用竖线定出每行的左右边界,且一个汉字必须对应两个空格。
  53. //
  54. // EXAMPLE:
  55. // #nop 需要将每一行竖排文字都拼接到一起,左右两边用竖线定界(重要);
  56. // #local vert {|谁 纵 千 救 眼 三 将 闲 事 十 银 赵 侠|
  57. // |能 死 秋 赵 花 杯 炙 过 了 步 鞍 客 |
  58. // |书 侠 二 挥 耳 吐 啖 信 拂 杀 照 缦 客|
  59. // |阁 骨 壮 金 热 然 朱 陵 衣 一 白 胡 |
  60. // |下 香 士 槌 后 诺 亥 饮 去 人 马 缨 行|
  61. // |, , , , , , , , , , , , |
  62. // |白 不 洹 邯 意 五 持 脱 深 千 飒 吴 |
  63. // |首 惭 赫 郸 气 岳 觞 剑 藏 里 沓 钩 |
  64. // |太 世 大 先 素 倒 劝 膝 身 不 如 霜 |
  65. // |玄 上 梁 震 霓 为 侯 前 与 留 流 雪 |
  66. // |经 英 城 惊 生 轻 嬴 横 名 行 星 明 |
  67. // |。 。 。 。 。 。 。 。 。 。 。 。 |};
  68. //
  69. // #local lines {\@algo.ParseVertLayout{\$vert}};
  70. // #local lineNo {};
  71. // #foreach {*lines[]} {lineNo} {
  72. // #echo {%s} {\$lines[\$lineNo]};
  73. // };
  74. //
  75. // OUTPUT:
  76. // 侠 客 行
  77. // 赵客缦胡缨,吴钩霜雪明。
  78. // 银鞍照白马,飒沓如流星。
  79. // 十步杀一人,千里不留行。
  80. // 事了拂衣去,深藏身与名。
  81. // 闲过信陵饮,脱剑膝前横。
  82. // 将炙啖朱亥,持觞劝侯嬴。
  83. // 三杯吐然诺,五岳倒为轻。
  84. // 眼花耳热后,意气素霓生。
  85. // 救赵挥金槌,邯郸先震惊。
  86. // 千秋二壮士,洹赫大梁城。
  87. // 纵死侠骨香,不惭世上英。
  88. // 谁能书阁下,白首太玄经。
  89. // };
  90. #func {algo.ParseVertLayout} {
  91. #local text {%0};
  92. #replace text {| |} {|};
  93. #replace text {^|} {};
  94. #replace text {|$} {};
  95. #local ch {};
  96. #local lines {};
  97. #local state {left};
  98. #local colNo {1};
  99. #local newline {|};
  100. #parse {$text} {ch} {
  101. #switch {"$state/$ch"} {
  102. #case {"left/ "} {
  103. #local state {right};
  104. };
  105. #case {"right/ "} {
  106. #local state {left};
  107. #local lines[$colNo] {$lines[$colNo] };
  108. #math colNo {$colNo + 1};
  109. };
  110. #case {"%*/$newline"} {
  111. #math colNo {1};
  112. #local state {left};
  113. };
  114. #case {"left/%*"} {
  115. #local lines[$colNo] {$lines[$colNo]$ch};
  116. #math colNo {$colNo + 1};
  117. };
  118. #default {
  119. errLog find BUG;
  120. #return {};
  121. };
  122. };
  123. };
  124. #local output {};
  125. #loop {&lines[]} {1} {colNo} {
  126. #replace {lines[$colNo]} {%+1..s$} {};
  127. #if { {$lines[$colNo]} == {%*%+1..S%*} } {
  128. #list output add {{$lines[$colNo]}};
  129. };
  130. };
  131. #return {$output};
  132. };