소트할때 직접 문자열을 복사하고 있는 부분이 문제인 것 같습니다.
그리고 소트도 한번에 할 수 있을 것 같습니다.
1181번 - 단어 정렬
길이 나열이랑 사전 나열이랑 한번에 할 수 있다는 건가요?
길이 나열과 사전 나열을 한번에 하는 건 이해가 되었습니다!
+ 밑에는 길이와 사전 나열을 한번에 하고 =대신 swap을 사용하였습니다 시간 초과는 동일합니다.
제가 초보라 위에서 퀵소트 할때 string 문자열을 =을 이용해서 직접 복사하는 방법 외에는 잘 알지못하는데 혹시 다른 방법이 있을까요?
* 일단 죄송합니다. ㅠㅠ
올리신 소스에서 가장 큰 문제는 quicksort 구현이 잘못되었습니다
첫번째 소스에서 27,28 라인이 29라인 뒤로 나와야 합니다.
* 두번째 올리신 소스에서는 sort 하나로 구현한 것이 정상적인 것인지 모르겠습니다. 보통은
inline bool compare(string& a, string& b) {
if (a.size() < b.size()) return true;
else if (a.size() > b.size()) return false;
else return a < b;
}
같이 비교함수를 만들고
while (left <= right) {
while (compare(arr[left], pivot)) left++;
while (compare(pivot, arr[right])) right--;
if (left <= right) {
swap(arr[left], arr[right]);
left++;
right--;
}
} quicksort(i, right); quicksort(left, j);
같이 사용합니다.
* string를 직접 복사하는 것이 아닌 방법은 index를 이용하는 방법인데, 최신 c++에서는 작성하신데로 swap 을 쓰면 동일한 연산량이 될 수도 있습니다.
index를 사용하는 방법은... 먼저 index[i] = i 로 미리 초기화하고,
비교는 arr[idx[left]], arr[idx[right]] 와 같이 하고 값을 바꿀 때는 idx[left], idx[right] 만 바꾸고...
출력할때는 다시 arr[idx[i]] 로 하는 방법입니다.
실제 문자열을 옮기는 것이 아니라 문자열의 위치만을 소팅하는데.. 실제 비교는 문자열로 하는 개념입니다.
int idx[20000]; ... int main() { ... for (int i = 0;i < num;i++) { cin >> arr[i]; idx[i] = i; } ... cout << arr[idx[0]]; for (int i = 1;i < num;i++) { if (arr[idx[i]] != arr[idx[i - 1]]) {//같은 것 제외 cout << '\n' << arr[idx[i]]; } } } void quicksort(int i, int j) { ... string pivot = arr[idx[(i + j) / 2]]; ... while (left <= right) { while (compare(arr[idx[left]], pivot)) left++; while (compare(pivot, arr[idx[right]])) right--; if (left <= right) { swap(idx[left], idx[right]); left++; right--; } } .... }
이런 식입니다.
정답 맞추고 나시면
https://www.acmicpc.net/source...
소스를 참고하세요.
우선 계속 도와주셔서 감사합니다!! 제가 일이 있어서 이제서야 읽어보고 댓글을 올리네요.
댓글을 작성하려면 로그인해야 합니다.
dlwngjs429 2년 전
예제도 잘 출력되고 다른 것도 되는 것 같은데 시간 초과가 나옵니다.
해결 방법이 있을까요?