题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
例如:如果输入如下矩阵:1 2 3 4
5 6 7 8
9 10 11 1213 14 15 16
则依次打印出数字:1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10。
思路如下:
算法如下:
#include <iostream>
#include <map>
using namespace std;
/*打印函数,这个函数传递二维数组用的形参 int arr[][columns],因此当传进来的二维函数维数变化时,就需要改动这里的columns值*/
/*可以把它改成 int ** arr,不过在传递的时候需要注意,传递指针的指针*/
void print_Matrix_InCircle(int arr[][5], int rows, int columns) /**rows:行,columns:列*/
{
if(NULL == arr || columns <= 0 || rows <= 0)
return;
int i = 0,j = 0;
unsigned int k = 0;
unsigned int all_number = rows * columns;
int s[all_number];
int n_c = columns, m_r = rows; /**列,行*/
map<int,int> word_count;
for(int x = 0; x < columns; x++)
{
for(int y = 0; y < rows; y++)
{
word_count[arr[x][y]] = 0;
}
}
while(n_c > 0 && m_r > 0)
{
/** 从左至右,剩余列数必须大于0 */
if(n_c > 0 && i < rows && j < columns) /**不要忘记 i、j 范围的判断*/
{
while(j < columns && !word_count[arr[i][j]])
{
s[k++] = arr[i][j];
//cout << arr[i][j] << ' ';
++word_count[arr[i][j]]; /*标记已访问*/
j++;
}
m_r--; /*可供访问的行数减1*/
j--; /*退出之前 j 多加了一步*/
i++; /*i向下走一步*/
}
/** 从上至下,剩余行数必须大于0 */
if(m_r > 0 && i < rows && j < columns)
{
while(i < rows && !word_count[arr[i][j]])
{
s[k++] = arr[i][j];
//cout << arr[i][j] << ' ';
//cout << arr[1][4] << ' ';
++word_count[arr[i][j]];
i++;
}
n_c--;
i--;
j--;
}
/** 从右至左,剩余列数必须大于0 */
if(n_c > 0 && i < rows && j < columns)
{
while(j >= 0 && !word_count[arr[i][j]])
{
s[k++] = arr[i][j];
//cout << arr[i][j] << ' ';
++word_count[arr[i][j]];
j--;
}
m_r--;
j++;
i--;
}
/** 从下至上,剩余行数必须大于0 */
if(m_r > 0 && i < rows && j < columns)
{
while(i >= 0 && !word_count[arr[i][j]])
{
s[k++] = arr[i][j];
//cout << arr[i][j] << ' ';
++word_count[arr[i][j]];
i--;
}
n_c--;
i++;
j++;
}
}
for(k = 0; k < all_number; k++)
{
cout << s[k] << ' ';
}
cout << endl;
}
int main()
{
/**
int arr1[4][4] ={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16}
};
//int ** p = (int **)&arr1;
//cout << p[1][1];
//int (*p1)[4] = arr1;
print_Matrix_InCircle(arr1,4,4);
cout << endl;
*/
/**
int arr2[5][5] ={
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25}
};
int (*p2)[5] = arr2;
print_Matrix_InCircle(p2,5,5);
cout << endl;
*/
int arr3[4][5] ={
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
};
//int (*p3)[5] = arr3;
print_Matrix_InCircle(arr3,4,5);
/**
int arr4[1][5] ={
{1,2,3,4,5}
};
print_Matrix_InCircle(arr4,1,5);
cout << endl;
*/
/**
int arr5[5][1] ={
{1},
{2},
{3},
{4},
{5}
};
print_Matrix_InCircle(arr5,5,1);
cout << endl;
*/
/**
int arr6[1][1] ={
{1}
};
print_Matrix_InCircle(arr6,1,1);
cout << endl;
*/
/**
int arr7[2][2] ={
{1,2},
{3,4}
};
print_Matrix_InCircle(arr7,2,2);
cout << endl;
*/
return 0;
}
结果如下:
以下是 设置 指针的指针 来指向二维数组的方法:
void Test(int columns, int rows)
{
printf("Test Begin: %d columns, %d rows.\n", columns, rows);
if(columns < 1 || rows < 1)
return;
int** numbers = new int*[rows]; /*注意这里,要给它分配空间*/
/*给一个指向 含有rows个int元素数组的 指针分配了存储空间,并将这个指针,赋给了 number指针*/
for(int i = 0; i < rows; ++i)
{
numbers[i] = new int[columns]; /*注意这里,number[i] 也是一个指针,指向一个数组元素,也需要给它分配空间*/
for(int j = 0; j < columns; ++j)
{
numbers[i][j] = i * columns + j + 1;
}
}
print_Matrix_InCircle(numbers, columns, rows); /*传递 指针的指针*/
printf("\n");
for(int i = 0; i < rows; ++i)
delete[] (int*)numbers[i];
delete[] numbers;
}
需要注意二维数组指针的问题,如:
int arr[5][6];
int (*p)[6] = arr; /* p 是一个指向有 6 个数组元素数组的指针,注意这是一个指向一维数组的指针 */
如果 (int **)强制转换,也不行,转换后无法操作二维数组数据。
/**点滴积累,我的一小步O(∩_∩)O~*/