【问题标题】:Switching Matrix columns and rows in C++在 C++ 中切换矩阵的列和行
【发布时间】:2014-12-05 22:54:33
【问题描述】:

我有一个 6 x 6 矩阵,我将它的值存储在一个大小为 36 的一维数组中。我想重新排列它,使行是列,列是行。我的方法是尝试将值复制到另一个数组中,但排序正确。我正在尝试一个 for 循环:

    for (int i = 0; i < 6; ++i){
        copyArray[i]= array[i*6];
    }

这对于由第一列组成的第一个新行很好,但我如何继续做所有这些?我尝试过嵌套 for 循环,但无法使用迭代器提出正确的算法。我可以手动执行此操作,但希望通过代码完成。

我正在使用 C++ 进行编码,但如果有人可以使用类似的语言进行编码,那就太好了。我觉得这是一道数学题。

问题:如何解决切换行和列的问题? (示例:如果我将第一行和第一列表示为 0,在 6x6 矩阵中,那么行和列都从 0 变为 5。因此,通过切换行和列,将切换第 2 行、第 5 列中的值使用第 5 行第 2 列中的值。)

【问题讨论】:

  • 不能将矩阵存储为二维数组吗?
  • @MuhammetAliAsan:这有什么帮助?
  • 这叫做做一个矩阵转置

标签: c++ arrays math matrix row


【解决方案1】:

难道你不能只使用一个嵌套的for 循环来做这样的事情吗?

for (int i = 0; i < 6; ++i)
    for (int j = 0; j < 6; ++j)
        copyArray[i*6+j]= array[j*6+i];

这是一个你可以运行的测试程序来证明它是有效的:

#include <stdio.h>

int main()
{
    int array[36] = {1,1,1,1,1,1,
                     2,2,2,2,2,2,
                     3,3,3,3,3,3,
                     4,4,4,4,4,4,
                     5,5,5,5,5,5,
                     6,6,6,6,6,6};
    int copyarray[36];

    for (int i = 0; i < 6; ++i)
        for (int j = 0; j < 6; ++j)
            copyarray[i*6+j]= array[j*6+i];

    for (int i = 0; i < 36; ++i)
    {
        if (i % 6 == 0)
            printf("\n");

        printf("%d ", array[i]);

    }

    printf("\n");
    printf("\n");

    for (int i = 0; i < 36; ++i)
    {
        if (i % 6 == 0)
            printf("\n");

        printf("%d ", copyarray[i]);
    }

    return 0;
}

输出:

1 1 1 1 1 1 
2 2 2 2 2 2 
3 3 3 3 3 3 
4 4 4 4 4 4 
5 5 5 5 5 5 
6 6 6 6 6 6 


1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6 
1 2 3 4 5 6

【讨论】:

  • 谢谢,我试试看。这正是我试图做的,但无法找出正确的变量/数学运算符组合。复杂代数感觉就像古老的知识。
  • 我为找出[] 中的两个公式所做的只是列出我希望它们成为的值,然后将模式以 6 表示,最后以 @987654326 表示@ 和 j。例如,我们希望左边的那个遵循模式0 1 2 3 4 5 6 7 8 9 10 11 12 ... 35,我们希望右边的遵循模式0 6 12 18 24 30 1 7 13 19 25 31 ... 35。接下来我们用6 表示:第一个模式变成(0*6+0) (0*6+1) ... (5*6+5),第二个模式变成(0*6+0) (1*6+0) (2*6+0) ... (5*6+5)。最后我们可以用ij 来表示。
【解决方案2】:

您应该将一维数组保存在一个类中。
然后,您可以在不实际移动数据的情况下交换数据的维度。

class MySwapableArray
{
     bool  normal;
     int   array[36];


     public:
         int& operator()(int x, int y)
         {
              int  h = normal ? x : y;
              int  v = normal ? y : x;

              return array[h*6+v];
         }
         void swapRowsAndColumns()
         {
             normal = ! normal;
         }
 };

如果您想像 A[x][y] 一样使用 operator[],请参阅:How to overload array index operator for wrapper class of 2D array?

【讨论】:

    【解决方案3】:

    这样做的模板。

    template<class X> std::unique_ptr<typename std::pointer_traits<X>::element_type[]>
    transpose(const X& p, int x, int y) {
        using T = std::pointer_traits<X>::element_type;
        std::unique_ptr<T[]> r = new T[x*y];
        for(int a = 0; a < x; ++a)
            for(int b = 0; b < y; ++b)
                r[x*a+b] = p[y*b+a];
        return r;
    }
    

    【讨论】:

      【解决方案4】:

      如果你想避免双重 for 循环,你应该能够用类似的东西在数学上做到这一点

      for (int i = 0; i < 36; ++i) {
          copyarray[6 * (i % 6) + i / 6] = array[i]
      }
      

      基本上,6 * (i % 6) 将您与转置矩阵中的右行对齐,i / 6 (ab) 使用整数除法将列值转换为行值。如果你能忍受混乱,floor (i / 6.0) 更正确。

      【讨论】:

        【解决方案5】:
        for( int i=0;i<6;i++)
           for( int j=0;j<6;j++)
              {         }//You can do whatever you want on original matrix here
        

        假设你想要“矩阵的转置”并做一些处理。基本上切换 i 和 j

         for( int j=0;j<6;j++)   // replaceed i with j
           for( int i=0;i<6;i++)
              {              }//You can do whatever you want on transpose matrix here
        

        【讨论】:

        • 是的,我试图这样做,但无法弄清楚开关的变量/操作符序列。是代数困扰着我,但谢谢!
        • @JCoder:顺便说一句:在您接受了一个答案(以最有帮助的一个)之后,您将获得 16 个代表(另外 2 个),因此足以支持任何对您有帮助的答案(也在您的旧问题,如果您想重新访问它们)。虽然不只是因为有人试图提供帮助而对答案投赞成票,但因为答案本身很有帮助。
        • @JCoder 你应该接受其中一个答案并投票
        猜你喜欢
        • 1970-01-01
        • 2021-11-09
        • 1970-01-01
        • 1970-01-01
        • 2016-03-30
        • 1970-01-01
        • 2015-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多