函数和分形 - 递归树 - 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!逻辑问题的主要内容,如果未能解决你的问题,请参考以下文章