函数和分形 - 递归树 - Bash!逻辑问题

Posted

技术标签:

【中文标题】函数和分形 - 递归树 - Bash!逻辑问题【英文标题】:Functions and Fractals - Recursive Trees - Bash! Logic Issue 【发布时间】:2016-09-19 12:36:32 【问题描述】:

我正在尝试根据构建它的要求构建分形树。 出了点问题。请协助。我正在尝试根据请求的级别构建分形树。这里的水平被跳过。需要了解如何解决问题。

    #!/bin/bash
declare -A matrix
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        matrix[$i,$j]='_'
    done
done
function update_matrix 
p1=$1
p2=$(echo $2-1|bc)
p1=$(echo $p1-1|bc)
p3=$(echo 2^$p2|bc)
p4=$(echo 2*$p3|bc)
p5=$(echo $p3/2|bc)
p6=$3
for ((q1=$p3;q1<$p4;q1++)) do
        if [ "$(echo $q1-$p3|bc)" -lt "$p5" ]
            then
            q2=$(echo $p6-$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            q3=$(echo $p6+$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            matrix[$q1,$q2]=1
            matrix[$q1,$q3]=1
            #printf '%s' "$q1 $q2 -- $q1 $q3"
            #echo ""
            else
            matrix[$q1,$p6]=1
            #echo $q1 $p6
        fi
done

if [ $p1 -ge 1 ]
then
update_matrix $p1 $p2 $(echo $p6+$p5|bc)
update_matrix $p1 $p2 $(echo $p6-$p5|bc)
else
return
fi

read iteration
if [ $iteration -ge 1 ]
then
    update_matrix $iteration 6 32
fi
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        printf '%s' "$matrix[$i,$j]"
    done
    echo ""
done

输出是:

____________________________________________________________________________________________________
________________________________________________1_1_________________________________________________
_________________________________________________1__________________________________________________
_________________________________________________1___1______________________________________________
__________________________________________________1_1_______________________________________________
___________________________________________________1________________________________________________
___________________________________________________1________________________________________________
___________________________________________________1_______1________________________________________
____________________________________________________1_____1_________________________________________
_____________________________________________________1___1__________________________________________
______________________________________________________1_1___________________________________________
_______________________________________________________1____________________________________________
_______________________________________________________1____________________________________________
_______________________________________________________1____________________________________________
_______________________________________________________1____________________________________________
_______________________________________1_______________1____________________________________________
________________________________________1_____________1_____________________________________________
_________________________________________1___________1______________________________________________
__________________________________________1_________1_______________________________________________
___________________________________________1_______1________________________________________________
____________________________________________1_____1_________________________________________________
_____________________________________________1___1__________________________________________________
______________________________________________1_1___________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________1_______________________________1____________________________________________________
________________1_____________________________1_____________________________________________________
_________________1___________________________1______________________________________________________
__________________1_________________________1_______________________________________________________
___________________1_______________________1________________________________________________________
____________________1_____________________1_________________________________________________________
_____________________1___________________1__________________________________________________________
______________________1_________________1___________________________________________________________
_______________________1_______________1____________________________________________________________
________________________1_____________1_____________________________________________________________
_________________________1___________1______________________________________________________________
__________________________1_________1_______________________________________________________________
___________________________1_______1________________________________________________________________
____________________________1_____1_________________________________________________________________
_____________________________1___1__________________________________________________________________
______________________________1_1___________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________

需要了解为什么左节点创建右节点没有创建。

【问题讨论】:

【参考方案1】:

我缺少的是将变量声明为本地变量。由于哪些全局变量正在更新,因此我的程序无法正常运行。

我解决了这个问题并使用了局部变量,它就像一个魅力。

解决方案的代码是 它用于 Hackerrank 函数和分形 - 递归树 - Bash!程序。 我花了 3 小时才确定下来。终于解决了,真是令人耳目一新。

    #!/bin/bash
declare -A matrix
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        matrix[$i,$j]='_'
    done
done
i=0
declare -A arr
function update_matrix 
local p1 p2 p3 p4 p5 p6 q1 q2 q3 p11 p12 p13 p14 p15 p16
p1=$1
p2=$(echo $2-1|bc)
p1=$(echo $p1-1|bc)
p3=$(echo 2^$p2|bc)
p4=$(echo 2*$p3|bc)
p5=$(echo $p3/2|bc)
p6=$3
for ((q1=$p3;q1<$p4;q1++)) do
        if [ "$(echo $q1-$p3|bc)" -lt "$p5" ]
            then
            q2=$(echo 18+$p6-$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            q3=$(echo 18+$p6+$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            matrix[$q1,$q2]=1
            matrix[$q1,$q3]=1
            #printf '%s' "$q1 $q2 -- $q1 $q3"
            #echo ""
            else
            matrix[$q1,$(echo 18+$p6|bc)]=1
            #echo $q1 $p6
        fi
done

if [ $p1 -ge 1 ]
then
p11=$p1
p12=$p2
p13=$(echo $p6-$p5|bc)
p14=$(echo $p6+$p5|bc)
p15=$p1
p16=$p2

#echo $p11 $p12 $p6 $p5 $p13
update_matrix $p11 $p12 $p13
#echo $p15 $p16 $p6 $p5 $p14

update_matrix $p15 $p16 $p14
t=4
else
s=2
fi

read iteration
if [ $iteration -ge 1 ]
then
    #echo $iteration 6 32
    update_matrix $iteration 6 32
fi
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        printf '%s' "$matrix[$i,$j]"
    done
    echo ""
done

【讨论】:

【参考方案2】:

HackerRank 提出的问题要求您使代码递归。要递归,代码必须在某个时候调用自身。下面我创建了一个递归的 create_y 函数。此函数将不断调用自身,直到满足其停止条件。停止条件是检查迭代变量是否大于 0 的 if 语句。

函数本身自然想要构建一个 Y,并在 Y 分支的末端创建一个大小为原始 Y 一半的新 Y。完成后,它将打印到标准输出。

#!/bin/bash
declare -A SCREEN
SCREENR=63
SCREENW=100
DEPTH=0
MAX=16

function create_y 
    local originR=$1
    local originC=$2
    local iteration=$3
    local size=$4
    local originVR=0
    local originVC=0
    local originNYLR=0
    local originNYLC=0
    local originNYRR=0
    local originNYRC=0

    if [[ iteration -gt 0 ]]; then
        for ((i=0;i<$size;i++))
        do
            SCREEN[$(($originR-$i)),$originC]=1
            let originVR="$(($originR-$i))"
        done

        for ((i=1;i<=$size;i++))
        do
             SCREEN[$(($originVR-$i)),$(($originC - $i))]=1
             let originNYLR="$(($originVR-$i))"
             let originNYLC="$(($originC - $i))"
             SCREEN[$(($originVR-$i)),$(($originC + $i))]=1
             let originNYRR="$(($originVR-$i))"
             let originNYRC="$(($originC + $i))"
        done

        create_y $(($originNYLR-1)) $originNYLC $(($iteration-1)) $(echo "$size/2" | bc)
        create_y $(($originNYRR-1)) $originNYRC $(($iteration-1)) $(echo "$size/2" | bc)
    fi  


for ((i=1;i<=$SCREENR;i++)) 
do
    for ((j=1;j<=$SCREENW;j++)) 
    do
        SCREEN[$i,$j]='_'
    done
done

read DEPTH

create_y $SCREENR $(echo "$SCREENW/2" | bc) $DEPTH $MAX

for ((i=1;i<=$SCREENR;i++)) do
    for ((j=1;j<=$SCREENW;j++)) do
         printf '%s' "$SCREEN[$i,$j]"
    done
    echo ""
done

exit 0

【讨论】:

感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 其长期价值,通过展示为什么这是解决问题的好方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。【参考方案3】:

试图在下面解释为什么这是最佳的。创建网格和解决问题的想法在逻辑上非常简单。

算法:

创建一个网格。 创建求解函数。 从中间开始创建一列(垂直线),长度为 l(间隔,初始为 16)。 用 1 标记从行尾开始的左右对角线。 你现在有一个 Y! 从 Y 的上角向左和向右递归,以创建“sub-Y”。 递归时确保数据正确(间隔应除以 2 等)。

PS:女士们,先生们,在分享代码时,请在评论时适当尝试,即使是最小的sn-p。它会改变你的生活!

 #!/bin/bash

 declare -A grid

 #Solves the fractal problem.
 #Variables:
 #  d: depth of recursion.
 #  l: length of gaps/interval.
 #  r: row
 #  c: column.
 solve()
  local d=$1
  local l=$2
  local r=$3
  local c=$4

  #base case, return.
  if [ $d -eq 0 ]; then
      return
  fi

# iterate backwards.
# create a column/vertical. line of 1's.
# sizeof(line) = l (length of interval) [initially 16].
# See graph below:
: '
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
'
for (( i = l; i > 0; i-- )); do
    grid[$((r-i)).$c]=1
done

((r -= l))

# iterate backwards.
# create the V-shaped tree/fractal.
# sizeof(tree) = l (length of interval) [initially 16].
# should fill all diagonal cells with 1's .
#       [r-1, c-1] (left), [r-1, c+1] (right) --> 1st.
#       [r-2, c-2] (left), [r-2, c+2] (right) --> 2nd.                                        for(i in [1,l])                        //remember l is dynamic. (16, 8, 4, 2, 1, ..)
#           ...                                                                         ---->       [r-i, c-l] (left), [r-i, c+l] (right) = 1 
#           ...                                                                                 
#       [r-l, c-l] (left), [r-l, c+l] (right) --> 16th (or l-th).


for (( i = l; i > 0; i--)); do
    grid[$((r-i)).$((c-i))]=1
    grid[$((r-i)).$((c+i))]=1
done

: '
    This for n = 1 creates the following pattern:

    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ---------------------------------1-------------------------------1----------------------------------
    ----------------------------------1-----------------------------1-----------------------------------
    -----------------------------------1---------------------------1------------------------------------
    ------------------------------------1-------------------------1-------------------------------------
    -------------------------------------1-----------------------1--------------------------------------
    --------------------------------------1---------------------1---------------------------------------
    ---------------------------------------1-------------------1----------------------------------------
    ----------------------------------------1-----------------1-----------------------------------------
    -----------------------------------------1---------------1------------------------------------------
    ------------------------------------------1-------------1-------------------------------------------
    -------------------------------------------1-----------1--------------------------------------------
    --------------------------------------------1---------1---------------------------------------------
    ---------------------------------------------1-------1----------------------------------------------
    ----------------------------------------------1-----1-----------------------------------------------
    -----------------------------------------------1---1------------------------------------------------
    ------------------------------------------------1-1-------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------




'

#   Now comes the fun part, we should recurse.
#   For a complete analysis about why recursion is optimal u could read CLRS
#   or any other Algorithms book of ur choice (be extra carefull on big-O notation, Master Theorem and recursion trees).

# Idea:
#   - We will subrtact 1 from the depth for each complete fractal we create, so we will eventually terminate.
#   - Interval gets reduced by half for any fractal, thus l' = l/2.
#   - r-l: Executed 2 times (see line 48) will bring us to the left/right topmost part of the newly created Y (left/right corner), on the proper row [---------].
#   - c-l/c+l: Will result us beeing on either left or right corner of the Y [See below figure for more].

: '
    
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ---------------------------------O-------------------------------O----------------------------------        After performing 2 recursive calls (left/right), the execution on the new copy
    ----------------------------------1-----------------------------1-----------------------------------        will start from points marked with "O".
    -----------------------------------1---------------------------1------------------------------------        
    ------------------------------------1-------------------------1-------------------------------------
    -------------------------------------1-----------------------1--------------------------------------
    --------------------------------------1---------------------1---------------------------------------
    ---------------------------------------1-------------------1----------------------------------------
    ----------------------------------------1-----------------1-----------------------------------------
    -----------------------------------------1---------------1------------------------------------------
    ------------------------------------------1-------------1-------------------------------------------
    -------------------------------------------1-----------1--------------------------------------------
    --------------------------------------------1---------1---------------------------------------------
    ---------------------------------------------1-------1----------------------------------------------
    ----------------------------------------------1-----1-----------------------------------------------
    -----------------------------------------------1---1------------------------------------------------
    ------------------------------------------------1-1-------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------




'

# This will work recursivelly so only thing we need to do, is wait and pray that our exit case will work.   
# This can also be seen as "Divide and Conquer" algorithm.

solve $((d-1)) $((l/2)) $((r-l)) $((c-l))
solve $((d-1)) $((l/2)) $((r-l)) $((c+l))



 # Just visualize the grid under given assumptions
 print_grid()
    for ((i=0; i<63; i++)); do
        for ((j=0; j<100; j++)); do
              if [[ $grid[$i.$j] ]]; then
              printf 1
              else
                printf -
              fi
        done
        echo
    done
 

 read n
 solve $n 16 63 49
 print_grid

【讨论】:

以上是关于函数和分形 - 递归树 - Bash!逻辑问题的主要内容,如果未能解决你的问题,请参考以下文章

有没有关于递归算法方面的书?

[LeetCode] 由 “分形" 所想

递归分形

递归分形

Javascript在画布上绘制分形,递归保存和恢复问题

分形 递归+模拟