728x90
programmers.co.kr/learn/courses/30/lessons/17686
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cctype>
using namespace std;
string findhead(string s){
string head ="";
for(int i=0; i<s.size(); i++){
if(s[i]>='0'&&s[i]<='9'){
break;
}
head+=s[i];
}
transform(head.begin(), head.end(), head.begin(), ::tolower); //string -> 모두 소문자로 나타내기
return head;
}
int findnum(string s){
string num="";
for(int i=0; i<s.size(); i++){
if(s[i]>='0'&&s[i]<='9'){
num+=s[i];
}
else {if(num.size()>0){break;}}
}
return stoi(num);
}
bool scompare(string a, string b){
string sa,sb;
sa = findhead(a);
sb = findhead(b);
return sa.compare(sb)<0; //string 사전순 검사
}
bool ncompare(string a, string b){
return findnum(a)<findnum(b);
}
vector<string> solution(vector<string> files) {
vector<string> answer;
stable_sort(files.begin(),files.end(),ncompare); // 값이 같을 때 기존 순서를 그대로 둔다.
stable_sort(files.begin(),files.end(),scompare);
answer = files;
return answer;
}
어떤 알고리즘 왜 그 알고리즘을 썼는지?
- 정렬을 이용해서 풀었다. 우선순위가 낮은 숫자 순으로 정렬하고 그다음에 앞에 head의 사전순으로 정렬을 했다.
새로 알게 된 부분
- stable_sort -> 같은 값일 때 기존 순서를 그대로 두도록 정렬한다.
- sa.compare(sb) <0 sa가 사전순으로 더 높을 때, sa.compare(sb)>0 sa가 사전순으로 더 낮을 때
- <cctype> 헤더에 tolower라고 하는 char 형의 대문자를 소문자로 바꿔주는 기능을 하는 것이 있다.
- std::transform(head.begin(),head.end(),head.begin(), ::tolower) -> string을 모두 소문자로 나타낼 수 있다.
<JAVA>
import java.util.*;
import java.util.regex.*;
class Solution {
public String[] solution(String[] files) {
String[] answer = {};
// Arrays.sort(files);
Arrays.sort(files,new Comparator<String>(){ //익명클래스는 comparator만 가능
@Override
public int compare(String s1, String s2){
String l1="";
String l2="";
int nnum1=0;
int nnum2=0;
int i =0;
int i2=0;
char c = s1.charAt(i);
while(!Character.isDigit(c)){
l1+=c;
i++;
if(i==s1.length()){break;} } // i범위 주의
c = s1.charAt(i);
}
c = s2.charAt(i2);
while(!Character.isDigit(c)){
l2+=c;
i2++;
if(i2==s2.length()){break;} } // i범위 주의
c = s2.charAt(i2);
}
l1 = l1.toLowerCase();
l2 = l2.toLowerCase();
int res = l1.compareTo(l2); //중요!! 사전순으로 정렬
if(res!=0){return res;} // l1과 l2 가 같지 않다면
/*여기부터 숫자부분을 구하고 오름차순 정렬*/
//c = s1.charAt(i);
String num1 ="";
boolean tg = false;
if(i<s1.length()){
c = s1.charAt(i);
while(Character.isDigit(c)){
tg = true;
num1+=c;
i++;
if(i==s1.length()){break;} // i범위 주의
c = s1.charAt(i);
}
if(tg){
nnum1 = Integer.parseInt(num1);
}
}
String num2 ="";
if(i2<s2.length()){
c = s2.charAt(i2);
tg = false;
while(Character.isDigit(c)){
tg = true;
num2+=c;
i2++;
if(i2==s2.length()){break;} } // i범위 주의
c = s2.charAt(i2);
}
if(tg){
nnum2 = Integer.parseInt(num2);
}
}
return nnum1-nnum2; //음수일떄 오름 차순
//if(res!=0){return res;}
}
});
answer = files;
return answer;
}
}
- 익명클래스 사용하는 법 익히기
- while문 사용하면서 i가 length를 넘어가는 일이 없는지 유심히 잘 보고 코딩해야겠다.