• 카테고리

    질문 & 답변
  • 세부 분야

    알고리즘 · 자료구조

  • 해결 여부

    미해결

39번 두 배열 합치기에서

20.03.16 23:59 작성 조회수 175

0

선생님, 안녕하세요? 저는 선생님께서 코드를 ㅈ작성하시기 이전에 제가 코드를 먼저 ㅈ작성하는 편인데요

강의 중에 포인터? 포인트??? 를 언급하시길래 아 포인터를 사용해야하나 보다 싶어서 포인터를 써서 ㅈ작성을 해봤습니다. 

그랬더니 코드는 다음과 같은데요

원래 index1 index2 index3 이거 없이 그냥 

a, b, c(c는 a,b각각을 합친 배열)에 대한 포인터를 각각

p1 p2, p3로 잡고 

조건에 따라 p1++ p2++ 이렇게 포인터를 증가시키면서 코드를 작성하려 하였더니 합쳐진 p3에서 엑세스 위반이 일어난다고 합니다. 그래서 index1 index2 index3를 각각 0으로 놓고 궁여지책으로라도 코드를 작성해봤는데요

코드는 잘 동작하는 것으로 보입니다.

1) 왜 p1++ p2++할 때에는 액세스 위반이 생기는 건가요?

2) 제 코드에 불필요한 부분이나 부ㅈ족한 부분이 있다면, 가르침을 주시면 감사하겠습니다. 

#include<stdio.h>
#include<stdlib.h>

int main() {
	int* p1, * p2, * p3;
	int* a, * b, * c;
	int N, M;
	int index1 = 0, index2 = 0, index3 = 0;
	scanf("%d", &N);

	a = (int*)malloc(sizeof(int) * N);
	for (int i = 0; i < N; i++) { scanf("%d", &a[i]); }
	
	scanf("%d", &M);
	b = (int*)malloc(sizeof(int) * M);
	
	for (int i = 0; i < M; i++) { scanf("%d", &b[i]); }

	c = (int*)malloc(sizeof(int) * (N + M));

	p1 = a, p2 = b, p3 = c;

	for (int i = 0; i < N; i++) { printf("%d ", *(p1+i)); }
	for (int i = 0; i < M; i++) { printf("%d ", *(p2+i)); }


	//if (*p1 < *p2) { *c = *p1; }
	while (index1 < N && index2 < M) {
		if (*(p1 + index1) < *(p2 + index2)) { *(p3 + index3) = *(p1 + index1); index3++; index1++; }
		if (*(p1 + index1) > * (p2 + index2)) { *(p3 + index3) = *(p2 + index2); index3++; index2++; }
		if(*(p1+index1)==*(p2+index2)){*(p3+index3)=*(p2+index2); index3++; index2++; }
	}

	//a배열이 남은 경우
	printf("%d %d %d \n", index1, index2, index3);


	if (index1 == N) {
		for (int i = index2; i < M; i++) {
			*(p3 + index3) = *(p2 + i);
			index3++;
		}
	}


	for (int i = 0; i < index3; i++) { printf("%d", c[i]); }




}

답변 1

답변을 작성해보세요.

0

포인터가 아니라 포인트입니다. 알고리즘에 투포인트 알고리즘이라는 게 있습니다. 배열의 두 지점을 가르키는 정수형 변수를 잡아서 배열인덱스를 컨트롤 하는 것입니다. 

질문에서 p1++과 p2++로 안된다고 하셨는데 안되는 코드를 주어야 제가 답변을 제대로 할 수 있습니다.   엑세스 위반이 일어난게 포인터 변수인 p1과 p2는 배열의 메모리 주소값이라는 사실을 알면 해결될 수 있는 오류가 아니었나 싶습니다.

알고리즘 문제풀이에 포인터를 잘 안쓰기 때문에 좋은 코드를 짤지는 모르겠지만 제가 p1++과 p2++로 짜봤습니다. 참조해서 더 좋은 코드를 짜보세요. 그리고 영상에서 설명하는 정수형 변수를 이용해 짜는 방식을 잘 알아두세요. 나중에 병합정렬에서 그대로 사용합니다.

#include<stdio.h>
#include<stdlib.h>

int main() {
	int* p1, * p2, * p3;
	int* a, * b, * c;
	int N, M;
	scanf("%d", &N);
	a = (int*)malloc(sizeof(int) * (N+1));
	for (int i = 0; i < N; i++) { scanf("%d", &a[i]); }
	a[N]=2147483647;
	
	scanf("%d", &M);
	b = (int*)malloc(sizeof(int) * (M+1));
	
	for (int i = 0; i < M; i++) { scanf("%d", &b[i]); }
	b[M]=2147483647;

	c = (int*)malloc(sizeof(int) * (N + M+1));

	p1 = a, p2 = b, p3 = c;
	
	while (*p1!=2147483647 || *p2!=2147483647) {
		if (*(p1) < *(p2)) { *(p3) = *(p1); p3++; p1++;}
		else { *(p3) = *(p2);p3++; p2++;}
	}

	for (int i = 0; i < N+M; i++) { printf("%d ", c[i]); }
	return 0;

}