JMK no matter what

같은 코드 파이썬/C++/자바로 짜기

SRM468 Div2 맥주먹고 자바로 돌고 있었는데, 미디엄이 완전 string manipulation + 표준 자료구조 쓰기의 결정체쯤 되었다. 자바로 한참 걸려서 짜고, 파이썬으로 짜보고, 다시 C++ 로 짰음. 자바에서는 워낙 모르는 게 많다는걸 느낀다.. int 랑 char 랑 왔다갔다 할 수 있나? 이런것부터.. split() 과 substring() 의 동작.. 아 근데 TreeMap<String, ArrayList<String>> s = new TreeMap<String, ArrayList<String>>(); 이건 완전 초안습이라능.. 이거 언제 다 치고 있나여... 역시 이클립스라도 써야하나. ㅠㅠ

이 홈페이지에 오시는 자바 구루님들 도와주세요. (과연있을까-_-)

Java

lang:java
import static java.lang.Math.*;
import static java.math.BigInteger.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import java.math.*;
import java.util.*;

public class T9 {
    public String message(String[] part, String[] dict, String[] keystr) {
        char[] mapping = new char[256];
        for(int i = 1; i <= 9; ++i) {
            for(char c: part[i-1].toCharArray()) {
                mapping[(int)c] = Character.forDigit(i, 10);
            }
        }
        TreeMap<String, ArrayList<String> > words = new TreeMap<String, ArrayList<String> >();
        for(String w: dict) {
            char[] signature = new char[w.length()];
            for(int i = 0; i < w.length(); ++i) {
                signature[i] = mapping[(int)w.charAt(i)];
            }
            String s = new String(signature);
            if(!words.containsKey(s)) {
                words.put(s, new ArrayList<String>());
            }
            words.get(s).add(w);
        }
        for(Iterator it = words.values().iterator(); it.hasNext();) {
            ArrayList<String> w = (ArrayList<String>)(it.next());
            sort(w);
        }
        StringBuilder s = new StringBuilder();
        for(String strokes: keystr) s.append(strokes);
        StringBuilder res = new StringBuilder();
        String all = s.toString();
        String[] tokens = ("10" + all + "01").split("0");
        for(int i = 1; i < tokens.length-1; ++i) {
            String token = tokens[i];
            res.append(" ");
            first = false;
            if(token.length() == 0) continue;
            int d = 0;
            while(d < token.length() && Character.isDigit(token.charAt(d))) ++d;
            String signature = token.substring(0, d);
            String add = token.substring(d);
            System.out.println("[" + signature + "] " + add);
            int next = add.length();
            for(char c: add.toCharArray()) if(c == '*') next += 4;
            res.append(words.get(signature).get(next));
        }

        return res.substring(1);
    }
}

Python

lang:py
from collections import *
from itertools import *
from re import *
def T9(part, dictionary, keystr):
    m = {}
    for i, string in zip(count(1), part):
        for ch in string:
            m[ch] = str(i)
    w = defaultdict(lambda: [])
    for word in dictionary: w["".join(map(m.get, word))].append(word)
    for lst in w.values(): lst.sort()
    res = ""
    for tok in "".join(keystr).split("0"):
        res += " "
        if tok == "": continue
        digpart = match("^\d+", tok).group(0)
        rest = tok[len(digpart):]
        idx = len(rest) + 4 * rest.count("*")
        res += w[digpart][idx]
    return res[1:]

C++

lang:cpp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<string>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<fstream>
#include<cassert>
#include<numeric>
#include<set>
#include<map>
#include<queue>
#include<list>
#include<deque>
using namespace std;

#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(it,x) for(typeof(x.begin()) it=x.begin();it!=x.end();++it)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define CLEAR(x,with) memset(x,with,sizeof(x))
#define sz size()
typedef vector<int> VI;
typedef long long ll;

struct T9
{
    vector<string> split(string s, char delim) {
        s += delim;
        string tok;
        vector<string> ret;
        REP(i,s.sz) {
            if(s[i] == delim) {
                ret.pb(tok);
                tok = "";
            }
            else
                tok += s[i];
        }
        return ret;
    }
    string message(vector <string> part, vector <string> dict, vector <string> keystr)
    {
        char push[128];
        FOR(d,1,10) REP(i,part[d-1].sz) push[part[d-1][i]] = char(d+'0');
        map<string, vector<string> > w;
        REP(i,dict.sz) {
            string s;
            REP(j,dict[i].sz) s += push[dict[i][j]];
            w[s].pb(dict[i]);
        }
        w[""].pb("");
        FORE(it,w) sort(all(it->second));
        string all = accumulate(all(keystr), string());
        vector<string> toks = split(all, '0');
        string ret;
        REP(i,toks.sz) {
            string token = toks[i];
            int digits = 0;
            while(digits < token.sz && isdigit(token[digits])) ++digits;
            int idx = token.sz - digits;
            REP(j,token.sz) if(token[j] == '*') idx += 4;
            ret += " " + w[token.substr(0, digits)][idx];

        }
        return ret.substr(1);
    }
};

매크로만 무절제하게-_- 쓰면 C++ 의 표현성도 괜찮은 편인데.. 이건 뭐 코드가 완전 캐안습으로 더럽다는게 문제. -_-;

2010-04-26 15:13:59 | JM | /logs/topcoder/ | 7 Comments
LIBe
2010-04-29 03:31:27
무방위에서 나왔음여
JM
2010-05-01 00:24:45
@LIBe, 고맙다.. b.b
Toivoa
2010-05-01 08:16:01
public class Foo extends TreeMap< String, ArrayList< String > > {}
해놓고 Foo로 쓰면 됨.
mkseo
2010-05-02 12:54:21
http://www.google.com/codesearch/p?hl=en#YXcrkXezIpQ/trunk/src/com/google/common/collect/Maps.java&q=TreeMap%20package:http://google-collections%5C.googlecode%5C.com&sa=N&cd=2&ct=rc&t=1&l=155

여기코드처럼 작성해놓고

TreeMap<...> foo = Maps.newTreeMap();

이렇게 쓰죠.

그런데 하시는 알고리즘 컨테스트에서는 쓸 수 없겠네요.
이희승
2010-05-02 21:52:02
JDK 7 에서는 Map<String, List<String>> m = new TreeMap<>(); 면 된다던데
mkseo
2010-05-02 23:31:04
오 JDK7 기대되네요.
JM
2010-05-03 01:17:54
@Toivoa, 적절한 팁이로세...
@mkseo, 아... 죽이네영. ㅠㅠ 느끼는데, 언어도 그렇고 툴셋도 그렇고, 자바는 '대충 짜고 버릴' 작은 프로그램 짜는데는 별로 신경을 안쓴거 같아요. ㅋㅋ
@희승옹, 오 들어본 바 있습니다. 올해안엔 나오겠죠?

Leave a comment

春來不似春

About

Eventstream

Pages

Guestbook

Search

Site Admin

Recent Comments