2011-03-13 10 views
2

필자는 필요할 때 셔플해야하는 값 집합을 가지고 있습니다. 어떤 변수 유형이 나에게 가장 적합한 지 알 수 없습니다. 데이터는 실제로 키 - 값 구조를 기반으로합니다.키 - 값 쌍을 셔플하는 방법은 무엇입니까?

100 "white" 
200 "black" 
300 "red" 

등. 내가 원하는 것은 키 - 값 쌍을 변경하는 것입니다. 알고리즘은 알지 못합니다. 그러나 이것들을 셔플해야합니다. 셔플은 이 아니기 때문에이되어야합니다. 그래서 데이터를 되돌릴 수 있습니다. 나는 필요하다.

100 "red" 
200 "white" 
300 "black" 

어떻게하면 내 접근 방식이 해결책이 될지 모르겠다. HashTable 등을 사용해야하나요? 어떻게 동적으로 섞을 수 있습니까? 어떤 도움이

+1

"믹싱 업"이란 무엇을 의미합니까? – marcog

+1

수행하려는 알고리즘을 모를 경우 어떤 데이터 구조가 가장 적합한 지 알 수 없습니다. –

+0

@Max 모든 키는 고유합니까? – Marnix

답변

0

을 감사합니다 나는 쌍을 당신이 에가는 방법을 정확히 확인 셔플 아니지만, 당신이 키를 기반으로 그들을 셔플해야하는 경우, 당신은 Map 사용할 수 있습니다

Map<String, String> map = new HashMap<String, String>(); 
map.put("100", "white"); 
map.put("200", "black"); 
map.put("300", "red"); 

// swap 100 with 200 
String temp = map.get("100"); 
map.put("100", map.get("200")); 
map.put("200", temp); 

을 또는 무작위로 쌍을 셔플해야하는 경우 larsmans가 제안한대로 (기본적으로 intString을 저장하는 클래스)을 만들어 배열에 저장할 수 있습니다. 그런 다음 Fisher-Yates shuffle의 약간 수정 된 버전을 사용할 수 있습니다. 이 줄의 어떤 것 :

// initialize list 
List<Pair<Integer, String>> values = new ArrayList<Pair<Integer, String>>(); 
values.add(new Pair<Integer, String>(100, "white")); 
values.add(new Pair<Integer, String>(200, "black")); 
values.add(new Pair<Integer, String>(300, "red")); 

// shuffle 
System.out.println(values); // e.g., [100 white, 200 black, 300 red] 
Random random = new Random(); 
for (int i = values.size() - 1; i > 1; i--) { 
    int j = random.nextInt(i + 1); 
    // swap values between i-th Pair and j-th Pair 
    Pair<Integer, String> iPair = values.get(i); // the iPair :-) 
    Pair<Integer, String> jPair = values.get(j); 
    String iString = iPair.getSecond(); 
    iPair.setSecond(jPair.getSecond()); 
    jPair.setSecond(iString); 
} 
System.out.println(values); // e.g., [100 red, 200 black, 300 white] 
+0

또는 단지 쌍의 배열. –

+0

답장을 보내 주셔서 감사합니다. 요점은 내가 필요할 때 역 셔플 작동이 필요하기 때문에 람직하게 셔플하고 싶지 않다는 것입니다. 그래서 되돌릴 수 있어야 해. 제안있어? – Max

0

tupples 목록이 필요합니다. 지도가 바로 그것입니다. 그러나 HashMap과 같은 표준에는 키와 값 간의 관계를 변경하는 기능이 없습니다.

나는 이것을 위해 내 자신의지도를 구현했을 것이라고 생각합니다. java.util.Map을 구현하는 클래스를 만들고 필요한 메소드를 구현하고 "믹싱"을위한 다른 메소드를 작성하십시오.

모든 항목은 실제로 터프 트 목록에 필요한 기능에 따라 다릅니다. 색상을 매우 빠르게 찾아야합니까? 동일한 번호의 터 플플이 여러 개있을 수 있습니까?

+0

답변 해 주셔서 감사합니다. 속도는별로 중요하지 않습니다. 그리고 두 번째 질문은 안된다. – Max

4

무작위 키와 ​​값의 매핑을 셔플을위한 또 다른 방법 :

public static <K,V> void shuffleMap(Map<K,V> map) { 
    List<V> valueList = new ArrayList<V>(map.values()); 
    Collections.shuffle(valueList); 
    Iterator<V> valueIt = valueList.iterator(); 
    for(Map.Entry<K,V> e : map.entrySet()) { 
     e.setValue(valueIt.next()); 
    } 
} 

편집 :

당신이 (당신이 나중에 그것을 필요로하기 때문에) 원래 맵을 변경하지 않으려면

, 당신은 정말 seemingl을 원하지 않는

public static <K,V> Map<K,V> shuffleMap(Map<K,V> map) { 
    List<V> valueList = new ArrayList<V>(map.values()); 
    Collections.shuffle(valueList); 
    Iterator<V> valueIt = valueList.iterator(); 
    Map<K,V> newMap = new HashMap<K,V>(map.size()); 
    for(K key : map.keySet()) { 
     newMap.put(key, valueIt.next()); 
    } 
    return newMap; 
} 

: 대신 새로 만들 수 있습니다 y- 무작위로 섞어서 되돌릴 수 있습니다. (바로 복잡 해짐)하지만 원본지도 만 유지하면됩니다. 이것이 맞지 않으면 문제를 더 잘 설명해야합니다.


좋습니다. 다른 매핑을 제공하고 다시 암호 해독하여 비밀 키를 사용하여 매핑을 암호화하려고합니다. 분명히 랜덤 셔플 링은 여기서 도움이되지 않으며 의사 랜덤 화도 신뢰할 수있는 방법을 제공하지 않기 때문에 좋지 않습니다. 기본 경우에, 당신의 키는 맵핑의 키 사이의 역전력 맵이 될 것입니다.

암호 해독은 실제로 키의 역방향 맵을 사용하여 동일하게 작동합니다.

예제 키가 {100, 200, 300} 인 경우 이러한 키의 순열은 "암호화 체계"의 유효한 키입니다. 는 (매우 안전하지 만 6 가능한 사람이 있습니다.)

Map sampleKey = new HashMap<Integer, Integer>(); 
sampleKey.put(100, 200); 
sampleKey.put(200, 300); 
sampleKey.put(300, 100); 

Map sampleUnKey = new HashMap<Integer, Integer>(); 
for(Map.Entry<Integer, Integer> e : sampleKey) { 
    sampleUnKey.put(e.getValue(), e.getKey()); 
} 

Map<Integer, String> data = new HashMap<Integer, String>(); 
data.put(100, "white"); 
data.put(200, "black"); 
data.put(300, "red"); 

System.out.println(data); 

Map<Integer, String> encrypted = encryptMap(data, sampleKey); 

System.out.println(encrypted); 

Map<Integer, String> decrypted = encryptMap(data, sampleUnKey); 

System.out.println(decrypted); 

지도 decrypted 이제 원래의 맵과 동일해야합니다.

더 큰 키 집합의 경우 입력 가능한 키에서 키의 순열을 얻는 방법을 찾고 싶을 것입니다.

+0

답장을 보내 주셔서 감사합니다. 요점은 내가 필요할 때 역 셔플 작동이 필요하기 때문에 람직하게 셔플하고 싶지 않다는 것입니다. 그래서 되돌릴 수 있어야 해. 제안있어? – Max

+0

분명히 예를 들어 보더라도 분명히 당신이 원하는 것이 무엇인지 분명하지 않았습니다. 단순히 새로운 섞인지도를 만드는 것 (그리고 오래된지도를 어딘가에 유지하는 것)으로 충분합니까? 그렇지 않은 경우 요구 사항을보다 명확하게 설명하십시오. –

+0

셔플 된지도에서 이전 (원본)지도를 유지해야합니다. 암호화/암호 해독과 같은 생각이 듭니다. 지금은 더 명확한가요? – Max

관련 문제