/*
Challenge Description:
Write a program to print a 2D array (n x m) in
spiral order (clockwise)
Input sample:
Your program should accept as its first
argument a path to a filename. The input file contains several lines.
Each line is one test case. Each line contains
three items (semicolon delimited).
The first is 'n'(rows), the second is
'm'(columns) and the third is a single space separated list of
characters/numbers in row major order.
E.g. 3;3;1 2 3 4 5 6 7 8 9
*/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
enum exception_code {
file_open_error = -2, size_mismatch
};
class matrix {
public:
void spiralPrint(const char *);
private:
void initArray(string);
void printRectangle(int);
void printTopRow(int);
void printLeftColumn(int);
void printBottomRow(int);
void printRightColumn(int);
private:
int row, column;
vector<string> arr;
};
void matrix::spiralPrint(const char * fileName) {
ifstream ifs;
ifs.open(fileName);
if (!ifs.is_open()) {
throw file_open_error;
}
string line;
while (getline(ifs, line)) {
try {
initArray(line);
}
catch (int & e) {
cerr << "Size of matrix is wrong!" << endl;
}
int layer = 0;
while (min(row, column) > 2*layer) {
printRectangle(layer);
layer++;
}
cout << endl;
}
ifs.close();
}
void matrix::initArray(string line) {
string str[2];
for (int i = 0; i < 2; i++) {
size_t pos = line.find(";");
str[i]= line.substr(0, pos);
line.erase(0, pos+1);
}
istringstream n(str[0]);
istringstream m(str[1]);
n >> row;
m >> column;
istringstream
iss(line);
arr.clear();
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (iss.eof()) {
throw size_mismatch;
}
string element;
iss >> element;
arr.push_back(element);
}
}
}
void matrix::printRectangle(int layer) {
if (row - 1 == 2 * layer) {
printTopRow(layer);
return;
}
if (column - 1 == 2 * layer) {
int start = layer;
int end = row - layer;
for (int i = start; i < end;
i++) {
cout << arr[column*i+(column-1-layer)] << " ";
}
return;
}
printTopRow(layer);
printRightColumn(layer);
printBottomRow(layer);
printLeftColumn(layer);
}
void matrix::printTopRow(int layer) {
int start = layer;
int end = column - layer;
for (int i = start; i < end;
i++) {
cout << arr[column*layer+i] << " ";
}
}
void matrix::printRightColumn(int layer) {
int start = layer + 1;
int end = row - layer;
for (int i = start; i < end;
i++) {
cout << arr[column*i+(column-1-layer)] << " ";
}
}
void matrix::printBottomRow(int layer) {
int start = column - 2 - layer;
int end = layer;
for (int i = start; i >= end;
i--) {
cout << arr[column*(row-1-layer)+i] << " ";
}
}
void matrix::printLeftColumn(int layer) {
int start = row - 2 - layer;
int end = layer;
for (int i = start; i > end;
i--) {
cout << arr[column*i+layer] << " ";
}
}
int main(int argc, const char * argv[])
{
matrix m;
if (argc != 2) {
cerr << "please enter a file name!" << endl;
return 0;
}
try {
m.spiralPrint(argv[1]);
}
catch (int & e) {
cerr << "Fail to open file!" << endl;
}
return 0;
}
No comments:
Post a Comment