একটি অ্যারের এলোমেলো পরিবর্তন


232

আমাকে এলোমেলোভাবে নিম্নলিখিত অ্যারে পরিবর্তন করতে হবে:

int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};

এটি করার কোনও কাজ আছে?


5
আপনি সংগ্রহে.সুফল (অ্যারেজ.এললিস্ট (অ্যারে)) সন্ধান করছেন এমন এসডিকে পদ্ধতি;
লুই হংক

2
@ লুই না, এটি কাজ করে না। এটি List<int[]>একটি এন্ট্রি সমন্বিত তৈরি করতে হবে । এটি ব্যবহার করার উপায়টির জন্য আমার উত্তর দেখুন Collections.shuffle()
ডানকান জোন্স

2
আসল প্রশ্নের কোনও উত্তর আসলেই নয়, তবে কমন্স-ম্যাথ 3 লাইব্রেরির ম্যাথআর্রেস.ফ্যাশলটি কাজটি করে।
Sandris

1
এটি উত্তরের বিষয়ে ওয়্যারেন্ট করার পক্ষে পর্যাপ্ত বিষয় নয়, তবে "গ্রাফিক্স রত্ন" বইয়ের একটি দুর্দান্ত নিবন্ধ মনে আছে যা ছদ্ম র্যান্ডম ক্রমে একটি অ্যারেরকে অনুসরণ করার কথা বলেছিল। আমার মনে যে বীটগুলি প্রথমে ডেটাটি স্থান পরিবর্তন করে। সি-বাস্তবায়নটি এখানে পাওয়া যাবে github.com/erich666/ গ্রাফিকস গেমস
লেনার্ট রোল্যান্ড

: এছাড়াও এই ঘনিষ্ঠভাবে সম্পর্কিত প্রশ্ন দেখতে পাবেন stackoverflow.com/questions/2450954/...
Pierz

উত্তর:


263

আদিম ধরণের অ্যারে পরিবর্তন করতে সংগ্রহগুলি ব্যবহার করা ওভারকিলের কিছুটা ...

এটা সহজ, ফাংশন নিজেকে বাস্তবায়ন উদাহরণস্বরূপ ব্যবহার যথেষ্ট ফিশার-ইয়েটস এলোমেলো :

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

class Test
{
  public static void main(String args[])
  {
    int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };

    shuffleArray(solutionArray);
    for (int i = 0; i < solutionArray.length; i++)
    {
      System.out.print(solutionArray[i] + " ");
    }
    System.out.println();
  }

  // Implementing Fisher–Yates shuffle
  static void shuffleArray(int[] ar)
  {
    // If running on Java 6 or older, use `new Random()` on RHS here
    Random rnd = ThreadLocalRandom.current();
    for (int i = ar.length - 1; i > 0; i--)
    {
      int index = rnd.nextInt(i + 1);
      // Simple swap
      int a = ar[index];
      ar[index] = ar[i];
      ar[i] = a;
    }
  }
}

26
অত্যন্ত তুচ্ছ নাইটপিক, তবে আপনি কেবল এর println()পরিবর্তে ব্যবহার করতে পারেন println("")। অভিপ্রায়টি আরও পরিষ্কার আমি মনে করি :)
কাউয়ান

55
কালেকশন.শ্যাফেল (অ্যারেজ.এললিস্ট (অ্যারে)) ব্যবহার করা আরও ভাল; তারপরে নিজের স্বর বদল করুন।
লুই হংক

21
@Louie Collections.shuffle(Arrays.asList(array))না কাজ, কারণ না Arrays.asList(array)আয় Collection<int[]>না Collection<Integer>হিসাবে আপনি চিন্তা।
অ্যাডাম স্টেলমাস্কিজিক

15
@ ইজহুমা কারণ আপনার যদি সাজানোর জন্য কয়েক হাজার বা মিলিয়ন আদিম মানের একটি অ্যারে থাকে তবে প্রত্যেককে কেবল একটি বাছাই করতে কোনও বস্তুতে মোড়ানো কিছুটা ব্যয়বহুল, স্মৃতিতে এবং সিপিইউ উভয়ই।
ফিলিহো

14
এই না ফিশার-ইয়েটস এলোমেলো। একে বলা হয় ডার্সটেনফেল্ড সাফেল । আসল ফিশার-ইয়েটস বদল O (n O 2) সময়ে চলে যা অত্যন্ত ধীর।
পেসারিয়ার

164

এখানে একটি ব্যবহার করে একটি সহজ উপায় ArrayList:

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);

1
আপনি সহজেই করতে পারেনCollectons.shuffle(Arrays.asList(solutionArray));
ফাইন্ডআউটস্ল্যাশ এখন

টিমমোস অ্যারে.এএসলিস্টটি মূল অ্যারের চারপাশে মোড় নেয় এবং এইভাবে এটি পরিবর্তন করে আসল অ্যারেটিকে সংশোধন করে। এজন্য আপনি যুক্ত বা সরাতে পারবেন না, কারণ অ্যারেগুলি নির্দিষ্ট আকারের।
নন্দ

@ এবং নিশ্চিত হন না যে আমি কী ভাবছিলাম, তবে উত্স কোডটি দেখে সত্যিই অ্যারেএস.এললিস্ট পদ্ধতিটি প্রদত্ত অ্যারে দ্বারা সমর্থিত একটি অ্যারেলিস্ট তৈরি করে। এটা ইশারা জন্য ধন্যবাদ। আমার পূর্ববর্তী মন্তব্য মুছে ফেলা হয়েছে (এটি সম্পাদনা করতে পারেনি)।
টিমমোস

100

এখানে একটি কার্যকরী এবং দক্ষ ফিশার – ইয়েটস এ্যারে ফাংশন বদলানো হয়েছে:

private static void shuffleArray(int[] array)
{
    int index;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        if (index != i)
        {
            array[index] ^= array[i];
            array[i] ^= array[index];
            array[index] ^= array[i];
        }
    }
}

অথবা

private static void shuffleArray(int[] array)
{
    int index, temp;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        temp = array[index];
        array[index] = array[i];
        array[i] = temp;
    }
}

1
ভোট দিয়েছি কারণ আমার এমন একটি সমাধানের প্রয়োজন ছিল যার সংকলন তৈরির উচ্চ ওভারহেড ছিল না
mwk

2
দ্বিতীয়টি বাস্তবায়নের নিজস্ব সূচকের সাথে অদলবদলের সম্ভাবনা কি নেই? random.nextInt(int bound)একচেটিয়া কিন্তু i + 1যুক্তি হিসাবে এটি প্রদান অনুমতি দেয় indexএবং iসম্ভাব্য একই হতে পারে।
বিএমসেটি 148

21
@ বিএমসেন্তি ১৪8 এলোমেলো ক্রমক্রমে কোনও উপাদান নিজেই অদলবদলযোগ্য। এটি না বুঝে এনিগমা দুর্বল হয়ে পড়ে এবং অ্যালান টুরিংকে এটি ক্র্যাক করতে সক্ষম করে helped en.wikedia.org/wiki/…
এলেন স্পারটাস

4
xorকৌতুক CPU- র রেজিস্টার সোয়াপিং যখন CPU- র কোন swap 'র নির্দেশ রয়েছে এবং কোন বিনামূল্যে রেজিস্টার হয় জন্য মহান, কিন্তু একটি লুপ ভিতরে অ্যারে উপাদানের সোয়াপিং জন্য, আমি কোন সুবিধার দেখতে না। অস্থায়ী স্থানীয় ভেরিয়েবলগুলির জন্য এগুলি লুপের বাইরে ঘোষণা করার কোনও কারণ নেই।
হলগার

1
tempলুপের বাইরে ভেরিয়েবলটি ঘোষণা করতে এটি আরও দক্ষ efficient XORকৌতুক একটি ব্যবহার তুলনায় দ্রুততর হওয়া উচিত tempপরিবর্তনশীল কিন্তু একমাত্র উপায় নিশ্চিত এটি একটি মাত্রাবিশিষ্ট পরীক্ষা সম্পাদন করতে হবে।
ড্যান ব্রে

25

সংগ্রহ শ্রেণিতে বদলে যাওয়ার জন্য একটি কার্যকর পদ্ধতি রয়েছে, যা অনুলিপি করা যায়, যাতে এটির উপর নির্ভর না করে:

/**
 * Usage:
 *    int[] array = {1, 2, 3};
 *    Util.shuffle(array);
 */
public class Util {

    private static Random random;

    /**
     * Code from method java.util.Collections.shuffle();
     */
    public static void shuffle(int[] array) {
        if (random == null) random = new Random();
        int count = array.length;
        for (int i = count; i > 1; i--) {
            swap(array, i - 1, random.nextInt(i));
        }
    }

    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

এটা নির্ভর করে না ? আমি এটির উপর নির্ভর করতে পছন্দ করতাম, যদি কেবল এটি সম্ভব হত।
shmosel

@ শ্মোসেল এর পরে নির্দ্বিধায় এটি ব্যবহার করুন। নিশ্চিত হয়ে নিন যে আপনি প্রয়োজনীয় বর্গটি আমদানি করেছেন এবং আপনি অ্যারেটিকে একটি তালিকায় রূপান্তর করেছেন Arrays.asList। ফলাফলের তালিকাটি আপনাকে একটি অ্যারেতেও রূপান্তর করতে হবে
কিটকাট

আপনি Arrays.asList()কোনও প্রাথমিক অ্যারে ব্যবহার করতে পারবেন না । এবং আপনাকে এটি আবার রূপান্তর করতে হবে না কারণ এটি কেবল একটি মোড়ক।
shmosel

13

তাকান Collectionsবর্গ, বিশেষভাবে shuffle(...)


8
আপনি কীভাবে অ্যান্ড্রয়েডে এই সংগ্রহ ক্লাসটি ব্যবহার করবেন? এটি ব্যবহারের জন্য আপনাকে একটি বিশেষ আমদানি করতে হবে (সিআরটিএল শিফট ও কাজ করে না)?
হুবার্ট

@ হুবার্ট এটি প্যাকেজের অংশ হওয়া উচিত java.util। এটি v1.2 থেকে স্ট্যান্ডার্ড লাইব্রেরির অংশ।
মৌগানরা

3
আপনার উত্তরটি আরও স্ব-র অন্তর্ভুক্ত করার জন্য, এতে উদাহরণ কোড থাকা উচিত। আইই:import java.util.Collections; shuffle(solutionArray);
স্টিভোসিয়াক

10

Collections.shuffleপদ্ধতির সাহায্যে এখানে একটি সম্পূর্ণ সমাধান :

public static void shuffleArray(int[] array) {
  List<Integer> list = new ArrayList<>();
  for (int i : array) {
    list.add(i);
  }

  Collections.shuffle(list);

  for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
  }    
}

নোট করুন যে জাভা এর মধ্যে int[]এবং Integer[](এবং এভাবে int[]এবং List<Integer>) এর মধ্যে সহজেই অনুবাদ করতে অক্ষমতার কারণে ভুগছে ।


10

আপনার কাছে এখানে কয়েকটি বিকল্প রয়েছে। পরিবর্তনের বিষয়টি যখন আসে তখন একটি তালিকা অ্যারের থেকে কিছুটা আলাদা।

যেমন আপনি নীচে দেখতে পাচ্ছেন, একটি অ্যারের তালিকার চেয়ে দ্রুত এবং আদিম অ্যারে কোনও বস্তুর অ্যারের চেয়ে দ্রুত।

নমুনা সময়কাল

List<Integer> Shuffle: 43133ns
    Integer[] Shuffle: 31884ns
        int[] Shuffle: 25377ns

নীচে, এলোমেলো তিনটি পৃথক বাস্তবায়ন। আপনি যদি কেবল কোনও সংগ্রহের সাথে ডিল করছেন তবে আপনার কেবল কালেকশন.শ্যাফল ব্যবহার করা উচিত। আপনার অ্যারেটিকে কেবল তা বাছাই করার জন্য কোনও সংগ্রহের মধ্যে মোড়ানোর দরকার নেই। নীচের পদ্ধতিগুলি প্রয়োগ করা খুব সহজ।

শাফল ইউটিল ক্লাস

import java.lang.reflect.Array;
import java.util.*;

public class ShuffleUtil<T> {
    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final int SHUFFLE_THRESHOLD = 5;

    private static Random rand;

মূল পদ্ধতি

    public static void main(String[] args) {
        List<Integer> list = null;
        Integer[] arr = null;
        int[] iarr = null;

        long start = 0;
        int cycles = 1000;
        int n = 1000;

        // Shuffle List<Integer>
        start = System.nanoTime();
        list = range(n);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(list);
        }
        System.out.printf("%22s: %dns%n", "List<Integer> Shuffle", (System.nanoTime() - start) / cycles);

        // Shuffle Integer[]
        start = System.nanoTime();
        arr = toArray(list);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(arr);
        }
        System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles);

        // Shuffle int[]
        start = System.nanoTime();
        iarr = toPrimitive(arr);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(iarr);
        }
        System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles);
    }

একটি জেনেরিক তালিকা পরিবর্তন করা

    // ================================================================
    // Shuffle List<T> (java.lang.Collections)
    // ================================================================
    @SuppressWarnings("unchecked")
    public static <T> void shuffle(List<T> list) {
        if (rand == null) {
            rand = new Random();
        }
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i = size; i > 1; i--) {
                swap(list, i - 1, rand.nextInt(i));
            }
        } else {
            Object arr[] = list.toArray();

            for (int i = size; i > 1; i--) {
                swap(arr, i - 1, rand.nextInt(i));
            }

            ListIterator<T> it = list.listIterator();
            int i = 0;

            while (it.hasNext()) {
                it.next();
                it.set((T) arr[i++]);
            }
        }
    }

    public static <T> void swap(List<T> list, int i, int j) {
        final List<T> l = list;
        l.set(i, l.set(j, l.get(i)));
    }

    public static <T> List<T> shuffled(List<T> list) {
        List<T> copy = copyList(list);
        shuffle(copy);
        return copy;
    }

একটি জেনেরিক অ্যারে বদলানো

    // ================================================================
    // Shuffle T[]
    // ================================================================
    public static <T> void shuffle(T[] arr) {
        if (rand == null) {
            rand = new Random();
        }

        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, i, rand.nextInt(i + 1));
        }
    }

    public static <T> void swap(T[] arr, int i, int j) {
        T tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static <T> T[] shuffled(T[] arr) {
        T[] copy = Arrays.copyOf(arr, arr.length);
        shuffle(copy);
        return copy;
    }

একটি আদিম অ্যারে বদলানো

    // ================================================================
    // Shuffle int[]
    // ================================================================
    public static <T> void shuffle(int[] arr) {
        if (rand == null) {
            rand = new Random();
        }

        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, i, rand.nextInt(i + 1));
        }
    }

    public static <T> void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static int[] shuffled(int[] arr) {
        int[] copy = Arrays.copyOf(arr, arr.length);
        shuffle(copy);
        return copy;
    }

ইউটিলিটি পদ্ধতি

অ্যারেগুলিকে তালিকাগুলিতে এবং বিপরীতে রূপান্তর করতে সাধারণ ইউটিলিটি পদ্ধতি।

    // ================================================================
    // Utility methods
    // ================================================================
    protected static <T> List<T> copyList(List<T> list) {
        List<T> copy = new ArrayList<T>(list.size());
        for (T item : list) {
            copy.add(item);
        }
        return copy;
    }

    protected static int[] toPrimitive(Integer[] array) {
        if (array == null) {
            return null;
        } else if (array.length == 0) {
            return EMPTY_INT_ARRAY;
        }
        final int[] result = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            result[i] = array[i].intValue();
        }
        return result;
    }

    protected static Integer[] toArray(List<Integer> list) {
        return toArray(list, Integer.class);
    }

    protected static <T> T[] toArray(List<T> list, Class<T> clazz) {
        @SuppressWarnings("unchecked")
        final T[] arr = list.toArray((T[]) Array.newInstance(clazz, list.size()));
        return arr;
    }

রেঞ্জ ক্লাস

পাইথনের rangeফাংশনের মতো মানের একটি ব্যাপ্তি তৈরি করে।

    // ================================================================
    // Range class for generating a range of values.
    // ================================================================
    protected static List<Integer> range(int n) {
        return toList(new Range(n), new ArrayList<Integer>());
    }

    protected static <T> List<T> toList(Iterable<T> iterable) {
        return toList(iterable, new ArrayList<T>());
    }

    protected static <T> List<T> toList(Iterable<T> iterable, List<T> destination) {
        addAll(destination, iterable.iterator());

        return destination;
    }

    protected static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
        while (iterator.hasNext()) {
            collection.add(iterator.next());
        }
    }

    private static class Range implements Iterable<Integer> {
        private int start;
        private int stop;
        private int step;

        private Range(int n) {
            this(0, n, 1);
        }

        private Range(int start, int stop) {
            this(start, stop, 1);
        }

        private Range(int start, int stop, int step) {
            this.start = start;
            this.stop = stop;
            this.step = step;
        }

        @Override
        public Iterator<Integer> iterator() {
            final int min = start;
            final int max = stop / step;

            return new Iterator<Integer>() {
                private int current = min;

                @Override
                public boolean hasNext() {
                    return current < max;
                }

                @Override
                public Integer next() {
                    if (hasNext()) {
                        return current++ * step;
                    } else {
                        throw new NoSuchElementException("Range reached the end");
                    }
                }

                @Override
                public void remove() {
                    throw new UnsupportedOperationException("Can't remove values from a Range");
                }
            };
        }
    }
}

1
আপনি একই জিনিসগুলির সময় নির্ধারণ করছেন না এবং আপনি প্রত্যেকে একবারে সময় নির্ধারণ করছেন (তারপরে তাদের অর্ডার গণনা করা হয় এবং আপনি রানটাইম অপ্টিমাইজেশন ভুলে যান)। আপনার কল করা উচিত range, toArrayএবং toPrimitiveকোনও সময় নির্ধারণের আগে, এবং লুপটি কোনও উপসংহারে পৌঁছাতে সক্ষম হতে হবে (সিউডো কোড: কয়েকবার করুন list তালিকা তৈরি করুন, আরার এবং আইআরআর; সময় বদলানো তালিকা; সময় বদলানো অ্যারে; সময় বদলানো আইআর})। আমার ফলাফল: 1 ম: list: 36017ns, arr: 28262ns, iarr: 23334ns। 100 তম: list: 18445ns, arr: 19995ns, iarr: 18657ns। এটি কেবল অন্তর্নিহিত দেখায় [] পূর্বনির্ধারিত (কোড অনুসারে) তবে তারা রানটাইম অপ্টিমাইজেশনের সাথে প্রায় সমান।
সাইমে

9

ব্যবহারের ArrayList<Integer>ফলে আপনি অনেক যুক্তি প্রয়োগ না করে এবং কম সময় ব্যয় না করে বদলির সমস্যা সমাধানে সহায়তা করতে পারেন। আমি যা পরামর্শ দিচ্ছি তা এখানে:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);

সম্ভবত পরেরটি নয় - কম সময় ব্যয় করা । প্রকৃতপক্ষে এটি অবশ্যই উপরের আদিম প্রয়োগগুলির চেয়ে ধীর।
বোরিস স্পাইডার

1
কারও জন্য কোডটি অনুলিপি করার জন্য, "চক্রের জন্য" i = 1 দেখুন আপনার i = 0 দরকার
বরিস কার্লোফ


5

আপনি এখন জাভা 8 ব্যবহার করতে পারেন:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);

2
এই কোডটিতে জাভা 8-নির্দিষ্ট কিছুই নেই। এটি জাভা 2 সাল থেকে কাজ করে। ঠিক আছে, এটি কার্যকর হবে, একবার আপনি প্রথম ব্যবহার listএবং হঠাৎ উল্লেখ করার মধ্যে অসঙ্গতিটি ঠিক করেন cardsList। তবে যেহেতু আপনাকে অস্থায়ী তৈরি করা দরকার list, যা আপনি বাদ দিয়েছেন, তাই Collections.shuffle(Arrays.asList(arr));বেশ কয়েকবার এখানে দেখানো পদ্ধতির কোনও লাভ নেই। যা জাভা 2 থেকেও কাজ করে works
হোলার

3

অ্যারেগুলির জন্য এখানে জেনারিক্স সংস্করণ রয়েছে:

import java.util.Random;

public class Shuffle<T> {

    private final Random rnd;

    public Shuffle() {
        rnd = new Random();
    }

    /**
     * Fisher–Yates shuffle.
     */
    public void shuffle(T[] ar) {
        for (int i = ar.length - 1; i > 0; i--) {
            int index = rnd.nextInt(i + 1);
            T a = ar[index];
            ar[index] = ar[i];
            ar[i] = a;
        }
    }
}

অ্যারেলিস্ট মূলত কেবল একটি অ্যারে হিসাবে বিবেচনা করে সুস্পষ্ট অ্যারের পরিবর্তে অ্যারেলিস্টের সাথে কাজ করা এবং কালেকশন.শ্যাফল () ব্যবহার করার পরামর্শ দেওয়া যেতে পারে। পারফরম্যান্স পরীক্ষাগুলি, উপরের এবং সংগ্রহের মধ্যে কোনও উল্লেখযোগ্য পার্থক্য দেখাবেন না।

Shuffe<Integer>.shuffle(...) performance: 576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance: 629400 shuffles per second
MathArrays.shuffle(int[]) performance: 53062 shuffles per second

অ্যাপাচি কমন্স বাস্তবায়ন ম্যাথআরয়েস.ফ্যাশলটি ইনট [] এর মধ্যে সীমাবদ্ধ এবং এলোমেলো নম্বর জেনারেটর ব্যবহৃত হওয়ার কারণে পারফরম্যান্স পেনাল্টি হতে পারে।


1
দেখে মনে হচ্ছে আপনি পাস করতে পারেন new JDKRandomGenerator()থেকে MathArrays.shuffle। আমি ভাবছি কীভাবে এটি পারফরম্যান্সকে প্রভাবিত করে?
ব্র্যান্ডন

আসলে ... দেখে মনে হচ্ছে MathArrays#shuffleএর মূল লুপটিতে একটি বরাদ্দ রয়েছে:int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();। উদ্ভট।
ব্র্যান্ডন

3
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
  int index = rnd.nextInt(i + 1);
  // Simple swap
  int a = ar[index];
  ar[index] = ar[i];
  ar[i] = a;
}

যাইহোক, আমি লক্ষ্য করেছি যে এই কোডটি ar.length - 1বেশ কয়েকটি উপাদান ফেরত দেয় , সুতরাং আপনার অ্যারেতে যদি 5 টি উপাদান থাকে তবে নতুন শিফলেড অ্যারেটিতে 4 টি উপাদান থাকবে। এটি ঘটে কারণ লুপ বলে i>0। আপনি যদি এতে পরিবর্তন করেন তবে আপনি i>=0সমস্ত উপাদানকে বদলে দেবেন ।


কেবল একটি মাথা আপ, আপনি এটি আপনার প্রশ্নের মন্তব্য বিভাগে স্থানান্তর করতে চাইতে পারেন, কারণ এটি সম্ভবত এটির নিজস্ব উত্তর হিসাবে ছেড়ে গেলে এটি পতাকাঙ্কিত হবে।
জেসন ডি

1
এটি প্রশ্নের উত্তর বলে মনে হচ্ছে, সুতরাং আপনি @ জেসনডি
সুমুরাই 8

1
কোডটি সঠিক, মন্তব্যটি ভুল। আপনি যদি পরিবর্তিত i>0হন i>=0, আপনি 0নিজের সাথে উপাদান অদলবদল করে সময় নষ্ট করেন ।
jcsahnwaldt পুনরায় ইনস্টল করুন মনিকা

3

অ্যাপাচি কমন্স ম্যাথ 3.x (কেবলমাত্র [কেবলমাত্র অ্যারেগুলির জন্য) ব্যবহার করে একটি সমাধান এখানে দেওয়া হয়েছে:

MathArrays.shuffle(array);

http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle (int- [])

বিকল্পভাবে, অ্যাপাচি কমন্স ল্যাং 3.6 ArrayUtilsক্লাসে নতুন শ্যাফেল পদ্ধতি চালু করেছে (অবজেক্টস এবং যে কোনও আদিম ধরণের জন্য)।

ArrayUtils.shuffle(array);

http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-


3

আমি কিছু উত্তরে কিছু মিস তথ্য দেখেছি তাই আমি নতুন একটি যুক্ত করার সিদ্ধান্ত নিয়েছি।

জাভা সংগ্রহগুলি অ্যারে.এএসলিস্টে টি টাইপের ভের-আরগ লাগে (T ...)। আপনি যদি কোনও আদিম অ্যারে (ইন্ট অ্যারে) পাস করেন, তবে তালিকা তালিকাটি অনুমান করে এবং একটি তৈরি করেList<int[]> যা একটি উপাদান তালিকা (এক উপাদানটি আদিম অ্যারে)। যদি আপনি এই একটি উপাদান তালিকার পরিবর্তন করেন তবে এটি কোনও জিনিসই বদলাবে না।

সুতরাং, প্রথমে আপনাকে আদিম অ্যারেটিকে র্যাপার অবজেক্ট অ্যারেতে রূপান্তর করতে হবে। এর জন্য আপনি ArrayUtils.toObjectapache.commons.lang থেকে পদ্ধতিটি ব্যবহার করতে পারেন । তারপরে উত্পন্ন অ্যারেটিকে একটি তালিকাতে পাস করুন এবং এটি শেষ হবে।

  int[] intArr = {1,2,3};
  List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
  Collections.shuffle(integerList);
  //now! elements in integerList are shuffled!

3

এখানে তালিকা বদলের আরও একটি উপায়

public List<Integer> shuffleArray(List<Integer> a) {
List<Integer> b = new ArrayList<Integer>();
    while (a.size() != 0) {
        int arrayIndex = (int) (Math.random() * (a.size()));
        b.add(a.get(arrayIndex));
        a.remove(a.get(arrayIndex));
    }
    return b;
}

আসল তালিকা থেকে একটি এলোমেলো সংখ্যা বাছুন এবং এটি অন্য তালিকায় সংরক্ষণ করুন hen তারপরে নম্বরটি মূল তালিকা থেকে সরিয়ে দিন all সমস্ত তালিকা নতুন তালিকায় সরানো না হওয়া অবধি মূল তালিকার আকার এক থেকে কমতে থাকবে।


2

গ্রোভির জন্য একটি সহজ সমাধান:

solutionArray.sort{ new Random().nextInt() }

এটি অ্যারে তালিকার সমস্ত উপাদানকে এলোমেলোভাবে সাজবে যা সমস্ত উপাদানকে বদলে দেওয়ার কাঙ্ক্ষিত ফলাফলটি সংরক্ষণাগারভুক্ত করে।



1

আমি এই খুব জনপ্রিয় প্রশ্নটি সম্পর্কে বিবেচনা করছি কারণ কেউ কোনও সাফ-কপি সংস্করণ লিখেছেন না। স্টাইলের কাছ থেকে প্রচুর orrowণ নেওয়া হয়েছে Arrays.java, কারণ আজকাল কে জাভা প্রযুক্তি খাড়া করছে না ? জেনেরিক এবং intবাস্তবায়ন অন্তর্ভুক্ত।

   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   @SuppressWarnings("unchecked")
   public static <T> T[] shuffledCopy(T[] original) {
      int originalLength = original.length; // For exception priority compatibility.
      Random random = new Random();
      T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength);

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }


   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   public static int[] shuffledCopy(int[] original) {
      int originalLength = original.length;
      Random random = new Random();
      int[] result = new int[originalLength];

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }

1

এটি নথ শিফেল অ্যালগরিদম।

public class Knuth { 

    // this class should not be instantiated
    private Knuth() { }

    /**
     * Rearranges an array of objects in uniformly random order
     * (under the assumption that <tt>Math.random()</tt> generates independent
     * and uniformly distributed numbers between 0 and 1).
     * @param a the array to be shuffled
     */
    public static void shuffle(Object[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            // choose index uniformly in [i, n-1]
            int r = i + (int) (Math.random() * (n - i));
            Object swap = a[r];
            a[r] = a[i];
            a[i] = swap;
        }
    }

    /**
     * Reads in a sequence of strings from standard input, shuffles
     * them, and prints out the results.
     */
    public static void main(String[] args) {

        // read in the data
        String[] a = StdIn.readAllStrings();

        // shuffle the array
        Knuth.shuffle(a);

        // print results.
        for (int i = 0; i < a.length; i++)
            StdOut.println(a[i]);
    }
}

1

এছাড়াও অন্য উপায় আছে, এখনও পোস্ট না

//that way, send many object types diferentes
public anotherWayToReciveParameter(Object... objects)
{
    //ready with array
    final int length =objects.length;
    System.out.println(length);
    //for ready same list
    Arrays.asList(objects);
}

প্রসঙ্গ উপর নির্ভর করে যে আরও সহজ


1

একটি অ্যারেতে এই র্যান্ডম শফলিংয়ের জন্য সর্বাধিক সহজ সমাধান।

String location[] = {"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};
int index;
String temp;
Random random = new Random();
for(int i=1;i<location.length;i++)
{
    index = random.nextInt(i+1);
    temp = location[index];
    location[index] = location[i];
    location[i] = temp;
    System.out.println("Location Based On Random Values :"+location[i]);
}

1
  1. বক্স থেকে int[]থেকেInteger[]
  2. Arrays.asListপদ্ধতি সহ একটি তালিকায় একটি অ্যারে মোড়ানো
  3. Collections.shuffleপদ্ধতির সাথে সাফ করুন

    int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
    
    Integer[] boxed = Arrays.stream(solutionArray).boxed().toArray(Integer[]::new);
    Collections.shuffle(Arrays.asList(boxed));
    
    System.out.println(Arrays.toString(boxed));
    // [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6]

1

বদল করার সহজতম কোড:

import java.util.*;
public class ch {
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        ArrayList<Integer> l=new ArrayList<Integer>(10);
        for(int i=0;i<10;i++)
            l.add(sc.nextInt());
        Collections.shuffle(l);
        for(int j=0;j<10;j++)
            System.out.println(l.get(j));       
    }
}

1

র্যান্ডম ক্লাস ব্যবহার করা

  public static void randomizeArray(int[] arr) {

      Random rGenerator = new Random(); // Create an instance of the random class 
      for (int i =0; i< arr.length;i++ ) {
          //Swap the positions...

          int rPosition = rGenerator.nextInt(arr.length); // Generates an integer within the range (Any number from 0 - arr.length)
          int temp = arr[i]; // variable temp saves the value of the current array index;
          arr[i] = arr[rPosition];  // array at the current position (i) get the value of the random generated 
          arr[rPosition] = temp; // the array at the position of random generated gets the value of temp

      }

      for(int i = 0; i<arr.length; i++) {
          System.out.print(arr[i]); //Prints out the array
      } 

  }

0
public class ShuffleArray {
public static void shuffleArray(int[] a) {
    int n = a.length;
    Random random = new Random();
    random.nextInt();
    for (int i = 0; i < n; i++) {
        int change = i + random.nextInt(n - i);
        swap(a, i, change);
    }
}

private static void swap(int[] a, int i, int change) {
    int helper = a[i];
    a[i] = a[change];
    a[change] = helper;
}

public static void main(String[] args) {
    int[] a = new int[] { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
    shuffleArray(a);
    for (int i : a) {
        System.out.println(i);
    }
}
}

আপনার উত্তর সম্পর্কিত কিছু সম্পর্কিত বিবরণ যুক্ত করুন।
অঙ্কিত সুথার

0
import java.util.ArrayList;
import java.util.Random;
public class shuffle {
    public static void main(String[] args) {
        int a[] =  {1,2,3,4,5,6,7,8,9};
         ArrayList b = new ArrayList();
       int i=0,q=0;
       Random rand = new Random();

       while(a.length!=b.size())
       {
           int l = rand.nextInt(a.length);
//this is one option to that but has a flaw on 0
//           if(a[l] !=0)
//           {
//                b.add(a[l]);
//               a[l]=0;
//               
//           }
//           
// this works for every no. 
                if(!(b.contains(a[l])))
                {
                    b.add(a[l]);
                }



       }

//        for (int j = 0; j <b.size(); j++) {
//            System.out.println(b.get(j));
//            
//        }
System.out.println(b);
    }

}

0

অদলবদল ব্যবহার না করেই খ

        Random r = new Random();
    int n = solutionArray.length;
    List<Integer> arr =  Arrays.stream(solutionArray).boxed().collect(Collectors.toList());
    for (int i = 0; i < n-1; i++) {
        solutionArray[i] = arr.remove( r.nextInt(arr.size())); // randomize base on size
    }
    solutionArray[n-1] = arr.get(0);

0

সমাধানগুলির মধ্যে একটি হ'ল ক্রমটি ব্যবহার করে সমস্ত অনুমতিগুলি প্রাক-গণনা এবং অ্যারেলিস্টে সঞ্চিত হয়

জাভা 8 জাভা.ইটিল.র্যান্ডম ক্লাসে একটি নতুন পদ্ধতি, ইনটস () প্রবর্তন করে। Ints () পদ্ধতিটি সিউডোর্যান্ডম ইন মানগুলির সীমাহীন স্ট্রিমটি দেয়। সর্বনিম্ন এবং সর্বাধিক মান সরবরাহ করে আপনি একটি নির্দিষ্ট পরিসরের মধ্যে এলোমেলো সংখ্যা সীমাবদ্ধ করতে পারেন।

Random genRandom = new Random();
int num = genRandom.nextInt(arr.length);

এলোমেলো সংখ্যা তৈরির সহায়তায় আপনি লুপের মাধ্যমে পুনরাবৃত্তি করতে পারবেন এবং এলোমেলো নম্বর সহ বর্তমান সূচীটি দিয়ে অদলবদল করতে পারবেন .. এভাবেই আপনি ও (1) স্পেস জটিলতার সাথে একটি এলোমেলো সংখ্যা তৈরি করতে পারেন।


0

এলোমেলো সমাধান ছাড়াই:

   static void randomArrTimest(int[] some){
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < some.length; i++) {
            long indexToSwap = startTime%(i+1);
            long tmp = some[(int) indexToSwap];
            some[(int) indexToSwap] = some[i];
            some[i] = (int) tmp;
        }
        System.out.println(Arrays.toString(some));
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.