C언어 문자열 선택정렬에 관해서 질문드립니다.
글쓴이: lhs8421478 / 작성시간: 월, 2013/01/28 - 3:25오후
안녕하세요 C언어 공부를 하고 있는 청년입니다..
우선 배열 main에서 배열선언과 호출은 아래와 같은 소스로 했고요
char string_arr[MAX_STRING][MAX_LENGTH] ={"programer", "joy", "root", "super", "sound", "he"}; select_sort_string(string_arr);
이렇게 해서 배열을 넘겨 주고 선택정렬 하는 함수는 아래와 같이 코딩 했습니다.
/** 문자열 선택정렬 함수 인자값으로 받은 이차원 배열에 저장된 문자열을 알파벳 순으로 선택정렬 한다. **/ void select_sort_string(char (*arr)[20]) { int num1; int num2; char (*min)[20]; char tmp[20]; memset(tmp, 0x00, sizeof(20)); for (num1 = 0; num1 < 5 ; num1++) { min = &arr[num1]; for (num2 = num1 + 1; num2 < 6; num2++) { if (strcmp(min[num1], arr[num2]) > 0) { min = &arr[num2]; } } if (arr[num1] != *min) { strcpy(tmp, arr[num1]); strcpy(arr[num1], *min); strcpy(*min, tmp); } } }
프로그램을 돌렸을 경우
제가 생각한 완성은 he joy programer root super sound
라고 출력이 되는거였습니다.
그러나 현재 출력상황은
he programer joy super sound root 라고 출력이 됩니다.
단계별로 확인해보니 joy가 programer랑 strcmp로 비교할때 joy이가 programer보다 커서 결과값이 0보다 큰값이 리턴이 됩니다.
이 부분이 전혀 이해가 안가는데 도움 부탁드립니다.
Forums:
음 ..
char (*min)[20]; ... 정말 의도를 알기 어렵군요..;;
진짜 min 값은 아마도 min[0] 에 있을텐데, min[num1] 에서 참조가 잘못 일어나는걸로 보입니다.
그 코드 그대로 쓰신다면 strcmp(min[num1], arr[num2]) 부분에서 *min 이나 min[0] 로 바꾸시면 되겠네요.
근데.. 그냥 char *min 으로 바꾸시거나, int min_index; 정도로 바꾸시는게 나을것 같습니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
답글 감사합니다.
흠..(*min)[20]을 사용한 이유는 이차원 배열이라 배열을 가르키는 포인터도 이차원 배열을 가르칠수 있는 포인터를 사용해야 된다고 생각해서 사용해 보았습니다.
소스코드 다시 한글자 한글자 비교해보니 min값이 이상한 값을 가르키고 교환을 하더군요...
min[num1][0]과 arr[num2][0]을 비교해본결과 첫번째 바퀴에서
min[num1][0]이 가르키는 값은 p가 맞고요.. 그리고 j로 변경되고
두번째 바퀴에서는 r을 가르키고 있어서... 이 문제점을 찾아보고 있습니다... 크... 머리아프네요 ㅠㅠ
음 ..
min 에 저장되어야 하는 값은 arr 의 특정 element 이고, 얘는 그냥 char array (equiv. char *) 입니다.
그러니 min 은 그냥 char * 로 쓰는게 맞는거죠. 즉, 개별 단어의 주소만 min 에 저장하는겁니다.
올리신 코드를 보면 min[0] 에만 최소값이 저장되는데 min[num1] 처럼 써버리면, 최소값이 아닌 문자열과 arr[num2] 를 비교해 버리게 됩니다.
엉뚱한 단어와 비교하고, 그 결과를 반영하게 되는 셈이니 오동작 하게 되는 거죠.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
strcmp 하기 직전에, 내가 지금 비교하는 원소
strcmp 하기 직전에, 내가 지금 비교하는 원소 두 개가 뭔지 min[num1]과 arr[num2] 를 출력시켜보세요.
의도한 것을 비교하고 있지 않을 겁니다.
그리고 for 루프 끝나기 전에 배열의 현재 상태를 출력시켜보시고요.
지금 작성하신 코드는 num1 이 0일 때는 잘 동작할 겁니다.
그러나 두번째 루프에서 num1이 1이 되는 순간
즉 엉뚱한 두 원소를 비교하며 최소를 찾고 있고, 그렇게 찾은 것을 arr[num1]과 스왑하고 있으니 정렬이 엉망이 됩니다.
좋은 하루 되세요!
그...그렇군요....
현재 말씀하신대로... strcmp하기 직전 출력해보니...
말씀하신 그대로 되네요...
마지막에는 이상한 저장공간에 있는걸 끌어다 쓰고 비교까지 하고 있네요...
이제 이걸 고치는일만 남았군요... 돌머리좀 굴려보겠습니다..
답변 감사합니다 ^^
min의 값을.... 도대체 어찌 해야될지 모르겠네요 ㅠㅠ
min의 값이 완전 이리저리 왔다 갔다 거리네요...
min값을 초기에 arr[0]에 놓고...
if문 안에서 min값이 변경이 될텐데.. 이게 완전 삼천포로 튀어버리네요...
계속 같은 문제로 고민하시는거 같아서 약간에 도움을
계속 같은 문제로 고민하시는거 같아서 약간에 도움을 드리면
아마도 포인터와 배열에 대한 개념이 아직 덜 잡히신거같습니다.
저도 말주변이 없어서 잘 설명을 하지 못하는데
min = &arr[0]; 이 초기화는 char (*min)[20]; 에서 (*min)[0];만 초기화 된겁니다.
즉 선언에서 포인터를 20개 선언하고 그중 하나만 초기화했는데
아마도 나머지 뒷부분은 배열을 따라 초기화 된거라고 생각하신거같은데
참 글로 설명하기 힘드네요 ㅠㅠ
근데 사용을
if (strcmp(min[num1], arr[num2]) > 0) {
이런식으로 초기화가 안된 데이터 min[num1] 사용하니깐 꼬이기 시작한 겁니다.
생각 하신대로 동작되게할려면 초기화를
min[i] = &arr[i]; 루프로 하면 되겠죠^^
포인터에 대해 저도 많이 고생했습니다. 아직도 힘듭니다.ㅋㅋㅋ 수고하세요
인생은 도박이다.
답변 감사합니다.
답변 감사합니다.
에고... 포인터에 대해 이제 좀 알겠네... 싶어서 좀더 보다보면
산덩이처럼 불어나버리네요....
정말 어려운거 같네요....
이제 소스코드는
이렇게 바꿨는데...
실행 화면은 생각대로 또 안나오고 전혀 엉뚱하게 나오네요...
미추어 버리겠네요 정말 ㅎㅎㅎㅎ
더 공부를 해봐야겠어요 ㅠㅠ
음 ..
위에서 계속 strcmp(min[num1], arr[num2]) 에서 min[num1] 이 잘못 되었다고 설명드렸는데..
아직 이해를 못 하신 듯 하네요.
min = &arr[num2];
이건 arr[num2] 이후의 element 들을 min 에 저장하겠다는 뜻이죠?
min[0] 은 arr[num2] 가 맞고, 최소값을 갖고 있지만..
min[num1] 은 단지, arr[num2] 이후의 element 중의 하나 일 뿐입니다.
num1 이 0 이 아니라면, 내가 저장한 min 이 아닌, 전혀 의도하지 않은 문자열을 가지고 비교하게 되는 겁니다.
더군다나 num1 이 MAX_STRING - num2 보다 크면 array 의 index 를 초과하는 문제도 있죠.
실제로 필요한 건 min 값에 해당하는 문자열의 pointer 나 array 의 index 뿐입니다.
char (*min)[20] 처럼 array 의 pointer 로 선언해서 쓸 이유가 없고..
그렇게 쓰더라도 실제 min[0] 또는 *min 에 해당하는 문자열만 min value 로 처리해야 합니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
답글 감사합니다....
흠.. 뭔가 복잡하네요... 리눅스에서 GCC로 돌리다보니 warning도 좀 많고요...
warning 없이 처리한다고 이것저것 많이 해봤네요...
그냥 결국 간단하게....
min 을 2차원배열포인터로 안하고... 간단하게.... 걍 포인터 사용해서 쉽게 처리해버렸습니다 ㅡㅡa
2차원 배열포인터는 아직 뭔가 어렵네요 ㅠㅠ 더 공부좀 해봐야겠어요...
계속 min값을 이동시키니 이놈의 시작 위치가 달라져서 배열포인터 안에 담고 있는 값도 틀려져서 계속 삽질만 한거 같았네요 ㅠㅠ
도움 주셔서 감사합니다 (__)
ctrl+f 브라우져에서 찾기를 해보세요 그럼 다음
ctrl+f 브라우져에서 찾기를 해보세요
그럼 다음
min[num1]
이걸 검색해보세요. 님이 자꾸 바꿔봤다는 소스에보면
min[num1] 이걸 잘못 사용하고 있다고 계속 말해도 그대로 사용하면서
엉뚱한거만 바꾼거 같네요.
왜 min[num1] 이걸 사용하면 안되는지 공붓해보세요.
답글 감사합니다
답글 감사합니다
리눅스 vi환경이라 ctrl + f 가 없는게 아쉽네요 ㅠㅠ
님 말씀데로... 2차원 배열포인터인데 min(num1)은... min이란놈이 이동하면서 새로 가르켜서 가르키고 있는 값이 틀린데 엉뚱한걸 제가 계속 끌어다 썻네요....
그래서 간단하게 그냥.... 1차원 포인터로 해결 봤습니다 ㅠㅠ
답글 감사했습니다 (__)
댓글 달기