প্রদত্ত সংখ্যার বিভাজকের সংখ্যা গণনা করার জন্য অ্যালগরিদম


177

প্রদত্ত সংখ্যার বিভাজক সংখ্যা গণনা করার জন্য সবচেয়ে অনুকূল অ্যালগরিদম (পারফরম্যান্স-ওয়াইজ) কী হবে?

আপনি সিউডোকোড বা কোনও উদাহরণের একটি লিঙ্ক সরবরাহ করতে পারলে এটি দুর্দান্ত হবে।

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


আপনার রেকগুলি দেওয়া কারণগুলির সংখ্যার সাথে আসা অস্পষ্ট। আমি অনুমান করছি আপনি অনন্য-অনন্য প্রাথমিক বিভাজকের সংখ্যা সন্ধান করছেন কারণ আপনি যদি না চান যে আমি কেবল একটি প্রোগ্রাম লিখি যাতে সবসময় 1 ফিরে আসে যদি ফ্যাক্টারে সংখ্যাটি এক হয় এবং 2 অন্য কিছু হয় তবে। 0 এর পরিবর্তনের দরকার হতে পারে ...
জাস্টিন বোজনিয়ায়ার

@ সকার: মানদণ্ডের এমন একটি বিধি রয়েছে যার জন্য আপনার বিভাজক প্রয়োজন need কারণগুলি গণনা করার অনেকগুলি উপায় রয়েছে এবং প্রতিটি পদ্ধতি একটি নির্দিষ্ট পরিসরের জন্য আরও উপযুক্ত।
অ্যান্ডি টার্নার

2
এখানে একটি সম্পর্কিত আকর্ষণীয় সমস্যা রয়েছে projecteuler.net/problem=12
ড্যানিলোকিও

1
এমনকি সম্পাদিত উইকিপিডিয়া নিবন্ধ থেকে আটকিনের নিখুঁত চালুনি আর্টোস্টেনিসের সর্বাধিক চক্রযুক্ত চাঁদীর চেয়ে বিশাল অযৌক্তিক সীমা পর্যন্ত আর কখনও দ্রুত হবে না এবং পৃষ্ঠাটি বিভাগিত সংস্করণগুলি এমনকি এসইওর পক্ষে বেশি হবে (দেখুন SoE প্রাইমসিভ বনাম সোএ প্রাইমজেন হিসাবে দেখুন) আটকিনের অংশীদার বার্নস্টেইন বাস্তবায়ন করেছেন। এটি সাধারণ ভুল ইন্টারনেট জ্ঞান যে তাদের গবেষণাটি এত দ্রুত প্রমাণ করেছে, তবে তারা এটি প্রমাণ করার জন্য ব্যবহৃত SoE এর অপ্টিমাইজেশনকে কৃত্রিমভাবে সীমাবদ্ধ করেছে furtherআর আরও ব্যাখ্যাের জন্য আমার SoA উত্তরটি দেখুন
গর্ডনবিগড

উত্তর:


78

দিমিত্রি ঠিক বলেছেন যে আপনি চাইছেন আটকিনের সিভির মূল তালিকাটি তৈরি করতে পারেন তবে আমি বিশ্বাস করি না যে পুরো বিষয়টি যত্ন নেয়। এখন আপনার কাছে প্রাইমগুলির একটি তালিকা রয়েছে আপনাকে দেখতে হবে যে সেই সমস্ত প্রাইমগুলির মধ্যে কতগুলি বিভাজন হিসাবে কাজ করে (এবং কতবার)।

আলগোটির জন্য এখানে অজগরটি এখানে দেখুন এবং "বিষয়: গণিত - বিভাজক অ্যালগরিদম প্রয়োজন" সন্ধান করুন। তালিকার আইটেমের সংখ্যাটি কেবল তাদের ফিরিয়ে না দিয়ে গণনা করুন।

এখানে একটি ডাঃ গণিত যা আপনাকে গাণিতিকভাবে করা উচিত ঠিক কী তা ব্যাখ্যা করে।

মূলত এটি আপনার সংখ্যাটি নীচে নেমে আসে n:
n = a^x * b^y * c^z
(যেখানে a, b, এবং c এন এর প্রধান বিভাজক এবং x, y এবং z হ'ল বিভাজকের পুনরাবৃত্তি সংখ্যাটি গণনা করা হয়) তবে বিভাজনকারীদের সকলের জন্য মোট গণনা হ'ল:
(x + 1) * (y + 1) * (z + 1)

সম্পাদনা করুন: বিটিডাব্লু, একটি, বি, সি ইত্যাদি খুঁজে পেতে যদি আপনি এটিকে সঠিকভাবে বুঝতে পারি তবে আপনি কোনও লোভী অ্যালগোয়ের পরিমাণ মতো কী করতে চাইবেন। আপনার সবচেয়ে বড় প্রধান বিভাজক দিয়ে শুরু করুন এবং এটি নিজে থেকে গুণ করুন যতক্ষণ না আরও গুণক n সংখ্যাটি অতিক্রম করবে। তারপরে পরবর্তী সর্বনিম্ন ফ্যাক্টারে যান এবং আগের মৌলিক সংখ্যাটি the বর্তমান প্রাইম দ্বারা এটি বহুগুণ বৃদ্ধি পেয়েছিল এবং প্রাইম দ্বারা পরবর্তী গুণমানকে আরও বেশি না হওয়া পর্যন্ত গুণতে থাকবে ... ইত্যাদি আপনি কত বার গুন করবেন তার ট্র্যাক রাখুন বিভাজক একসাথে এবং উপরের সূত্রে এই সংখ্যাগুলি প্রয়োগ করুন।

আমার আলগো বিবরণ সম্পর্কে 100% নিশ্চিত নয় তবে যদি তা না হয় তবে এটি অনুরূপ কিছু।


1
আপনি যদি একটি বিশাল সংখ্যক ফ্যাক্টরির হন তবে আপনি এমনকি প্রাথমিক তালিকাটি দেখতে চান না । আপনি যত তাড়াতাড়ি সম্ভব সমস্ত সম্ভাবনার ব্যাপ্তি দূর করতে চান! আরও উত্তর জন্য আমার উত্তর দেখুন।
ব্যবহারকারী 11318

আমি বুঝতে পারি যে এটি 2 বছর আগে ছিল, কিন্তু আপনার অজগরটি অ্যালগো লিঙ্কটি ভেঙে গেছে, এখন কোথায় আছে তা জানতে হবে?
জেবি।

2
তাই n = (a^x * b^y * c^z)-(x + 1) * (y + 1) * (z + 1)নিয়ম
SIslam

1
@ শশাঙ্ক যেমন বলেছেন, "EDIT:" বিভাগের অ্যালগরিদমটি ভুল: মনে করুন এন = 45 = 3 * 3 * 5। বৃহত্তম প্রধান বিভাজক 5, তবে এটি অতিক্রম না করা পর্যন্ত এটি নিজেই দ্বারা গুণ করা অ্যালগরিদমকে বলে দেবে যে এটিতে ফ্যাক্টর 5 এর 2 অনুলিপি রয়েছে (যেহেতু 5 * 5 = 25 <45)।
j_random_hacker

1
'সিভির অফ সিটিন' এর ও (এন / লগ (লগ (এন))) এর রানটাইম জটিলতা রয়েছে । ব্রুট-ফোর্স 1 থেকে সমস্ত সম্ভাব্য বিভাজনগুলি পরীক্ষা করে ... স্কয়ার্ট (এন) এর ও (স্ক্রার্ট (এন)) এর একটি রানটাইম জটিলতা যা অনেক উচ্চতর। কিভাবে এই উত্তর গৃহীত হয়েছে?
লে_ মি

47

একটা হয় অনেক Atkin এর চালনী চেয়ে ফ্যাক্টরিং আরো কৌশল। উদাহরণস্বরূপ ধরুন আমরা 5893 গুণন করতে চাই Well এটির স্কয়ারটি 76.76 is ... এখন আমরা 5893 বর্গের পণ্য হিসাবে লেখার চেষ্টা করব। ভাল (77 * 77 - 5893) = 36 যা 6 স্কোয়ার্ড, তাই 5893 = 77 * 77 - 6 * 6 = (77 + 6) (77-6) = 83 * 71। যদি এটি কাজ না করে আমরা 78 * 78 - 5893 একটি নিখুঁত বর্গক্ষেত্র কিনা তা লক্ষ্য করতাম। ইত্যাদি। এই কৌশলটি দিয়ে আপনি পৃথক প্রাইমগুলি পরীক্ষা করে তার চেয়ে অনেক দ্রুত এন বর্গক্ষেত্রের নিকটবর্তী কারণগুলির জন্য দ্রুত পরীক্ষা করতে পারেন। যদি আপনি চালুনির সাথে বড় প্রাইমসকে শাসনের জন্য এই কৌশলটি একত্রিত করেন তবে কেবল চালাইয়ের চেয়ে আপনার কাছে আরও ভাল ফ্যাক্টরিং পদ্ধতি থাকবে।

এবং এটি কেবল বিপুল সংখ্যক কৌশলগুলির মধ্যে একটি যা বিকাশ লাভ করেছে। এটি মোটামুটি সরল is উপবৃত্তাকার বক্ররেখার উপর ভিত্তি করে ফ্যাক্টরিং কৌশলগুলি বোঝার জন্য যথেষ্ট সংখ্যা তত্ত্বটি শিখতে আপনার দীর্ঘ সময় লাগবে। (আমি জানি তাদের অস্তিত্ব আছে I আমি সেগুলি বুঝতে পারি না))

অতএব আপনি যদি ছোট সংখ্যার সাথে ডিল না করেন তবে আমি নিজেই সেই সমস্যাটি সমাধান করার চেষ্টা করব না। পরিবর্তে আমি PARI লাইব্রেরির মতো এমন কিছু ব্যবহার করার উপায় অনুসন্ধান করার চেষ্টা করব যা ইতিমধ্যে একটি অত্যন্ত দক্ষ সমাধান প্রয়োগ করেছে। এটি দিয়ে আমি প্রায় 00 সেকেন্ডে 124321342332143213122323434312213424231341 এর মতো এলোমেলো 40 টি সংখ্যার ফ্যাক্টর করতে পারি। (আপনি যদি অবাক হয়ে থাকেন তবে এর কার্যকারিতাটি 29 * 439 * 1321 * 157907 * 284749 * 33843676813 * 4857795469949 I


1
আপনি কৌশলটি খুব চালাক, তবে এটি সংখ্যার কতগুলি কারণ রয়েছে তা আমাকে বলে না, এটি আছে?
sker

23
একবার যখন আপনি মৌলিক ফ্যাক্টরীকরণটি পেয়েছেন, তখন কতগুলি কারণ রয়েছে তা নির্ধারণ করা সহজবোধ্য। ধরা যাক মূল কারণগুলি হ'ল পি 1, পি 2, ..., পিকে এবং সেগুলি এম 1, এম 2, ..., এম কে বার পুনরাবৃত্তি করে। তারপরে (1 + এম 1) (1 + এম 2) ... (1 + এম কে) ফ্যাক্টর রয়েছে।
ব্যবহারকারী 11318

একটি উত্সাহব্যঞ্জক চালনী হয় দ্বিঘাত চালনী । এটি সংখ্যার তত্ত্ব ব্যবহার করে - চতুষ্কোণ সম্মিলন এবং কিছু লিনিয়ার বীজগণিত। আমি এটি বিশ্ববিদ্যালয়ের দ্বিতীয় বর্ষের তত্ত্বের কোর্সে ব্যবহার করার জন্য যথেষ্ট শিখেছি।
ট্যানার

33

@Yasky

আপনার বিভাজকের কার্যক্রমে একটি ত্রুটি রয়েছে যা এটি নিখুঁত স্কোয়ারগুলির জন্য সঠিকভাবে কাজ করে না।

চেষ্টা করুন:

int divisors(int x) {
    int limit = x;
    int numberOfDivisors = 0;

    if (x == 1) return 1;

    for (int i = 1; i < limit; ++i) {
        if (x % i == 0) {
            limit = x / i;
            if (limit != i) {
                numberOfDivisors++;
            }
            numberOfDivisors++;
        }
    }

    return numberOfDivisors;
}

6
(X% i) i = 0 হলে শূন্য দ্বারা বিভাজন ঘটায় না? আমি = 1.. কমানো উচিত?
rhu

@ আরহু 0 টি যা-ই হোক নিরর্থক কারণ 0 কোনও সংখ্যার ফ্যাক্টর নয়।
ইজোশুয়াস - মনিকা পুনরায় ইনস্টল করুন

29

আমি অসম্মতি জানাই যে আটকিনের চালনিটি চলার পথ because

এখানে কিছু কোড যা সামান্য হ্যাকিয়ার হলেও সাধারণত অনেক দ্রুত হয়:

import operator
# A slightly efficient superset of primes.
def PrimesPlus():
  yield 2
  yield 3
  i = 5
  while True:
    yield i
    if i % 6 == 1:
      i += 2
    i += 2
# Returns a dict d with n = product p ^ d[p]
def GetPrimeDecomp(n):
  d = {}
  primes = PrimesPlus()
  for p in primes:
    while n % p == 0:
      n /= p
      d[p] = d.setdefault(p, 0) + 1
    if n == 1:
      return d
def NumberOfDivisors(n):
  d = GetPrimeDecomp(n)
  powers_plus = map(lambda x: x+1, d.values())
  return reduce(operator.mul, powers_plus, 1)

PS এই সমস্যাটি সমাধান করার জন্য অজগর কোডটি কাজ করছে।


11

এখানে একটি সরল ফরওয়ার্ড ও (স্কয়ার্ট (এন)) অ্যালগরিদম। আমি প্রকল্প ইউরার সমাধান করতে এটি ব্যবহার করেছি

def divisors(n):
    count = 2  # accounts for 'n' and '1'
    i = 2
    while i ** 2 < n:
        if n % i == 0:
            count += 2
        i += 1
    if i ** 2 == n:
        count += 1
    return count

তবে আপনি কেন সর্বদা গণনা 2 দ্বারা বাড়িয়ে দেন? ... আপনি যে উপপাদ্য প্রয়োগ করেছেন তা কি আছে?
সামার কোড

3
কারণ আপনি কেবল sqrt (n) পর্যন্ত সঙ্কুচিত হন। উদাহরণস্বরূপ: যদি আপনি 36 এর জন্য সমস্ত বিভাজনকারী অনুসন্ধান করার চেষ্টা করছেন - আপনি 2 থেকে 6 পর্যন্ত গণনা করবেন You আপনি জানেন যে 1 এবং 36,2 এবং 18, 3 এবং 12, 4 এবং 9, 6,6 সমস্ত বিভাজন এবং তারা যুগল হয়ে আসে।
অ্যান্টনি টমাস

2
অ্যান্টনি অনেক ধন্যবাদ, আমি এখন বুঝতে পেরেছি: ডি! একটি ছোট সংযোজন: আমি মনে করি এটি স্কয়ার্ট (এন) মানকে আলাদাভাবে চিকিত্সা করা উচিত কারণ আপাতত এটি এটির পরিবর্তে দু'বার বিবেচনায় নেয়, আমি মনে করি
সামার কোড

O (sqrt (n)) খুব খারাপ না হলেও এটি অনুকূল নয়। প্রাইম ফ্যাক্টরের পচন গণনা করা খুব দ্রুত করা যায় এবং বিভাজকের সংখ্যা গণনা করার জন্য যথেষ্ট।
লে_ম

প্রতিটি পুনরাবৃত্তিতে আপনাকে i you গণনা করতে হবে, I in (কেবল একবার গণনা করা) এর সাথে তুলনা করা কি দ্রুত হবে না?
ইউকুল্লি

10

এই আকর্ষণীয় প্রশ্নটি দেখতে দেখতে অনেক কঠিন, এবং এর উত্তর দেওয়া হয়নি। প্রশ্নটি 2 খুব আলাদা প্রশ্নের মধ্যে ফ্যাক্টর করা যায়।

1 প্রদত্ত এন, এন এর প্রাথমিক কারণগুলির তালিকা এলটি সন্ধান করুন

2 প্রদত্ত এল, সংখ্যার অনন্য সংমিশ্রণের গণনা করুন

আমি এখন পর্যন্ত যে সমস্ত উত্তর দেখছি সেগুলি # 1 উল্লেখ করে এবং উল্লেখ করতে ব্যর্থ হয় এটি বিপুল সংখ্যার জন্য ট্র্যাকটেবল নয়। মাঝারি আকারের এন, এমনকি 64-বিট সংখ্যার জন্য, এটি সহজ; প্রচুর এন এর জন্য, ফ্যাক্টরিং সমস্যাটি "চিরকালের জন্য" নিতে পারে। পাবলিক কী এনক্রিপশন এটি নির্ভর করে।

প্রশ্ন # 2 এর আরও আলোচনার প্রয়োজন। যদি এলটিতে কেবলমাত্র অনন্য সংখ্যা থাকে তবে এটি এন আইটেম থেকে কে অবজেক্ট বেছে নেওয়ার সমন্বয় সূত্র ব্যবহার করে একটি সাধারণ গণনা। প্রকৃতপক্ষে, আপনাকে 1 থেকে আকারের (এল) এর পরিবর্তিত করে সূত্র প্রয়োগ করে ফলাফলগুলি যোগ করতে হবে। যাইহোক, এল সাধারণত একাধিক প্রাইমের একাধিক উপস্থিতি ধারণ করে। উদাহরণস্বরূপ, এল = {2,2,2,3,3,5 N হল এন = 360 এর গুণককরণ ization এখন এই সমস্যাটি বেশ কঠিন!

# 2 টি পুনরায় বিশিষ্ট করা, প্রদত্ত কালেকশন সি দিয়ে আই আইটেম রয়েছে, যেমন আইটেমটির 'ডুপ্লিকেট' রয়েছে এবং আইটেম বিতে বি 'ডুপ্লিকেট ইত্যাদি রয়েছে 1 থেকে কে -1 আইটেমের কতগুলি অনন্য সংমিশ্রণ রয়েছে? উদাহরণস্বরূপ, = 2}, {2,2}, {2,2,2}, {2,3}, {2,2,3,3 each প্রতিটি অবশ্যই একবার এবং কেবল একবার এল = {2,2 হওয়া আবশ্যক , 2,3,3,5}। এই জাতীয় প্রতিটি উপ-সংগ্রহ হ'ল উপ-সংগ্রহের আইটেমগুলিকে গুণ করে N এর একটি অনন্য বিভাজক।


এখানে খুব 2. অনুরূপ একটি সমস্যা কিছু ছদ্ম কোড একটি লিঙ্ক answers.google.com/answers/threadview/id/392914.html
mR_fr0g

3
প্রশ্ন # 2 এর একটি সুপরিচিত সমাধান রয়েছে। {পি_আই, কে_আই of এর গুণককরণের জন্য যেখানে সংখ্যাবৃদ্ধির p_iসাথে সংখ্যার একটি মৌলিক ফ্যাক্টর k_i, সেই সংখ্যার বিভাজকের মোট সংখ্যা (k_1+1)*(k_2+1)*...*(k_n+1)। আমার ধারণা আপনি এখনই এটি জানেন তবে আমি এখানে এলোমেলো পাঠক যদি সুবিধার জন্য এটি লিখি।
নেস 16

9

আপনার প্রশ্নের উত্তর পূর্ণসংখ্যার আকারের উপর নির্ভর করে। ছোট সংখ্যার জন্য পদ্ধতি, উদাহরণস্বরূপ, তারপর কম 100 বিট, এবং সংখ্যার জন্য ~ 1000 বিট (যেমন ক্রিপ্টোগ্রাফিতে ব্যবহৃত) সম্পূর্ণ আলাদা।


6


কেবলমাত্র একটি লাইন আমি আপনার প্রশ্ন সম্পর্কে খুব সতর্কতার সাথে চিন্তা করেছি এবং আমি কোডের একটি অত্যন্ত দক্ষ এবং পারফরম্যান্ট টুকরো লেখার চেষ্টা করেছি স্ক্রিনে প্রদত্ত সংখ্যার সমস্ত বিভাজক মুদ্রণের জন্য আমাদের কেবলমাত্র একটি লাইন কোডের প্রয়োজন! (gcc এর মাধ্যমে সংকলনের সময় বিকল্প -std = c99 ব্যবহার করুন)

for(int i=1,n=9;((!(n%i)) && printf("%d is a divisor of %d\n",i,n)) || i<=(n/2);i++);//n is your number

বিভাজকের সংখ্যা সন্ধানের জন্য আপনি নিম্নলিখিত খুব দ্রুত ফাংশনটি ব্যবহার করতে পারেন (1 এবং 2 ব্যতীত সমস্ত সংখ্যার জন্য সঠিকভাবে কাজ করুন)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    return counter;
}

বা যদি আপনি প্রদত্ত সংখ্যাটিকে বিভাজন হিসাবে গণ্য করেন (1 এবং 2 ব্যতীত সমস্ত সংখ্যার জন্য সঠিকভাবে কাজ করুন)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    return ++counter;
}

দ্রষ্টব্য: উপরের দুটি ফাংশন 1 এবং 2 নম্বর ব্যতীত সমস্ত ধনাত্মক পূর্ণ সংখ্যার জন্য সঠিকভাবে কাজ করে তাই এটি 2 এর চেয়ে বেশি সংখ্যক সংখ্যার জন্য কার্যকরী তবে যদি আপনার 1 এবং 2 টি আবরণ করা প্রয়োজন তবে আপনি নীচের একটি ফাংশন ব্যবহার করতে পারেন (সামান্য ধীর)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    if (n==2 || n==1)
    {
    return counter;
    }
    return ++counter;
}

অথবা

int number_of_divisors(int n)
{
    int counter,i;
for(counter=0,i=1;(!(i==n) && !(n%i) && (counter++)) || i<=(n/2);i++);
    return ++counter;
}

ছোট সুন্দর :)


5

অ্যাটকিনের চালনা হ'ল ইরোটোস্টেনেসের চালুনির একটি অনুকূলিত সংস্করণ যা সমস্ত প্রদত্ত সংখ্যাকে একটি প্রদত্ত পূর্ণসংখ্যা পর্যন্ত দেয়। আপনার আরও বিশদের জন্য এটি গুগল করতে সক্ষম হওয়া উচিত।

আপনার যদি একবার সেই তালিকা হয়ে যায়, তবে প্রতিটি প্রধান দ্বারা আপনার সংখ্যাটি ভাগ করে নেওয়া একেবারেই সহজ বিষয় এটি সঠিক বিভাজক (যেমন, বাকীটি শূন্য হয়)।

একটি সংখ্যার (ডি) জন্য বিভাজক গণনা করার প্রাথমিক পদক্ষেপগুলি হ'ল এটি হ'ল সিউডোকোডটি রিয়েল কোড থেকে রূপান্তরিত হয়েছে তাই আমি আশা করি যে আমি ত্রুটিগুলি প্রবর্তন করিনি]:

for z in 1..n:
    prime[z] = false
prime[2] = true;
prime[3] = true;

for x in 1..sqrt(n):
    xx = x * x

    for y in 1..sqrt(n):
        yy = y * y

        z = 4*xx+yy
        if (z <= n) and ((z mod 12 == 1) or (z mod 12 == 5)):
            prime[z] = not prime[z]

        z = z-xx
        if (z <= n) and (z mod 12 == 7):
            prime[z] = not prime[z]

        z = z-yy-yy
        if (z <= n) and (x > y) and (z mod 12 == 11):
            prime[z] = not prime[z]

for z in 5..sqrt(n):
    if prime[z]:
        zz = z*z
        x = zz
        while x <= limit:
            prime[x] = false
            x = x + zz

for z in 2,3,5..n:
    if prime[z]:
        if n modulo z == 0 then print z

5

আপনি এটি চেষ্টা করতে পারেন। এটি কিছুটা হ্যাকিশ, তবে এটি যুক্তিসঙ্গত দ্রুত।

def factors(n):
    for x in xrange(2,n):
        if n%x == 0:
            return (x,) + factors(n/x)
    return (n,1)

2
যদিও এই ফাংশনটি যুক্তিসঙ্গত সময়ে n এর মূল ফাংশন ক্ষয় সরবরাহ করে, এটি ক) অনুকূল নয় এবং খ)
ওপির

এবং এটির পুনরাবৃত্তির কারণে বড় সংখ্যার পক্ষে কাজ করবে না
whackamadoodle3000

যদিও এটি সর্বোত্তম নয়, এবং গুণনীয় কারণগুলির তুলনায় এটি আসলে তাদের তালিকাভুক্ত করে, এর সরলতা এবং সৌন্দর্য আশ্চর্যজনক এবং যুক্তিযুক্তভাবে দ্রুত। ^^
গৌরব সিংহল

5

একবার আপনার প্রাথমিক গুণক তৈরি হয়ে গেলে, বিভাজকের সংখ্যা সন্ধান করার উপায় রয়েছে is প্রতিটি স্বতন্ত্র ফ্যাক্টরের প্রতিটি এক্সটেনটারে একটি যোগ করুন এবং তারপরে এক্সপোজারগুলিকে একসাথে গুণ করুন।

উদাহরণস্বরূপ: 36 প্রধান ফ্যাক্টরাইজেশন: 2 ^ 2 * 3 ^ 2 বিভাজক: 1, 2, 3, 4, 6, 9, 12, 18, 36 বিভাজকের সংখ্যা: 9

প্রতিটি ক্ষতিকারকগুলিতে একটি যোগ করুন 2 ^ 3 * 3 ^ 3 গুণাগুণকে গুণিত করুন: 3 * 3 = 9


3

আপনি কোনও সমাধানের প্রতিশ্রুতি দেওয়ার আগে বিবেচনা করুন যে সাধারন ক্ষেত্রে সিভ পদ্ধতির কোনও ভাল উত্তর হতে পারে না।

কিছুক্ষণ আগে এখানে একটি প্রধান প্রশ্ন ছিল এবং আমি একটি সময় পরীক্ষা করেছিলাম - 32-বিট পূর্ণসংখ্যার জন্য অন্তত নির্ধারণ করে যে এটি প্রাইম ছিল কি না তা জোরের বলের চেয়ে ধীর। দুটি কারণ চলছে:

1) কোনও বিভাগ বিভাগ করতে কিছু সময় নিলে তারা কম্পিউটারে খুব দ্রুত - উত্তরটি দেখার ব্যয়ের অনুরূপ।

2) আপনার কাছে প্রাইম টেবিল না থাকলে আপনি একটি লুপ তৈরি করতে পারেন যা পুরোপুরি এল 1 ক্যাশে চলে। এটি এটি দ্রুত করে তোলে।


3

এটি একটি কার্যকর সমাধান:

#include <iostream>
int main() {
  int num = 20; 
  int numberOfDivisors = 1;

  for (int i = 2; i <= num; i++)
  {
    int exponent = 0;
    while (num % i == 0) {
        exponent++; 
        num /= i;
    }   
    numberOfDivisors *= (exponent+1);
  }

  std::cout << numberOfDivisors << std::endl;
  return 0;
}

2

বিভক্তরা দর্শনীয় কিছু করে: তারা সম্পূর্ণরূপে বিভক্ত হয়। আপনি যদি কোনও সংখ্যার জন্য বিভাজকের সংখ্যাটি পরীক্ষা করতে চান nতবে পুরো স্পেকট্রামটি স্প্যান করা স্পষ্টতই অপ্রয়োজনীয় 1...n। আমি এর জন্য কোনও গভীরতর গবেষণা করিনি তবে আমি ত্রিভুজাকার সংখ্যাগুলিতে প্রজেক্ট ইউলারের সমস্যা 12 সমাধান করেছি । বৃহত্তর ৫০০ টি বিভাজক পরীক্ষার জন্য আমার সমাধানটি 309504 মাইক্রোসেকেন্ডে (~ 0.3s) চালিয়েছে। সমাধানের জন্য আমি এই বিভাজক ফাংশনটি লিখেছি।

int divisors (int x) {
    int limit = x;
    int numberOfDivisors = 1;

    for (int i(0); i < limit; ++i) {
        if (x % i == 0) {
            limit = x / i;
            numberOfDivisors++;
        }
    }

    return numberOfDivisors * 2;
}

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

শুভ ছুটির দিন.


1
আপনার এখানে প্রথম পুনরাবৃত্তির জন্য 0 দিয়ে বিভাজন থাকতে হবে
বারফুন

দুর্ভাগ্যবশত না. ++ i ++ এর থেকে পৃথক (যার ফলে বিভাজন শূন্যের ত্রুটি হতে পারে)
আইগবানাম

আমি পিএইচপি-তে আপনার ফাংশন লিখেছি এবং এটি চালিয়েছি
বারফুন

কিছু অদ্ভুত কারণে, এটি আমার জন্য নির্দোষভাবে কাজ করেছিল। ওহ ভাল, আমার খারাপ। শুরু করুন numberOfDivisorsএবং 1 এ পুনরাবৃত্তিকারী; এটি শূন্য ত্রুটির দ্বারা বিভাজন থেকে মুক্তি পাওয়া উচিত
iGbanam

1
আপনার অ্যালগরিদম নিখুঁত স্কোয়ারের জন্য কাজ করে না। উদাহরণস্বরূপ, এটি x = 4 ইনপুটটির জন্য 4 ফেরায়, কারণ এটি 2 বার গণনা করছে ... 1, 2, 2, 4. উত্তরটি 3: 1,2,4 হওয়া উচিত
মাইকেল

1

আপনি এখানে বর্ণিত আতকিনের চালনী চান: http://en.wikedia.org/wiki/Sieve_of_Atkin


1
এটি আপনাকে আপনার প্রদত্ত সংখ্যার নীচে প্রাইমস পেতে চলেছে - তবে কোনও গ্যারান্টি নেই যে এই প্রাইমগুলি বিভাজনকারী হতে চলেছে? (যতক্ষণ না আমি কিছু মিস করছি)
অ্যান্ড্রু এডজকম্বে

এখান থেকে সমস্ত প্রাইম <
স্কয়ার্ট

1
এটি দ্রুত ঝাঁপিয়ে পড়তে পারে তবে সমস্ত প্রাইমস পরীক্ষা করা <sqrt (N) এখনও এটি একটি খারাপ ফ্যাক্টরিং কৌশল যা আপনি এটি কতটা দক্ষতার সাথে খুঁজে পান না কেন। যে উন্নতি করার জন্য অনেক উপায় আছে।
ব্যবহারকারী 11318

প্রাইমগুলি পরীক্ষা করা ও (এন), এটি প্রাইমগুলি সন্ধান করা যা শক্ত অংশ। তবে এমনকি ইরোটোস্টিনিসগুলির নিরবচ্ছিন্ন চালনী দিয়ে আপনি এখনও কয়েক সেকেন্ডের অধীনে সমস্ত প্রাইম খুঁজে পেতে পারেন। এটি যে কোনও b৪ বি নম্বরকে কভার করে, এবং আমি নিশ্চিত যে আমরা এখানে ক্রিপ্টো স্তর স্তরের
স্ট্যাক্টরিংয়ের

1

প্রাথমিক নম্বর পদ্ধতিটি এখানে খুব স্পষ্ট। পি [] হ'ল বর্গ = স্কয়ার্ট (এন) এর চেয়ে কম বা সমান মূল সংখ্যাগুলির একটি তালিকা;

for (int i = 0 ; i < size && P[i]<=sq ; i++){
          nd = 1;
          while(n%P[i]==0){
               n/=P[i];
               nd++;
               }
          count*=nd;
          if (n==1)break;
          }
      if (n!=1)count*=2;//the confusing line :D :P .

     i will lift the understanding for the reader  .
     i now look forward to a method more optimized  .

1

সংখ্যা তত্ত্বের পাঠ্যপুস্তকগুলি বিভাজক-গণনা ফাংশনটিকে তাউ বলে। প্রথম আকর্ষণীয় ঘটনাটি হ'ল এটি গুণক, অর্থাৎ। τ (অব) = τ (ক) τ (খ), যখন ক এবং খের কোনও সাধারণ কারণ নেই। (প্রুফ: ক এবং খ এর প্রতিটি বিভাজক পৃথক পৃথক পৃথক বিভাজন দেয়))

এখন নোট করুন যে প্যা প্রাইম, τ (পি ** কে) = কে + 1 (পি এর ক্ষমতা)। সুতরাং আপনি সহজেই এর গুণক থেকে ute (n) গণনা করতে পারেন।

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

  1. সংখ্যাটি প্রাথমিক (দ্রুত) হলে পরীক্ষা করুন
  2. যদি তাই হয়, 2 ফিরে
  3. অন্যথায়, সংখ্যাকে ফ্যাক্ট করুন (একাধিক বৃহত প্রধান মৌলিক কারণ যদি ধীর)
  4. গুণক থেকে গুণন Comp (n) n

1

প্রদত্ত সংখ্যার বিভাজক সংখ্যা নির্ধারণের জন্য নীচে একটি সি প্রোগ্রাম রয়েছে।

উপরের অ্যালগরিদমের জটিলতা হ'ল O (sqrt (n))।

এই অ্যালগরিদম সংখ্যার জন্য সঠিকভাবে কাজ করবে যা নিখুঁত বর্গক্ষেত্রের পাশাপাশি সেই সংখ্যাগুলির জন্য যা নিখুঁত বর্গ নয়।

লক্ষ করুন যে অ্যালগোরিদমকে সবচেয়ে দক্ষ করতে লুপের উপরের অংশটি সংখ্যাটির বর্গ-রুটে সেট করা থাকে root

নোট করুন যে ওপারলিমিটকে একটি পৃথক ভেরিয়েবলে সংরক্ষণ করাও সময় সাশ্রয় করে, আপনার জন্য লুপের শর্ত বিভাগে sqrt ফাংশনটি কল করা উচিত নয়, এটি আপনার গণনার সময় সাশ্রয় করে।

#include<stdio.h>
#include<math.h>
int main()
{
    int i,n,limit,numberOfDivisors=1;
    printf("Enter the number : ");
    scanf("%d",&n);
    limit=(int)sqrt((double)n);
    for(i=2;i<=limit;i++)
        if(n%i==0)
        {
            if(i!=n/i)
                numberOfDivisors+=2;
            else
                numberOfDivisors++;
        }
    printf("%d\n",numberOfDivisors);
    return 0;
}

লুপের জন্য উপরের পরিবর্তে আপনি নিম্নলিখিত লুপটি ব্যবহার করতে পারেন যা আরও বেশি কার্যকর কারণ এটি সংখ্যার স্কোয়ার-রুট খুঁজে পাওয়ার প্রয়োজনীয়তা সরিয়ে দেয়।

for(i=2;i*i<=n;i++)
{
    ...
}

1

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

public static List<Integer> divisors(n) {   
    ArrayList<Integer> aList = new ArrayList();
    int top_count = (int) Math.round(Math.sqrt(n));
    int new_n = n;

    for (int i = 2; i <= top_count; i++) {
        if (new_n == (new_n / i) * i) {
            aList.add(i);
            new_n = new_n / i;
            top_count = (int) Math.round(Math.sqrt(new_n));
            i = 1;
        }
    }
    aList.add(new_n);
    return aList;
}

আমি জানি না এই ফাংশনটি কী গণনা করে তবে এটি অবশ্যই n এর বিভাজকের তালিকা নয়।
লে_ মি

1

এটি সংখ্যা বিভাজক গণনা করার সবচেয়ে প্রাথমিক উপায়:

class PrintDivisors
{
    public static void main(String args[])
    {

    System.out.println("Enter the number");

    // Create Scanner object for taking input
    Scanner s=new Scanner(System.in);

    // Read an int
    int n=s.nextInt();

        // Loop from 1 to 'n'
        for(int i=1;i<=n;i++)
        {

            // If remainder is 0 when 'n' is divided by 'i',
            if(n%i==0)
            {
            System.out.print(i+", ");
            }
        }

    // Print [not necessary]    
    System.out.print("are divisors of "+n);

    }
}

1

@Kendall

আমি আপনার কোডটি পরীক্ষা করেছি এবং কিছু উন্নতি করেছি, এখন এটি আরও দ্রুত। আমি @ هومن جاویدپور কোড দিয়েও পরীক্ষা করেছি, এটিও তার কোডের চেয়ে দ্রুত।

long long int FindDivisors(long long int n) {
  long long int count = 0;
  long long int i, m = (long long int)sqrt(n);
  for(i = 1;i <= m;i++) {
    if(n % i == 0)
      count += 2;
  }
  if(n / m == m && n % m == 0)
    count--;
  return count;
}

0

এটি কি কেবল সংখ্যাটি ফ্যাক্টর করার প্রশ্ন নয় - সংখ্যার সমস্ত কারণ নির্ধারণ করে? তারপরে আপনি সিদ্ধান্ত নিতে পারেন যে আপনার এক বা একাধিক কারণের সমস্ত সমন্বয় প্রয়োজন।

সুতরাং, একটি সম্ভাব্য অ্যালগরিদম হ'ল:

factor(N)
    divisor = first_prime
    list_of_factors = { 1 }
    while (N > 1)
        while (N % divisor == 0)
            add divisor to list_of_factors
            N /= divisor
        divisor = next_prime
    return list_of_factors

এরপরে উত্তরটির বাকি অংশগুলি নির্ধারণের জন্য বিষয়গুলি একত্রিত করা আপনার পক্ষে।


0

এটি এমন কিছু যা আমি জাস্টিন উত্তরের উপর ভিত্তি করে নিয়ে এসেছি। এটির জন্য কিছু অপটিমাইজেশন প্রয়োজন হতে পারে।

n=int(input())

a=[]
b=[]

def sieve(n):
    np = n + 1
    s = list(range(np)) 
    s[1] = 0
    sqrtn = int(n**0.5)
    for i in range(2, sqrtn + 1): 
        if s[i]:
            s[i*i: np: i] = [0] * len(range(i*i, np, i))
    return filter(None, s)

k=list(sieve(n))

for i in range(len(k)):
        if n%k[i]==0:
                a.append(k[i])

a.sort()

for i in range(len(a)):
        j=1
        while n%(a[i]**j)==0: 
                j=j+1
        b.append(j-1)

nod=1

for i in range(len(b)):
        nod=nod*(b[i]+1)

print('no.of divisors of {} = {}'.format(n,nod))

0

আমি মনে করি এটিই আপনি খুঁজছেন I আমি যা চেয়েছিলাম ঠিক তাই করি। এটিকে নোটপ্যাডে অনুলিপি করুন এবং এটি আটকান *

প্লিজ নোট করুন যে একটি সিএমডি ভেরিয়েবল ক্যান্ট সমর্থন করে 999999999 এর চেয়ে বেশি

@echo off

modecon:cols=100 lines=100

:start
title Enter the Number to Determine 
cls
echo Determine a number as a product of 2 numbers
echo.
echo Ex1 : C = A * B
echo Ex2 : 8 = 4 * 2
echo.
echo Max Number length is 9
echo.
echo If there is only 1 proces done  it
echo means the number is a prime number
echo.
echo Prime numbers take time to determine
echo Number not prime are determined fast
echo.

set /p number=Enter Number : 
if %number% GTR 999999999 goto start

echo.
set proces=0
set mindet=0
set procent=0
set B=%Number%

:Determining

set /a mindet=%mindet%+1

if %mindet% GTR %B% goto Results

set /a solution=%number% %%% %mindet%

if %solution% NEQ 0 goto Determining
if %solution% EQU 0 set /a proces=%proces%+1

set /a B=%number% / %mindet%

set /a procent=%mindet%*100/%B%

if %procent% EQU 100 set procent=%procent:~0,3%
if %procent% LSS 100 set procent=%procent:~0,2%
if %procent% LSS 10 set procent=%procent:~0,1%

title Progress : %procent% %%%



if %solution% EQU 0 echo %proces%. %mindet% * %B% = %number%
goto Determining

:Results

title %proces% Results Found
echo.
@pause
goto start

882161280 - 1282 বিভাজক
ডন্ডন

0

আমি অনুমান করি যে এটি এক উপযুক্ত পাশাপাশি সঠিকও হবে

script.pyton

>>>factors=[ x for x in range (1,n+1) if n%x==0] print len(factors)


0

এই লাইন বরাবর কিছু চেষ্টা করুন:

int divisors(int myNum) {
    int limit = myNum;
    int divisorCount = 0;
    if (x == 1) 
        return 1;
    for (int i = 1; i < limit; ++i) {
        if (myNum % i == 0) {
            limit = myNum / i;
            if (limit != i)
                divisorCount++;
            divisorCount++;
        }
    }
    return divisorCount;
}

-1

আমি সবচেয়ে দক্ষ পদ্ধতিটি জানি না, তবে আমি নিম্নলিখিতগুলি করতাম:

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

Work o / কাজ করা উচিত

আপনার যদি প্রয়োজন হয়, আমি আগামীকাল সিতে কিছু করতে কোডটি প্রদর্শন করতে পারি।


2
আমি বিভ্রান্ত একটি সংখ্যার বর্গমূলের চেয়ে কম সমস্ত প্রাইম গণনা করা আপনাকে এটির বিভাজক দেয় না ... প্রতিটি সংখ্যার বর্গমূলের চেয়ে কম সংখ্যক প্রধান এই সংখ্যার জন্য বিভাজক হবে না।
গ্যারেট বার্গ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.