我必须增加以下部分:
Array1 * Array2 =结果
Array3 * result = result1
Array4 * result1 = result2
ShowMatrix() { echo "MyMatrix is:" for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do printf ' '${myArray[i*n+j]} done printf '\n'; done }
我尝试将它分成4个部分,就像在模式中一样,并将每个部分分配给Array1,Array2,Array3和Array4
cut1() { for((i=0;i<$n/2;i++))do for((j=0;j<$n/2;j++))do Array1[i*n+j]=${myArray[i*n+j]} done done } cut2() { for((i=0;i<$n/2;i++))do for((j=$n/2;j<$n;j++))do Array2[i*n+j]=${myArray[i*n+j]} done done } cut3() { for((i=$n/2;i<$n;i++))do for((j=0;j<$n/2;j++))do Array3[i*n+j]=${myArray[i*n+j]} done done } cut4() { for((i=$n/2;i<$n;i++))do for((j=$n/2;j<$n;j++))do Array4[i*n+j]=${myArray[i*n+j]} done done }
在那之后,我试着像在模式中那样将它们相乘:
Array1 * Array2 =结果
Array3 * result = result1
Array4 * result1 = result2
multiply() { for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do result[i*n+j]=0 for((k=0;k<$n;k++))do let "result[i*n+j]=${result[i*n+j]}+${Array1[i*n+k]}*${Array2[k*n+j]}" done done done } multiply1() { for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do result1[i*n+j]=0 for((k=0;k<$n;k++))do let "result1[i*n+j]=${result1[i*n+j]}+${result[i*n+k]}*${Array3[k*n+j]}" done done done } multiply2() { for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do result2[i*n+j]=0 for((k=0;k<$n;k++))do let "result2[i*n+j]=${result2[i*n+j]}+${result1[i*n+k]}*${Array4[k*n+j]}" done done done }
cut1 cut2 cut3 cut4 multiply multiply1 multiply2 echo "result is:" for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do printf ' '${result[i*n+j]} done printf '\n'; done echo "result1 is:" for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do printf ' '${result1[i*n+j]} done printf '\n'; done echo "result2 is:" for((i=0;i<$n;i++))do for((j=0;j<$n;j++))do printf ' '${result2[i*n+j]} done printf '\n'; done
解决方法
具体来说,切割函数中存在一个明确的错误.存储回Array1..Array3时,您使用的是较大数组的索引而不是简化数组. POSIX shell和bash愉快地扩展缺少的条目并用零填充它们.所以bash不会帮助你在这里找到你的bug.
类似地,乘法函数应该只尝试乘以减小大小的数组的边界.通过将2D数组存储为线性数组,获取数组的一侧有点小问题:要么像下面那样传递尺寸,要么可以从数组中获取大小(假设已经正确初始化)并采取平方根.
你提到你认为的随机行为.我怀疑这里发生的是从您的环境或过去执行中查找的动态变量是将值提供给各个子例程.为了防止这种情况,我将声明函数内的所有局部变量.当然,那里的数组不是本地的,但同样,在程序中你也应该声明它们.
这就是为什么我认为其他人建议你使用更合适的语言来做这样的事情.我同意这些评估.
但是如果你必须使用POSIX shell,你可能应该知道并更好地使用它.您可以使用bash -n语法检查代码.如果代码是POSIX兼容的,我强烈推荐这里,那么ksh -n将给你一个更彻底和详细的批评程序.
为了帮助你找到这个程序中的错误,我建议the bash debugger.为了测试代码,我建议Kate Ward的单元测试程序shunit.
我重写了修复bug的代码.尽可能地告诉它你说你想做什么以及你拥有的代码.但是你从来没有真正描述过你要做的事情,或者对你所拥有的具体数据给出了预期的答案,所以我没有办法独立检查.
我建议做但但下面没做的一件事就是DRY(不要重复自己)代码.如果您传递起点和终点以及要存储结果的数组的名称,则可以将4个剪切函数折叠成单个例程.我认为您必须在此处使用eval.
同样,通过传入要处理的数组的名称,可以将3个乘法函数折叠成一个.
我通过加强你的ShowMatrix例程删除了数组显示代码的副本.
typeset -ir n=4 typeset -a Array=() typeset -a Array1=() typeset -a Array2=() typeset -a Array3=() typeset -a Array4=() typeset -a Result=() typeset -a Result1=() typeset -a Result2=() ShowMatrix() { typeset arr=$1 typeset n=$2 typeset -i i echo "Matrix $arr is:" for ((i=0;i<n;i++)) ; do typeset -i j typeset -i val for ((j=0;j<n;j++)) ; do ((val=${arr}[i*n+j])) printf '%5d ' $val done printf '\n'; done } cut1() { typeset -i i typeset -i k=0 for((i=0;i<n/2;i++)) ; do typeset -i j for((j=0;j<n/2;j++)); do ((Array1[k++] = Array[i*n+j])) done done } cut2() { typeset -i i typeset -i k=0 for((i=0;i<n/2;i++)) ; do typeset -i j for((j=n/2;j<n;j++)) ; do ((Array2[k++] = Array[i*n+j])) done done } cut3() { typeset -i i typeset -i k=0 for((i=n/2;i<n;i++)) ; do for((j=0;j<n/2;j++)) ; do ((Array3[k++] = Array[i*n+j])) done done } cut4() { typeset -i i typeset -i k=0 for((i=n/2;i<n;i++)) ; do for((j=n/2;j<n;j++)); do ((Array4[k++] = Array[i*n+j])) done done } multiply() { typeset -i i typeset -i n=$1 ShowMatrix Array1 $n ShowMatrix Array2 $n for((i=0;i<n;i++)); do typeset -i j for((j=0; j < n; j++)); do typeset -i l ((l=i*n+j)) ((Result[l]=0)) typeset -i k for((k=0; k<n; k++)) ; do ((Result[l] += Array1[i*n+k]*Array2[k*n+j])) done done done } multiply1() { typeset -i n=$1 ShowMatrix Result $n ShowMatrix Array3 $n typeset -i i for((i=0; i < n; i++)) ; do typeset -i j for((j=0; j < n; j++)); do typeset -i l ((l=i*n+j)) ((Result1[i*n+j]=0)) typeset -i k for ((k=0;k<n;k++)); do ((Result1[l] += Result[i*n+k]*Array3[k*n+j])) done done done } multiply2() { typeset -i i typeset -i n=$1 ShowMatrix Result1 $n ShowMatrix Array4 $n for ((i=0; i<n; i++)) ; do typeset -i j for ((j=0; j < n; j++)) ; do typeset -i l ((l=i*n+j)) ((Result2[i*n+j]=0)) typeset -i k for((k=0;k<n;k++)); do ((Result2[l] += Result1[i*n+k]*Array4[k*n+j])) done done done } typeset -i i for((i=0; i<n*n; i++)) ; do ((Array[i]=i+1)) done cut1 cut2 cut3 cut4 typeset -i n2 ((n2 = n / 2)) multiply $n2 multiply1 $n2 multiply2 $n2 ShowMatrix Result2 $n2