1

リンクされたハッシュマップがあり、2 つのランダムな値の間で並べ替え (値のキーを変更) する必要があります

例 :

キー 1 値 123 キー 2 値 456 キー 3 値 789

2 つの値をランダムに並べ替えた後

キー 1 の値 123 キー 2 の値 789 キー 3 の値 456

ここでは、キー 2 とキー 3 の間で値を並べ替えました

ありがとうございました;

私のマップのコードのサンプル:

    Map map = new LinkedHashMap();
        map =myMap.getLinkedHashMap();

       Set key = map.keySet();

   for(Iterator it = cles.iterator(); it.hasNext();)
    {
        Integer cle =  it.next(); 
        ArrayList values = (ArrayList)map.get(cle);//an arrayList of integers

        int i = 0;
        while(i < values.size())
        {
            //i donno what to do here
            i++;
        }
    }
4

3 に答える 3

2

まず、ジェネリック コレクションを使用する必要があります。

Map<Integer, List<Integer>> map = new LinkedHashMap<Integer, List<Integer>>();

これは宿題のように見えるので、完全な解決策ではなく、前進するのに役立つヒントを提供しようとしています. StackOverflow は宿題を書いてくれるわけではありません :-)

交換するには、2 つの要素のキーが必要です。それができたら、指定されたキーに対応する値を取得し、2 つのキー間でそれらを交換するだけです。次に、ランダムキー生成を追加します-@Eyalの一般的なソリューションを改善します:

  class MapSwapper1 {
    private static Random rnd = new Random();
    private static K[] nullArray = new K[0];

    public static <K,V> void swapTwoRandomValues(Map<K,V> map){
      if (map.size() <= 1)
        throw new IllegalArgumentException("Not enough items");

      //Choose 2 random positions pos1<pos2
      int pos1 = 0, pos2 = 0;
      while (pos1 == pos2) {
        pos1 = rnd.nextInt(map.size());
        pos2 = rnd.nextInt(map.size());
      }
      // Get the keys into an indexable array
      K[] keys = map.keySet().toArray(nullArray);

      swap(map, keys[pos1], keys[pos2]);
    }

    private static void <K,V> swap(Map<K, V> map, K key1, K key2) {
      V tmp = map.get(key1);
      map.put(key1, map.get(key2));
      map.put(key2, tmp);
    }
  }

この解決策は、そのままでも彼よりも速いかもしれないと思います。ただし、マップを変更せずに同じマップ内で値を何度もスワップする場合 (つまり、マップでキーが追加、削除、または変更されていない場合)、keys後続のスワップ呼び出し間で配列を再利用することにより、ソリューションをさらに最適化できます。

  class MapSwapper2<K, V> {
    private Random rnd = new Random();
    private Map<K,V> map;
    private K[] keys;

    public MapSwapper2(Map<K, V> map) {
      resetKeys();
      this.map = map;
    }

    public void resetKeys() {
      if (map.size() <= 1)
        throw new IllegalArgumentException("Not enough items");
      keys = map.keySet().toArray(new K[0]);
    }

    public void swapTwoRandomValues() {
      if (map.size() != keys.length)
        resetKeys();

      //Choose 2 random positions pos1<pos2
      int pos1 = 0, pos2 = 0;
      while (pos1 == pos2) {
        pos1 = rnd.nextInt(map.size());
        pos2 = rnd.nextInt(map.size());
      }
      swap(map, keys[pos1], keys[pos2]);
    }

    private void swap(K key1, K key2) {
      V tmp = map.get(key1);
      map.put(key1, map.get(key2));
      map.put(key2, tmp);
    }
  }

ご覧のとおり、MapSwapper2オブジェクトは特定のマップ インスタンスに関連付けられており、その要素は繰り返し交換できます。マップ キーが変更された場合は、このresetKeysメソッドを呼び出す必要があります。スワッパーは、マップのサイズが変更されたかどうかを検出できますが、たとえば、キーが削除されて別のキーが追加された場合は検出できません。

于 2010-05-07T22:09:37.830 に答える
1

数人がすでに何かを入力していることに気付きましたが、これはかなり完全です。これは最も効率的なコードではありませんが、途中で役立ち、値をマップに戻すことができます。

    Map<Integer, Integer> map = new LinkedHashMap<Integer, Integer>();
    map.put(1, 123);
    map.put(2, 456);
    map.put(3, 789);

    for (Entry<Integer, Integer> entry : map.entrySet())
        System.out.println("old key: " + entry.getKey() + " and value: " + entry.getValue());

    List<Integer> values = new ArrayList<Integer>(map.values());
    Collections.shuffle(values);

    int i = 0;
    for (Entry<Integer, Integer> entry : map.entrySet())
    {
        map.put(entry.getKey(), values.get(i));
        i++;
    }

    for (Entry<Integer, Integer> entry : map.entrySet())
        System.out.println("new key: " + entry.getKey() + " and value: " + entry.getValue());
于 2010-05-07T22:28:21.660 に答える
1

これは宿題ではないので、これが私の解決策です。スワッピング自体は効率的ですが、2 つのアイテムのランダム サンプリングは改善できます :)

private static Random rnd = new Random();
...
public static <K,V> void swapTwoRandomValues(Map<K,V> map){
    if (map.size() <= 1)
        throw new IllegalArgumentException("Not enough items");

    //Choose 2 random positions pos1<pos2
    int pos1 = 0, pos2 = 0;
    while (pos1 == pos2){
        pos1 = rnd.nextInt(map.size());
        pos2 = rnd.nextInt(map.size());
    }       
    if (pos1 > pos2){
        int aux = pos1;
        pos1 = pos2;
        pos2 = aux;
    }

    //Fetch the entries
    Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();
    Map.Entry<K, V> entry1 = null;
    for(int i=0;i <= pos1;i++)
        entry1 = it.next();
    Map.Entry<K, V> entry2 = null;
    for(int i = pos1;i < pos2;i++)
        entry2 = it.next();

    //Swap values
    V tmpValue = entry1.getValue();
    entry1.setValue(entry2.getValue());
    entry2.setValue(tmpValue);
}
于 2010-05-07T22:23:03.323 に答える