c# - একক ক্রিয়াকলাপে কি সহজ(x== 0 || x== 1) সহজ করা সম্ভব?




algorithm optimization (10)

তাই আমি ফিবোনাচি সিক্যুয়েন্সে n তম সংখ্যাটি যথাসম্ভব কমপ্যাক্টে একটি ক্রিয়াকলাপে লেখার চেষ্টা করছিলাম:

public uint fibn ( uint N ) 
{
   return (N == 0 || N == 1) ? 1 : fibn(N-1) + fibn(N-2);
}

তবে আমি ভাবছি আমি পরিবর্তন করে এটিকে আরও আরও কমপ্যাক্ট এবং দক্ষ করে তুলতে পারি কিনা

(N == 0 || N == 1)

একক তুলনায়। এমন কিছু অভিনব বিট শিফট অপারেশন রয়েছে যা এটি করতে পারে?


কীভাবে এটি বিটশিট দিয়ে করবেন

আপনি যদি বিটশিফ্ট ব্যবহার করতে চান এবং কোডটি কিছুটা অস্পষ্ট করতে চান (তবে সংক্ষিপ্ত) আপনি করতে পারেন:

public uint fibn ( uint N ) {
   return N >> 1 != 0? fibn(N-1) + finb(N-2): 1;
}

ভাষার সি তে স্বাক্ষরযুক্ত পূর্ণসংখ্যার জন্য, N>>1 লো অর্ডার বিটটি ছাড়িয়ে যায়। যদি ফলাফলটি শূন্য নয় তবে এটি সূচিত করে যে এন 1 এর চেয়ে বড়।

দ্রষ্টব্য: এই অ্যালগরিদম মারাত্মকভাবে অক্ষম কারণ এটি অকারণে ক্রমটির মানগুলি পূর্বে গণনা করা হয়েছে বলে পুনরায় গণনা করে।

কিছু ওয়ে ওয়ে ওয়ে

সুস্পষ্টভাবে একটি ফিবোনাচি (এন) আকারের গাছ তৈরির পরিবর্তে এটি একটি পাস গণনা করুন:

uint faster_fibn(uint N) { //requires N > 1 to work
  uint a = 1, b = 1, c = 1;
  while(--N != 0) {
    c = b + a;
    a = b;
    b = c;
  }
  return c;
}

কিছু লোক যেমন উল্লেখ করেছেন, a৪ বিটের স্বাক্ষরবিহীন পূর্ণ পূর্ণসংখ্যার এমনকি উপচে পড়তে বেশি সময় লাগে না। আপনি কতটা বড় হওয়ার চেষ্টা করছেন তার উপর নির্ভর করে আপনার স্বেচ্ছাচারিত যথার্থ পূর্ণসংখ্যা ব্যবহার করতে হবে।


আপনি অন্যান্য সমস্ত বিট 0 এর মতো দেখতেও পরীক্ষা করতে পারেন:

return (N & ~1) == 0 ? 1 : N * fibn(N-1);

পুরোপুরি ধন্যবাদ Matt আরও আরও ভাল সমাধানের জন্য:

return (N | 1) == 1 ? 1 : N * fibn(N-1);

উভয় ক্ষেত্রে আপনার প্রথম বন্ধনীর যত্ন নেওয়া প্রয়োজন কারণ বিটওয়াইজ অপারেটরগুলির == চেয়ে কম অগ্রাধিকার রয়েছে।


আপনি যেমন একটি ইউন্ট ব্যবহার করেন যা নেতিবাচক পেতে পারে না, আপনি n < 2 পরীক্ষা করতে পারেন

সম্পাদনা

বা বিশেষ ফাংশনের ক্ষেত্রে আপনি নীচে এটি লিখতে পারেন:

public uint fibn(uint N)
    return (N == 0) ? 1 : N * fibn(N-1);
}

যা অবশ্যই অতিরিক্ত পুনরাবৃত্তি পদক্ষেপের ব্যয় করে একই ফলাফলের দিকে নিয়ে যাবে।


এই এক কাজ

Math.Sqrt(N) == N 

0 এবং 1 এর বর্গমূল যথাক্রমে 0 এবং 1 ফিরে আসবে।


এন ইউন্ট হয়, শুধু ব্যবহার করুন

N <= 1

কেবল N <= 1 আছে কিনা তা পরীক্ষা করে দেখুন যেহেতু আপনি জানেন যে এন স্বাক্ষরযুক্ত সেখানে কেবলমাত্র দুটি শর্ত থাকতে পারে N <= 1 যা TRUE : 0 এবং 1 এর ফলাফল দেয়

public uint fibn ( uint N ) 
{
   return (N <= 1) ? 1 : fibn(N-1) + finb(N-2);
}

পার্টিতে দেরি হয়ে গেলেও আপনি এটিও করতে পারেন (x==!!x)

!!x যদি 0 না তবে মানটিকে 1 রূপান্তর করে এবং যদি এটি হয় তবে 0 এ রেখে দেয়।
আমি এই ধরণের জিনিসটি প্রচুর অবহেলায় ব্যবহার করি।

দ্রষ্টব্য: এটি সি, এটি সি # তে কাজ করে কিনা তা নিশ্চিত নন


ফিবোনাচি সিকোয়েন্স হ'ল সংখ্যার একটি সিরিজ যেখানে দুটি নম্বর আগে যুক্ত করে একটি সংখ্যা পাওয়া যায়। দুটি প্রারম্ভিক পয়েন্ট রয়েছে: ( 0,1 , 1,2, ..) এবং ( 1,1 , 2,3)।

-----------------------------------------
Position(N)| Value type 1 | Value type 2
-----------------------------------------  
1          |  0           |   1
2          |  1           |   1
3          |  1           |   2
4          |  2           |   3
5          |  3           |   5
6          |  5           |   8
7          |  8           |   13
-----------------------------------------

এই ক্ষেত্রে অবস্থান N 1 থেকে শুরু হয়, এটি অ্যারে সূচক হিসাবে 0-based নয়।

সি # 6 এক্সপ্রেশন-বডি বৈশিষ্ট্য এবং টিনারি অপারেটর সম্পর্কে দিমিত্রি'র পরামর্শ ব্যবহার করে আমরা টাইপ 1 এর সঠিক গণনা সহ একটি লাইন ফাংশন লিখতে পারি:

public uint fibn(uint N) => N<3? N-1: fibn(N-1)+fibn(N-2);

এবং টাইপ 2 জন্য:

public uint fibn(uint N) => N<3? 1: fibn(N-1)+fibn(N-2);

যেহেতু যুক্তিটি uint ( স্বাক্ষরযুক্ত ) আপনি রাখতে পারেন

  return (N <= 1) ? 1 : N * fibn(N-1);

কম পাঠযোগ্য (আইএমএইচও) তবে আপনি প্রতিটি অক্ষর গণনা করলে ( কোড গল্ফ বা একই রকম)

  return N < 2 ? 1 : N * fibn(N-1);

সম্পাদনা : আপনার সম্পাদিত প্রশ্নের জন্য :

  return (N <= 1) ? 1 : fibn(N-1) + fibn(N-2);

অথবা

  return N < 2 ? 1 : fibn(N-1) + fibn(N-2);

সুতরাং আমি এই বিশেষ পূর্ণসংখ্যার একটি List তৈরি করেছি এবং N সাথে সম্পর্কিত কিনা তা পরীক্ষা করেছিলাম।

static List<uint> ints = new List<uint> { 0, 1 };

public uint fibn(uint N) 
{
   return ints.Contains(N) ? 1 : fibn(N-1) + fibn(N-2);
}

আপনি বিভিন্ন উদ্দেশ্যে একটি সম্প্রসারণ পদ্ধতিও ব্যবহার করতে পারেন যেখানে অন্তর্ভুক্ত কেবলমাত্র একবারে কল করা হয় (যেমন আপনার অ্যাপ্লিকেশনটি ডেটা শুরু এবং লোড করার সময়)। এটি একটি পরিষ্কার শৈলী সরবরাহ করে এবং আপনার মান ( N ) এর সাথে প্রাথমিক সম্পর্কটি স্পষ্ট করে:

static class ObjectHelper
{
    public static bool PertainsTo<T>(this T obj, IEnumerable<T> enumerable)
    {
        return (enumerable is List<T> ? (List<T>) enumerable : enumerable.ToList()).Contains(obj);
    }
}

এটি প্রয়োগ করুন:

N.PertainsTo(ints)

এটি করার দ্রুততম উপায় এটি নাও হতে পারে, তবে আমার কাছে এটি আরও ভাল শৈলী বলে মনে হয়।





arithmetic-expressions