tutorial - জাভা java runtime environment




আমি কীভাবে জাভা পদ্ধতিতে অকেজো রিটার্ন এড়াব? (7)

আপনার রিটার্নের মান বাইরের লুপের ভেরিয়েবলের উপর ভিত্তি করে আপনি কেবল count < range করে বাহ্যিক লুপের শর্তটি পরিবর্তন করতে পারেন এবং তারপরে ফাংশনের শেষে এই শেষ মানটি (যা আপনি কেবল বাদ দিয়েছেন) ফিরে আসতে পারেন:

private static int oneRun(int range) {
    ...

    for (int count = 1; count < range; count++) {
        ...
    }
    return range;
}

এইভাবে আপনাকে এমন কোড প্রবর্তনের দরকার নেই যা কখনই পৌঁছাতে পারে না।

আমার এমন একটি পরিস্থিতি রয়েছে যেখানে তাত্ত্বিকভাবে লুপের for দু'জনে return স্টেটমেন্টটি পৌঁছে যাবে।

সংকলক একমত নয় এবং লুপের বাইরে একটি বিবরণী বিবৃতি প্রয়োজন requires আমি আমার বর্তমান বোধগম্যের বাইরে এই পদ্ধতিটি অনুকূলকরণের জন্য একটি মার্জিত উপায় জানতে চাই এবং আমার বিরতির বাস্তবায়নের কোনওটিই কাজ করছে বলে মনে হয় না।

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

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range; count++) { // Run until return.
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                return count;
            }
        }
    }
    return 0; // Never reached
}

আমি সম্মত হলাম যে যেখানে অপ্রাপ্য বক্তব্য আসে সেখানে একটি ব্যতিক্রম ছুঁড়ে ফেলা উচিত। কেবল একই পদ্ধতিটি আরও পাঠযোগ্য উপায়ে এটি কীভাবে করতে পারে তা কেবলমাত্র দেখতে চেয়েছিলেন (জাভা 8 টি স্ট্রিম প্রয়োজনীয়)।

private static int oneRun(int range) {
    int[] rInt = new int[range + 1];
    return IntStream
        .rangeClosed(0, range)
        .peek(i -> rInt[i] = generator.nextInt(range))
        .filter(i -> IntStream.range(0, i).anyMatch(j -> rInt[i] == rInt[j]))
        .findFirst()
        .orElseThrow(() -> new RuntimeException("Shouldn't be reached!"));
}

যদিও একটি জোর দেওয়া ভাল দ্রুত সমাধান solution সাধারণভাবে এই ধরণের সমস্যার অর্থ হল আপনার কোডটি খুব জটিল। আমি যখন আপনার কোডটি দেখছি, এটি স্পষ্টতই আপনি পূর্ববর্তী সংখ্যাগুলি ধরে রাখতে কোনও অ্যারে চান না। আপনি একটি Set চান:

Set<Integer> previous = new HashSet<Integer>();

int randomInt = generator.nextInt(range);
previous.add(randomInt);

for (int count = 1; count <= range; count++) {
    randomInt = generator.nextInt(range);
    if (previous.contains(randomInt)) {
       break;
    }

    previous.add(randomInt);
}

return previous.size();

এখন নোট করুন যে আমরা ফিরে যাচ্ছি তা আসলে সেটটির আকার। কোড জটিলতা চতুর্ভুজ থেকে লিনিয়ারে হ্রাস পেয়েছে এবং এটি অবিলম্বে আরও পঠনযোগ্য।

এখন আমরা বুঝতে পারি যে আমাদের সেই count দরকার নেই:

Set<Integer> previous = new HashSet<Integer>();

int randomInt = generator.nextInt(range);

while (!previous.contains(randomInt)) {          
    previous.add(randomInt);      
    randomInt = generator.nextInt(range);
}

return previous.size();

যে পদ্ধতিগুলির মধ্যে রিটার্নের বিবৃতি থাকে এবং সেগুলির ভিতরে একটি লুপ / ​​লুপ থাকে সেগুলির জন্য সর্বদা লুপের বাইরে ফিরতি বিবৃতি প্রয়োজন। এমনকি লুপের বাইরের এই বিবৃতিটি কখনই পৌঁছায় না। এই জাতীয় ক্ষেত্রে, অপ্রয়োজনীয় রিটার্নের বিবৃতি এড়াতে, আপনি পদ্ধতির শুরুতে বা संबंधित লুপের (গুলি) এর আগে ও বাইরে, সম্পর্কিত প্রকারের আপনার ক্ষেত্রে একটি পূর্ণসংখ্যার সংজ্ঞা দিতে পারেন। লুপের ভিতরে কাঙ্ক্ষিত ফলাফল পৌঁছে গেলে আপনি এই প্রাক-সংজ্ঞায়িত ভেরিয়েবলের জন্য সংশ্লিষ্ট মানটিকে স্বীকৃতি দিতে পারেন এবং এটি লুপের বাইরে রিটার্ন স্টেটমেন্টের জন্য ব্যবহার করতে পারেন।

যেহেতু আপনি চান আপনার পদ্ধতিটি প্রথম ফলাফলটি ফিরে আসে যখন rInt [i] rInt [গণনা] এর সমান হয়, কেবলমাত্র উপরে বর্ণিত ভেরিয়েবল প্রয়োগ করা যথেষ্ট নয় কারণ rInt [i] rInt [গণনা] এর সমান হলে পদ্ধতিটি শেষ ফলাফলটি ফিরে আসবে। একটি বিকল্প হ'ল দুটি "ব্রেক স্টেটমেন্ট" প্রয়োগ করা যা আমাদের যখন পছন্দসই ফলাফল দেয় তখন ডাকা হয়। সুতরাং, পদ্ধতিটি এরকম কিছু দেখবে:

private static int oneRun(int range) {

        int finalResult = 0; // the above-mentioned variable
        int[] rInt = new int[range + 1];
        rInt[0] = generator.nextInt(range);

        for (int count = 1; count <= range; count++) {
            rInt[count] = generator.nextInt(range);
            for (int i = 0; i < count; i++) {
                if (rInt[i] == rInt[count]) {
                    finalResult = count;
                    break; // this breaks the inside loop
                }
            }
            if (finalResult == count) {
                break; // this breaks the outside loop
            }
        }
        return finalResult;
    }

সংকলকের হিউরিস্টিকস আপনাকে শেষ রিটার্নটি বাদ দিতে দেয় না। আপনি যদি নিশ্চিত হন যে এটি কখনই throw না, তবে পরিস্থিতি স্পষ্ট করার জন্য আমি একটি throw দিয়ে প্রতিস্থাপন করব।

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range; count++) {
        ...
    }

    throw new AssertionError("unreachable code reached");
}

হতে পারে এটি একটি ইঙ্গিত যা আপনার কোডটি পুনরায় লিখতে হবে। উদাহরণ স্বরূপ:

  1. পূর্ণসংখ্যার 0 .. রেঞ্জ -1 এর অ্যারে তৈরি করুন। সমস্ত মান 0 তে সেট করুন।
  2. একটি লুপ সঞ্চালন। লুপে, একটি এলোমেলো সংখ্যা তৈরি করুন। আপনার তালিকায়, সেই সূচীতে দেখুন, মানটি 1 হয় কিনা তা দেখতে লুপটি ভেঙে দিন। অন্যথায়, সেই সূচকের মানটি 1 তে সেট করুন
  3. তালিকায় 1 টি সংখ্যা গণনা করুন এবং সেই মানটি ফিরিয়ে দিন।

private static int oneRun(int range) {
    int result = -1; // use this to store your result
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range && result == -1; count++) { // Run until result found.
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.   
        for (int i = 0; i < count && result == -1; i++) { // Check for past occurence and leave after result found.
            if (rInt[i] == rInt[count]) {
                result = count;
            }
        }
    }
    return result; // return your result
}




java