如何改组键值对? [英] how to shuffle key-value pairs?

查看:80
本文介绍了如何改组键值对?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组值,需要时需要重新整理. 我不知道哪种变量类型最适合我.数据实际上是基于键值结构的.

I have a set of values which need to be shuffled when needed. I don't know which variable type is best for me. Data is actually based on key-value structure.Like;

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

等等.我想做的是根据我不知道的算法来更改键值对,但是需要像这样对它们进行改组,但是改组不需要随机,因此我可以在需要时还原数据.

and like that. What I want to do is to change the key-value pairs according to I don't know yet, some algorithm.But they need to be shuffled like this, but shuffling need to be not random, so I can revert data when I need.

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

我真的不知道我应该如何解决.我应该使用HashTable之类的东西,如何动态地对其进行随机播放? 感谢您的帮助

I don't really know how my approach should be to the solution. Should I use HashTable or something, and how can I shuffle them dynamically? Any help is appreciated

推荐答案

另一种随机调整键值映射的方法:

Another way for shuffling the key-value mappings randomly:

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());
    }
}



如果您不想更改原始地图(因为以后需要它),则可以创建一个新的地图:

If you don't want to change the original map (since you need it afterwards), you can create a new one instead:

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;
}

您真的不希望一个看起来很随机的混音可以还原(很快就会变得复杂),而只是保留原始地图即可.如果这不合适,则需要更好地描述您的问题.

You do not really want a seemingly-randomly mixing which can be reverted (which quickly gets complicated), but simply retain your original map. If this does not fit, you need to describe your problem better.

好的,您想使用秘密密钥加密映射,提供另一个映射,然后再次对其解密.显然,随机改组对此无济于事,甚至伪随机也无济于事,因为它没有提供可靠的改组方法.在基本情况下,您的键将是我们映射键之间的可逆映射.

Okay, you want to encrypt the mapping by using a secret key, giving another mapping, and then decrypt it again. Obviously random shuffling does not help here, and even pseudorandom is no good, since it gives no reliable way to reshuffle. In the basic case, your key would be a invertible map between the keys of our mapping.

public static <K,V> Map<K,V> encryptMap(Map<K,V> plainMap, Map<K,K> key) {
    Map<K,V> cryptoMap = new HashMap<K,V>(plainMap.size());
    for(Map.Entry<K,V> entry : plainMap.entrySet()) {
       cryptoMap.put(key.get(entry.getKey()), entry.getValue());
    }
    return cryptoMap;
}

实际上,仅使用密钥的反向映射,解密的工作原理相同.

Decryption works the same, in fact, only using the reverse map of the key.

因此,当您拥有示例密钥{100, 200, 300}时,这些密钥的任何排列都是对我们的加密方案"有效的密钥. (只有6种可能,这不是很安全.)

So, when you have your example keys of {100, 200, 300}, any permutation of these keys is a valid key for our "encryption scheme". (There are only 6 possible ones, which is not very secure.)

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现在应该与原始地图相同.

The map decrypted now should be the same as the original map.

对于更大的键集,您可能想找到一个合适的方案 某些可输入键的键排列.

For bigger keysets you would want to find a scheme to get a suitable permutation of keys from some input-able key.

这篇关于如何改组键值对?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆