仅使用指针横向打印数组(转置)

时间:2018-06-22 12:04:34

标签: c arrays pointers gcc

我正在尝试编写一种名为“ transpose”的方法,该方法仅使用指针就可以“横向”打印2D数组(即其列为行,其行为列),即使int i作为索引也不被接受。 每个数组的单元格0都包含其大小,并且在大数组的末尾有一个Null地址。

示例:

int A[] = { 5,-5,14,5,2 };
int B[] = { 3,6,11 };
int C[] = { 4,1,-3,4 };
int D[] = { 6,2,7,1,8,2 };
int E[] = { 2,15 };
int F[] = { 3,4,-2 };
int *All[] = { A,B,C,D,E,F,NULL };

方法需要打印:

-5    6   1   2   15   4
14   11  -3   7       -2
 5        4   1     
 2            8     
              2         

(注意:我们只打印单元格1中的数组,因为我们不打印尺寸)

这是我到目前为止的进展:

我已经制作了一种方法,该方法返回最长数组的地址:

int * getMax(int **All) 
      {
          int * max = (*All);
          while (*All != NULL)
          {
              if ((*All)[0] > max[0]) 
              {
                  max = (*All);
          }
          *All++;
      }
      return max;
      }

这将返回D的地址,然后我可以通过以下方式访问值6(这是最大的行):

void transpose(int **All) 
     {
         int * lines = getMax(All);
         int * m = lines + lines[0];
         lines++;
         while (lines != m) 
         {
                 lines++;
         }
     }

这将运行一次外循环5次,因此我们可以打印5行。 然后我们可以对列数进行内部循环,并可以使用关键字NULL作为终止点

void transpose(int **All) 
     {
         int * lines = getMax(All);
         int * m = lines + lines[0];
         lines++;
         while (lines != m) 
         {
             int ** arr = All;
             while (*arr != NULL) 
             {
                *arr++;
         }
                 lines++;
     }

我遇到了一个问题,那就是其他数组小于5(最大行长)。我如何确保它打印出空白并且不会超出范围。

3 个答案:

答案 0 :(得分:2)

要解决您的问题:

  

问题…其他数组是否小于5(最大行长),我如何确保它打印空白并且不会超出范围(?)

最简单的方法就是精确地(在打印时)检查实际行数是否少于元素数。

考虑以下替代方法:

#include <stdio.h>

// I don't care WHICH one is the longest
int find_longest(int **ppi)
//                   ^^^^^ this is NOT a 2D array... 
{
    int longest = 0;
    if ( ppi )
    {
        while (*ppi)
        {
            if ( (*ppi)[0] > longest )
            {
                longest = (*ppi)[0];
            }
            ++ppi;
        }
    }
    return longest;
}

void print_transposed(int **ppi)
{
    int rows_to_be_printed = find_longest(ppi);

    for (int row = 1; row < rows_to_be_printed; ++row)
    {
        for (int i = 0; ppi[i]; ++i)
        {
            // the first element is the number of elements, so...
            if (ppi[i][0] > row)
            {
                printf("%4d", ppi[i][row]);
            }
            else
            {
                printf("    ");   
            }
        }
        puts("");
    }
}

int main()
{
    // The first element is the number of elements, including itself (odd…)
    int A[] = { 5,-5,14,5,2 };
    int B[] = { 3,6,11 };
    int C[] = { 4,1,-3,4 };
    int D[] = { 6,2,7,1,8,2 };
    int E[] = { 2,15 };
    int F[] = { 3,4,-2 };
    // Please note that this is NOT a 2D array, it's an array of pointers
    int *All[] = { A,B,C,D,E,F,NULL};

    print_transposed(All);
}

这将打印出来:

  -5   6   1   2  15   4
  14  11  -3   7      -2
   5       4   1        
   2           8        
               2        

编辑

我忘了考虑作业的限制之一:

  

仅使用指针,这意味着不允许您声明整数值

这是可行的,只是使代码更难看:

int *find_longest(int **ppi)
{
    int *longest = NULL;
    if ( ppi )
    {
        longest = *ppi;
        while (*ppi)
        {
            if ( **ppi > *longest )
            {
                longest = *ppi;
            }
            ++ppi;
        }
    }
    return longest;
}

void print_transposed(int **ppi)
{
    int *longest = find_longest(ppi);
    if ( longest )
    {
        int *end_of_longest = longest + *longest;
        for (int *row = longest + 1; row != end_of_longest; ++row)
        {
            for (int **ppj = ppi; *ppj; ++ppj)
            {
                if ( (*ppj)[0] > row - longest)
                {
                    printf("%4d", (*ppj)[row - longest]);
                }
                else
                {
                    printf("    ");   
                }
            }
            puts("");
        }
    }
}

答案 1 :(得分:1)

另一种转置数组的选项。

#include <stdio.h>

int main ( void) {
    int A[] = { 5,-5,14,5,2 };
    int B[] = { 3,6,11 };
    int C[] = { 4,1,-3,4 };
    int D[] = { 6,2,7,1,8,2 };
    int E[] = { 2,15 };
    int F[] = { 3,4,-2 };
    int *All[] = { A,B,C,D,E,F,NULL };
    int **line = All;//used to iterate through arrays A, B, C...
    int *col = *line;//points to an array and then an element in array
    int *repeat = *line;//flag to continue do/while
    int *astart = *line;//set to first array first element ex A[0]
    int *acurr = astart;//set to track do/while element ex A[1], A[2]...

    do {
        line = All;//reset line for each iteration
        repeat = NULL;//set so as to stop loop if no more elements
        while ( line && *line) {//loop to sentinel NULL
            if ( *line == astart) {//at the first array in this example A[]
                ++acurr;//advance current pointer to next element ex A[1], A[2]...
            }
            col = *line;//set col to point to each array A[0], B[0], C[0]...
            col += acurr - astart;//advance col to each element in each array A[n]...
            if ( **line > ( acurr - astart)) {//if value at **line ( ex A[0]) greater than n
                printf ( "%-5d", *col);//print value
                if ( **line > ( acurr - astart) + 1) {//indicates are there more elements
                    repeat = col;//set so as to repeat do/while
                }
            }
            else {
                printf ( "     ");//print spaces
            }
            line++;//next array A[0], B[0], C[0]...
        }
        printf ( "\n");
    } while ( repeat);//loop exits it repeat == NULL

    return 0;
}

答案 2 :(得分:1)

#include <stdio.h>                                                              

int main()                                                                      
{                                                                               
  int A[] = { 5,-5,14,5,2 };                                                    
  int B[] = { 3,6,11 };                                                         
  int C[] = { 4,1,-3,4 };                                                       
  int D[] = { 6,2,7,1,8,2 };                                                    
  int E[] = { 2,15 };                                                           
  int F[] = { 3,4,-2 };                                                         
  int *All[] = { A,B,C,D,E,F,NULL };                                            

  int index = 1;                                                                
  int rem   = 6;     // change this to a function which returns length of All[]                                                   

  while (rem > 0)                                                               
  {                                                                             
    for (int i = 0; i < 6; i++)      // Here also change 6 with a function                                           
    {                                                                           
      int *arr = All[i];                                                        

      if (index < arr[0])                                                       
        printf("%-4d", arr[index]);                                             
      else                                                                      
      {                                                                         
        rem--;                                                                  
        printf("    ");                                                         
      }                                                                         
    }                                                                           

    index++;                                                                    
    printf("\n");                                                               
  }                                                                             

  return 0;                                                                     
}