Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash-乘二维矩阵_Bash_Matrix - Fatal编程技术网

Bash-乘二维矩阵

Bash-乘二维矩阵,bash,matrix,Bash,Matrix,假设我有二维矩阵nxn,我们已经知道n=4,值为1-16 我必须将下列各部分相乘: Array1*Array2=结果 数组3*result=result1 数组4*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 } multiply(

假设我有二维矩阵nxn,我们已经知道n=4,值为1-16

我必须将下列各部分相乘:

Array1*Array2=结果

数组3*result=result1

数组4*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
}
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
}
ShowMatrix()
{
echo“MyMatrix是:”

对于((i=0;i所编写代码的主要概念性问题是,您将一个大数组划分为较小的片段,但不针对这些片段的缩减进行调整

具体来说,cut函数中存在一个明确的错误。当存储回Array1..Array3时,您使用的是较大数组的索引,而不是缩减数组的索引。POSIX shell和bash愉快地展开缺少的条目并用零填充它们。因此bash不会帮您在此处找到错误

类似地,乘法函数应该只尝试在缩小大小的数组的边界上乘法。通过将2D数组存储为线性数组,获取数组的边有点麻烦:要么像下面我所做的那样传递维度,要么从数组中提取大小(假设已正确初始化)取平方根

你提到了你所认为的随机行为。我怀疑这里发生的是,从你的环境或从过去的执行中查找的动态变量正在将值输入到各个子例程中。为了防止这种情况,我将在函数中声明所有局部变量。当然,这里的数组不是局部的,而是内部的程序也应该声明这些

这就是为什么我认为其他人建议你使用更合适的语言来做这样的事情。我同意这些评估

但是如果您确实必须使用POSIX shell,您可能应该更好地了解和使用它。您可以使用
bash-n
检查代码的语法。如果代码与POSIX兼容,我在这里强烈推荐这一点,那么
ksh-n
将为您提供对该程序更全面和详细的评论

为了帮助你发现此类程序中的bug,我建议。为了测试代码,我建议使用Kate Ward的单元测试程序

我已经重写了修复bug的代码。尽我所能,它遵循你说的你想做的事情和你拥有的代码。但是你从来没有真正描述过你想做什么,或者对你拥有的特定数据给出预期的答案,所以我没有办法独立检查

下面我建议做但没有做的一件事是干代码(不要重复自己的代码)。如果您传递开始点和结束点以及要存储结果的数组的名称,则可以将4个剪切函数折叠成一个例程。不过,我认为您必须在此处使用eval

同样地,通过传入所处理数组的名称,可以将3个乘法函数合并为一个

我已经通过增强ShowMatrix例程删除了显示代码的数组副本

排版-ir n=4
排版-数组=()
排版-a数组1=()
排版-a数组2=()
排版-a数组3=()
排版-a数组4=()
排版-结果=()
排版-a结果1=()
排版-a结果2=()
ShowMatrix(){
字体arr=$1
字体n=$2
排版-i
echo“矩阵$arr为:”

为了((i=0;IIMNSHO,BASH不是一个合适的矩阵乘法语言。您可能可以做到这一点,但这并不容易。您也可以在 SED中进行,因为<代码> SED在计算上是完整的;但是,这比使用BASH更滑稽。主要条件是使用BASH!但是错误是逻辑上的。如果你想在下标中进行乘法,
${variable[$((3*2+2))}
工作(访问元素8),
${variable[$($I*$n+$j))]}
甚至
${variable[$((I*n+j))}
以获得合适的
i
n
j
值。不过,我仍然不认为使用Bash来完成这项任务是个好主意,但虐待狂教师显然不这么认为。@JonathanLeffler:实际上,对于数组变量,下标的计算是算术的,所以您不需要
$(…)
或美元符号。请参阅:“下标被视为必须计算为数字的算术表达式。”@rici:我喜欢缺少正交性。有时确实会发生,有时不会发生;如果不仔细阅读手册中的每一个该死的单词,就无法知道哪一个适用。规则中有太多的例外。好吧,我不知道代码有什么问题,但我不会尝试它。我对whet有两个想法她想删除我的另一条评论(这条评论可能很快就会从这个凡人的圈子中消失)。
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
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