프로그래밍/C언어

이차원배열

mi-nos 2019. 6. 27. 00:58

1) 입력된 수만큼 키판 움직임 

   -  입력문자열  :  1U4D2R1L2D

   -  4*4 키판을 위에 입력 문자열 만큼 이동

void rotateNumberPad(int numberPad[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE], int arraySize, char rotationStr[MAX_DATA_LENGTH] {
	
	for(int i=0; i<strlen(rotationStr); i+=2 ) {
		char tmpStr[3] = {0,};
		strncpy(tmpStr, rotationStr+i, sizeof(char)*2);
		int direction = tmpStr[0] - '0';
		int isUpAndDown = 0;
		if(tmpStr[1] == 'U' || tmpStr[i] == 'D') {
			isUpAndDown =1;
			if(tmpStr[1] == 'U') direction *= -1;
		}else {
			isUpAndDown = 0;
			if(tmpStr[1] == 'L') direction *= -1;
		}
		rotateArr(numberPad, arraySize, direction,isUpAndDown);
	}
}

void rotateArr(int numberPad[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE], int arraySize, int direction, int isUpAndDown) {

	int tmpNumberPad[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE];
	memcpy(tmpNumberPad, numberPad, sizeof(int)*MAX_ARRAY_SIZE*MAX_ARRAY_SIZE);
	for(int i=0; i<arraySize; i++) {
		for(int j=0; j<arraySize; j++) {
			if(isUpAndDown == 1)  numberPad[(arraySize*arraySize+direction+i)%arraySize][j] = tmpNumberPad[i][j];
			else numberPad[i][(arraySize*arraySize+direction+j)%arraySize] = tmpNumberPad[i][j];
		}
	}
}

2) 배열 접기 

   -. 가로접기는 더하기, 세로접기는 곱하기로 마지막까지 접는 것 

   -. 짝수면 접고, 홀수면 가운데 제거 

   -. 가로 세로 접기 

 

void getFoldingArr(int foldingArr[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE], int *foldingArrCnt, int iniArr[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE], int arraySize) {

	memset(foldingArr,0, sizeof(int)*MAX_ARRAY_SIZE*MAX_ARRAY_SIZE); 
	*foldingArrCnt = 0;
	
	int center = arraySize/2; 
	
	//가로 접기
	for(int i=0; i<center; i++) {
		for(int j=0; j<arraySize; j++) {
			foldingArr[i][j] = iniArr[i][j] + iniArr[ArraySize-1-i][j];			
		}
	}
	
	//세로접기
	for(int i=0; i<center; i++) {
		for(int j=0; j<center; j++) {
			foldingArr[i][j] = foldingArr[i][j] * foldingArr[i][ArraySize-1-j];			
		}
	}
	*foldingArrCnt = center;
}

   - 배열크기가 홀수면 가운데 제거하고 다시 가로 세로 접기.. 최후 한개만 남을때까지 

void getFinalValue(int foldingArr[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE], int foldingArrCnt) {
	int arrSize =foldingArrCnt;
	while(1) {
		int tmpFoldingArr[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE];
		memset(tmpFoldingArr, 0, sizeof(int)*MAX_ARRAY_SIZE*MAX_ARRAY_SIZE);
		int newArr[MAX_ARRAY_SIZE][MAX_ARRAY_SIZE];
		int newArrCnt=0;
		
		//홀수면 가운데 삭제 
		if(arrSize%2 == 1) {
			int center = round(arrSize/2);
			int indexI=0;
			int indexJ=0;
			for(int i=0; i<arrSize; i++) {
				if(i != center) {
					for(int j=0; j<arrSize; j++) {
						if(j != center) {
							tmpFoldingArr[indexI][indexJ] = foldingArr[i][j];
							indexJ++;
						}
					}
					indexI++;
					indexJ=0;
				}
			}
			memcpy(foldingArr,tmpFoldingArr, sizeof(int)*MAX_ARRAY_SIZE*MAX_ARRAY_SIZE);
			arrSize -= 1;
		}
		getFoldingArr(newArr, &newArrCnt, foldingArr, arrSize);
		arrSize = newArrCnt; 
		for(int i=0; i<newArrCnt; i++) {
			for(int i=0; i<newArrCnt; i++) {
				folding[i][j] = newArr[i][j];
			}
		}
		if(arrSize == 1) {
			finalValue = foldingArr[0][0];
			break;
		}
	}
}

3) 이차원배열 행렬 기준 오름차순 정렬 

//가로 오름차순 정렬
for(int i=0; i<arrSize; i++) {
	for(int j=0; j<arrSize; j++) {
		for(int k=j+1; k<arrSize; k++) {
			if(arr[i][j] > arr[i][k]) {
				int tmp = arr[i][j];
				arr[i][j] = arr[i][k];
				arr[i][k] = tmp;
			}
		}
	}
}

//세로 오름차순 정렬 
for(int i=0; i<arrSize; i++) {
	for(int j=0; j<arrSize; j++) {
		for(int k=j+1; k<arrSize; k++) {
			if(arr[j][i] > arr[k][i]) {
				int tmp = arr[j][i];
				arr[j][i] = arr[k][i];
				arr[k][i] = tmp;
			}
		}
	}
}

4) 이차원 배열 - 특정 지점에서 인접한 수가 동일하지 않는 경우만 합산 

int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};

//인접한 곳에 같은 수가 없는 경우만 합산
for(int i=0; i<arrSize; i++) {
	for(int j=0; j<arrSize; j++) {
		if(arr[i][j] != 0) {
			int flag=0;
			for(int k=0; k<4; k++) {
				int nx = i+dx[k];
				int ny = j+dy[k]; 
				if(nx<arrSize && nx>=0 && ny<arrSize ny>=0 )  {
					if(arr[i][j] == arr[nx][ny]) {
						flag=1;
						break;
					}
				}
			}
			if(flag == 0) arrSum += arr[i][j];
		}
	}
}

5. 이차원배열 달팽이 채우기 

void snale_matrix(){
    int matrix[5][5];
    int num=1;
    int delta=1;
    int limit=5;
    int i=0,j=-1;
 
    int p,q;
 
    while(1){
 
        //가로로 이동하면서 하나씩 할당
        for(p=0; p<limit; p++){
            j=j+delta;
            matrix[i][j]=num;
            num++;
        }
 
        //횟수 줄이고
        limit--;
 
        if(limit<0) break;
 
        //세로로 이동하면서 하나씩 할당
        for(p=0; p<limit; p++){
            i=i+delta;
            matrix[i][j]=num;
            num++;
        }
 
        //이동방향의 양음이 바뀜
        delta=-delta;
    }
 
    //2차원 배열 출력
    for(p=0; p<5; p++){
        for(q=0; q<5; q++){
            printf("%d\t",matrix[p][q]);
        }
        printf("\n");
    }
 
}

6) 이차원배열내 특정 위치에서 '1'이 연속하여 이어진 갯수 

size =0, copiedData: 이차원배열, x/y : 특정 위치 
int checkTerritory(copiedData, x, y, size) {
	if(copiedData[x][y] == '1') {
		copiedData[x][y] == '2';
		size++;
		
		if(x>0) size = checkTerritory(copiedData, x-1, y, size);
		if(y>0) size = checkTerritory(copiedData, x, y-1, size);
		if(x<MAX-1) size = checkTerritory(copiedData, x+1, y, size);
		if(y< MAX-1) size = checkTerritory(copiedData, x, y+1, size);
		
		return size;		
	}else 
		return size;
}

7) 이차원 배열 전 구간에 영역별 크기 계산 (위의 6번 함수 이용)

만약 전체 경로에서 "1"이 연속된 곳의 위치를 계산하고, 크기순으로 오름차순으로 하면 
for(int i=0; i<MAX; i++) {
	for(int j=0; j<MAX; j++) {
		int tmpSize =0;
		tmpSize = checkTerritory(copiedData, i, j, tmpSize);		
		if(tmpSize) {
			terrSize[(*terrCnt)++] = tmpSize;
		}
	}
} 

//크기순으로 오름차순 정렬
for(int i=0; i<*terrCnt; i++) {
	for(int j=0; j<*terrCnt; j++) {
		if(terrSize[i] > terrSize[j]) {
			int tmp = terrSize[i];
			terrSize[i] = terrSize[j];
			terrSize[j] = tmp;
		}
	}
}