【问题标题】:Generate every possible spacing within a specified string?在指定的字符串中生成每个可能的间距?
【发布时间】:2019-03-10 15:06:34
【问题描述】:

我有去掉空格的摩尔斯电码字符串,长度相等。

比如说一个是..--.---..

我想在不同的行上生成所有可能的解决方案。

. . - - . - - - . ... - - .- --. ...- -.- - -. .

有什么好的、有效的方法来做到这一点?我对这种事情感到很糟糕,我被难住了。

【问题讨论】:

  • Bash 几乎可以肯定是错误的工具。如果字符串在文件中,则使用例如置换它awk 应该不难;但是,如果您对从哪里开始没有任何偏好,那么像 Python 这样的现代脚本语言可能是更好的选择。
  • 有关 Stack Overflow 的问题预计会显示出某种努力 - 如果不是您自己的代码尝试,那么至少您搜索的内容、发现的内容以及应用这些搜索结果时遇到了什么麻烦解决您的问题。
  • 我曾经在采访中问过这个问题。如果这是一个关于“我怎样才能找到这个字符串可以代表的所有可能的英语单词?”的 XY 问题,我会建议从英语词典中倒退。这样就不会是O(2^n)

标签: python bash loops math awk


【解决方案1】:

这是 awk 中的一个。当我看到这个问题并决定尝试一些东西时,我只是在玩 awk 二进制转换。它从 i=0 运行到 2(length(morse)-1)-1,将 i转为二进制并将所有 1 替换为空格,将 0 替换为空值,例如:

morse=-.-
length(morse)=3 -> 2^(3-1)-1=3
runs 0..3
0==00 -> -0.0- -> -.-
1==01 -> -0.1- -> -. -
2==10 -> -1.0- -> - .-
3==11 -> -1.1- -> - . -

脚本:

$ echo -..- |
  awk '
  function tobin(d,l) {
    r=""
    while(d) {
        r=d%2r
        d=int(d/2)
    }
    return sprintf("%0" l "d",r)
} 
{
    n=split($0,a,"")
    for(i=0;i<=2^(length-1)-1;i++) {
        split(tobin(i,length-1),b,"")
        for(j=1;j<=n;j++)
            printf "%s%s",a[j],(b[j]?" ":(j==n?ORS:""))
    }
}'

输出:

-..-
-.. -
-. .-
-. . -
- ..-
- .. -
- . .-
- . . -

【讨论】:

    【解决方案2】:

    如果您想在纯 bash 中执行此操作,可能会变得很棘手。这个想法是利用大括号扩展来处理所有可能性。

    $ a='..--'
    $ [[ $a =~ ${a//?/(.)} ]] && b=${BASH_REMATCH[*]:1} && eval printf "%s\\\n" ${b// /\{,\" \"\}})
    

    它是如何工作的?

    这个想法本质上是变换

    '..--'
    

    进入

    .{," "}.{," "}-{," "}-
    

    并让 bash 使用大括号展开来进行所有组合。

    1. [[ $a =~ ${a//?/(.)} ]] bash 测试将尝试匹配类似于(.)(.)(.)(.) 的正则表达式${a//?/(.)}。它将所有匹配项存储在变量BASH_REMATCH

    2. b=${BASH_REMATCH[*]:1} BASH_REMATCH 的索引为 0 的元素是匹配整个正则表达式的字符串部分。索引为nBASH_REMATCH 的元素是匹配第n 个带括号的子表达式的字符串部分。因此,我们只对除第一个部分之外的所有部分感兴趣:

      $ [[ $a =~ ${a//?/(.)} ]] && echo ${BASH_REMATCH[*]}
      ..-- . . - -
      $ [[ $a =~ ${a//?/(.)} ]] && echo ${BASH_REMATCH[*]:1}
      . . - -
      
    3. ${b// /\{,\" \"\}} 这会将所有空格替换为{," "}。这将允许我们使用大括号扩展,我们需要使用 eval 进行评估

      $ a='..--'
      $ [[ $a =~ ${a//?/(.)} ]]
      $ b=${BASH_REMATCH[*]:1}
      $ echo "${b// /\{,\" \"\}}"
      .\{," "\}.\{," "\}-\{," "\}-
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多