স্ট্রিংয়ের সংখ্যা, যখন প্রতিটি অক্ষর এমনকি কয়েকবার ঘটতে পারে


9

আমি এই সমস্যার জন্য আমার খুলিটিকে কিছুক্ষণ ধরে ধাক্কা দিচ্ছি এবং এটি সত্যিই আমাকে হতাশ করতে শুরু করেছে। সমস্যা হল:

আমি অক্ষরের একটি সেট আছে, A, B, C, এবং D। দৈর্ঘ্য হওয়া nএবং প্রতিটি অক্ষর এমনকি কয়েকবার অবশ্যই উপস্থিত হতে হবে , সেই অক্ষরগুলি থেকে কতগুলি স্ট্রিং তৈরি করা যায় তা আমাকে জানাতে হবে।

উদাহরণস্বরূপ, এর উত্তর n = 24:

AA
BB
CC
DD

এর উত্তর n = 440 টি those বৈধ স্ট্রিংগুলির মধ্যে কয়েকটি হ'ল:

AAAA
AABB
CACA
DAAD
BCCB

আমি যুক্তি দিয়ে আটকে আছি আমি মনে করি এটির জন্য কোনও ডিপি সমাধান হতে পারে। ব্রুট-জোর করে আমার এই পথটি বের করা এই প্রশ্নের বাইরে নয়: সমাধানের সংখ্যা দ্রুত সংখ্যায় বেড়ে যায়।

আমি কাগজে সমস্ত ধরণের ধারণা আঁকার চেষ্টা করেছি, কোনও লাভ হয়নি। তাদের জটিলতা অনেক বড় হওয়ায় আমাকে প্রায় এই ধারণাগুলিই বাতিল করতে হয়েছিল। সমাধানটির জন্য দক্ষ হওয়া উচিত n = 10^4

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

আমাকে কি কেউ সাহায্য করতে পারবেন?


3
আপনার কি স্ট্রিংগুলি গণনা করতে হবে, বা তারের সংখ্যা গণনা করতে হবে? আপনার যদি কেবল স্ট্রিংয়ের সংখ্যা প্রয়োজন হয় তবে আপনি সম্ভবত পরিমাণটি সরাসরি গণনা করতে সংযুক্তি ব্যবহার করতে পারেন ।

@ সুমন কেবলমাত্র সম্ভাব্য স্ট্রিংয়ের সংখ্যা প্রয়োজন। তবে আমি এখানে কম্বিনেটরিটিক্স ব্যবহার করতে পারতাম বলে মনে করি না। কোনও উপায় থাকলেও, আমি নিশ্চিত যে খাঁটি গণিত দিয়ে সমস্যার সমাধান হওয়ার কথা নয় , এবং সেই কারণেই এটি করতে চান না। বা মানে কি?
ওলাভি মুস্তানোজা

2
নিশ্চিত যে আপনি কম্বিনেটর ব্যবহার করতে পারেন। দৈর্ঘ্যের এন স্ট্রিংয়ের জন্য, {এএ, বিবি, সিসি, ডিডি all এর সমস্ত সংমিশ্রণ পান} প্রতিটি সংমিশ্রণের জন্য, স্বতন্ত্র ক্রমানুসরণ পান। তারপরে প্রতিটি সংমিশ্রনের ফলাফলগুলি এক অনন্য অনুক্রমের সেটগুলিতে একত্রিত করুন। আমি কীভাবে এটি করব তা নিশ্চিত নই, প্রাথমিকভাবে স্বতন্ত্রতার সীমাবদ্ধতার কারণে, তবে আমি নিশ্চিত যে এর উপায় আছে।

@ স্নোমান আপনি কি বলতে চাইছেন তা আমি দেখতে পাচ্ছি। তবে এর জন্য কি কমপক্ষে সংমিশ্রণগুলি সংরক্ষণের প্রয়োজন হবে না? অনন্য ক্রমসংখ্যার সংখ্যা পেতে এটির প্রয়োজন হয় এবং সংমিশ্রণের সংখ্যা খুব দ্রুত বেড়ে যায় অনুপাতের মধ্যে আমি সম্ভবত সঞ্চয় করতে পারি না।
ওলভী মুস্তানোজা

1
সম্ভবত। আমি নিশ্চিতভাবে জানতে সংযোজকগুলির সাথে যথেষ্ট পারদর্শী নই। হয়তো গণিত.এসই এর সাথে কি একই প্রশ্ন আছে? আমার এখনই এটি খননের সময় নেই, তবে এটি একটি আকর্ষণীয় সমস্যা। আমি এটি সম্পর্কে চিন্তা এবং ফিরে চেক করব।

উত্তর:


5

স্বতন্ত্র অক্ষর ব্যবহার করে f(n,d)(এমনকি আপনার দৈর্ঘ্যের) দৈর্ঘ্যের ক্রমান্বনের সংখ্যা প্রদান করে একটি ফাংশন হিসাবে সেট আপ করুন ।ndd=4

পরিষ্কারভাবে f(0,d) = 1এবং f(n,1) = 1যেমন কেবলমাত্র একটির ব্যবস্থা রয়েছে যখন আপনার কেবলমাত্র একটি অক্ষর বা শূন্যস্থান রয়েছে।

এখন আনয়ন পদক্ষেপ:

dঅক্ষরগুলি ব্যবহার করে একটি বৈধ স্ট্রিং তৈরি করতে , অক্ষরগুলি ব্যবহার করে যে কোনও সংক্ষিপ্ত এমনকি দৈর্ঘ্যের স্ট্রিং নিন d-1এবং এই নতুন চরিত্রটির আরও একাধিক যোগ করে দৈর্ঘ্য পর্যন্ত করুন। বিন্যাসের সংখ্যাটি হ'ল choose(n,n_newdigits)কারণ আপনি n_newdigitনতুন অঙ্কের জন্য মোট স্ট্রিংয়ের দৈর্ঘ্যের মধ্যে জায়গা বেছে নিতে পারেন এবং বাকীগুলি মূল স্ট্রিংটি ক্রমে পূরণ করা হয়।

আর এ এ নিষ্পাপ পুনরাবৃত্তি ব্যবহার করে বাস্তবায়ন করতে, আমি তা করেছি:

f <- function(n,d)
{
  if(n==0) return(1)
  if(d==1) return(1)
  retval=0
  for (i in seq(from=0, to=n, by=2)) retval=retval+f(n-i,d-1)*choose(n,i)
  return(retval)
}

f(4,4)
# 40    

f(500,4)
# 1.339386e+300 takes about 10 secs

আপনার আগ্রহী সংখ্যার জন্য আমি ভেবেছিলাম যে দ্বিমাত্রিক অ্যারেতে সংখ্যাগুলি সংরক্ষণ করা আরও বেশি দক্ষ এবং বাড়তি d এর উপর পুনরাবৃত্তি হতে পারে তবে এটি আপনার ভাষা পছন্দের উপর নির্ভর করে।


4

মিফের উত্তর অবশ্যই মার্জিত। যেহেতু আমি আমার প্রায় শেষ করে ফেলেছি তবুও এটি সরবরাহ করি। ভাল জিনিস হ'ল আমি n = 500 :-) এর জন্য একই ফলাফল পেয়েছি

মঞ্জুরিপ্রাপ্ত বিভিন্ন অক্ষরের সংখ্যা হ'ল ডি আপনার ক্ষেত্রে ডি = 4 করুন।

এন এর স্ট্রিংয়ের দৈর্ঘ্য হোক, শেষ পর্যন্ত আপনি n এর সমান মানগুলিও দেখবেন।

আপনাকে কোনও স্ট্রিং-এ অনির্দিষ্ট অক্ষরের সংখ্যা হতে দিন।

N (n, d, u) এর দৈর্ঘ্য n এর স্ট্রিংয়ের সংখ্যা হউক, ডি থেকে আলাদা আলাদা অক্ষর থেকে তৈরি হয়ে গেছে এবং আপনাকে অক্ষত অক্ষরযুক্ত করা উচিত। এন গণনা করার চেষ্টা করুন।

পর্যবেক্ষণ করার জন্য বেশ কয়েকটি কর্নার কেস রয়েছে:

u> d বা u> n => N = 0

u <0 => এন = 0

n% 2! = u% 2 => এন = 0।

N থেকে n + 1 এ পদক্ষেপ নেওয়ার সময় আপনাকে অবশ্যই 1 বাড়াতে হবে বা 1 দ্বারা হ্রাস করতে হবে, সুতরাং আমাদের অনুসারে পুনরাবৃত্তি করতে হবে

N (n, d, u) = f (N (n-1, d, u-1), N (n-1, d, u + 1))

আপনাকে এক করে কমাতে কয়টি উপায় আছে। এটি একটি সহজ, কারণ আমাদের একটি অপ্রাপ্ত অক্ষর যুক্ত করতে হবে, যা এটি কেবল আপনার করে তোলে। সুতরাং চ এর দ্বিতীয় অংশটি (ইউ + 1) * এন (এন -1, ডি, ইউ + 1) পড়বে অবশ্যই এই সতর্কতার সাথে আমাদের অবশ্যই লক্ষ্য করতে হবে যে N = 0 যদি u + 1> n-1 বা আপনি +1 টি> ঘ।

একবার আমরা এটি বুঝতে পেরেছি, চ এর প্রথম অংশটি কী তা সহজেই দেখা যায়: যখন ইউ -১ অবিবাহিত অক্ষর রয়েছে তখন আমরা কত উপায়ে ইউ বাড়াতে পারি? ঠিক আছে, আমাদের যুক্ত করা (ক- (ইউ -১) অক্ষরের একটি বেছে নিতে হবে।

সুতরাং সমস্ত কোণার কেস বিবেচনায় নিয়ে এন এর পুনরাবৃত্তির সূত্র

N (n, d, u) = (d- (u-1)) * N (n-1, d, u-1) + (u + 1) * N (n-1, d, u + 1)

আমি কীভাবে পুনরাবৃত্তির সমাধান করবেন তা http://en.wikedia.org/wiki/Concrete_M गणিত পড়তে যাচ্ছি না ।

পরিবর্তে আমি কিছু জাভা কোড লিখেছি। আবার কিছুটা আরও আনাড়ি, যেমন জাভা তার ভারবোসিটির কারণে। তবে আমার পুনরাবৃত্তিটি ব্যবহার না করার প্রেরণা ছিল, যেহেতু এটি খুব তাড়াতাড়ি শুরু হয়ে যায়, অন্তত জাভাতে, যখন স্ট্যাকটি 500 বা 1000 বাসা বাঁধে স্তরে ভাসমান।

N = 500, d = 4 এবং u = 0 এর ফলাফল:

এন (500, 4, 0) = 1339385758982834151185531311325002263201756014631917009304687985462938813906170153116497973519619822659493341146941433531483931607115392554498072196838958545795769042788035468026048125208904713757765805163872455056995809556627183222337328039422584942896842901774597806462162357229520744881314972303360

মধ্যবর্তী ফলাফল মুখস্থ করার কারণে, 0.2 সেকেন্ডের মধ্যে গণনা করা। এন (40000,4,0) 5 সেকেন্ডেরও কমের মধ্যে গণনাগুলি। এখানে কোডও : http://ideone.com/KvB5Jv

import java.math.BigInteger;

public class EvenPairedString2 {
  private final int nChars;  // d above, number of different chars to use
  private int count = 0;
  private Map<Task,BigInteger> memo = new HashMap<>();

  public EvenPairedString2(int nChars) {
    this.nChars = nChars;
  }
  /*+******************************************************************/
  // encodes for a fixed d the task to compute N(strlen,d,unpaired).  
  private static class Task {
    public final int strlen;
    public final int unpaired;

    Task(int strlen, int unpaired) {
      this.strlen = strlen;
      this.unpaired = unpaired;
    }
    @Override
    public int hashCode() {
      return strlen*117 ^ unpaired;
    }
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof Task)) {
        return false;
      }
      Task t2 = (Task)other;
      return strlen==t2.strlen && unpaired==t2.unpaired;
    }
    @Override
    public String toString() {
      return "("+strlen+","+unpaired+")";
    }
  }
  /*+******************************************************************/
  // return corner case or memorized result or null  
  private BigInteger getMemoed(Task t) {
    if (t.strlen==0 || t.unpaired<0 || t.unpaired>t.strlen || t.unpaired>nChars
        || t.strlen%2 != t.unpaired%2) {
      return BigInteger.valueOf(0);
    }

    if (t.strlen==1) {
      return BigInteger.valueOf(nChars);
    }
    return memo.get(t);
  }

  public int getCount() {
    return count;
  }

  public BigInteger computeNDeep(Task t) {
    List<Task> stack = new ArrayList<Task>();
    BigInteger result = null;
    stack.add(t);

    while (stack.size()>0) {
      count += 1;
      t = stack.remove(stack.size()-1);
      result = getMemoed(t);
      if (result!=null) {
        continue;
      }

      Task t1 = new Task(t.strlen-1, t.unpaired+1);
      BigInteger r1 = getMemoed(t1);
      Task t2 = new Task(t.strlen-1, t.unpaired-1);
      BigInteger r2 = getMemoed(t2);
      if (r1==null) {
        stack.add(t);
        stack.add(t1);
        if (r2==null) {
          stack.add(t2);
        }
        continue;
      }
      if (r2==null) {
        stack.add(t);
        stack.add(t2);
        continue;
      }
      result = compute(t1.unpaired, r1, nChars-t2.unpaired, r2);
      memo.put(t,  result);
    }
    return result;
  }
  private BigInteger compute(int u1, BigInteger r1, int u2, BigInteger r2) {
    r1 = r1.multiply(BigInteger.valueOf(u1));
    r2 = r2.multiply(BigInteger.valueOf(u2));
    return r1.add(r2);
  }
  public static void main(String[] argv) {
    int strlen = Integer.parseInt(argv[0]);
    int nChars = Integer.parseInt(argv[1]);

    EvenPairedString2 eps = new EvenPairedString2(nChars);

    BigInteger result = eps.computeNDeep(new Task(strlen, 0));
    System.out.printf("%d: N(%d, %d, 0) = %d%n", 
                      eps.getCount(), strlen, nChars, 
                      result); 
  }
}

2

আমি একটি সমাধান নিয়ে আসার চেষ্টা করেছি তবে ব্যর্থ হয়ে গণিত.স্ট্যাকএক্সচেঞ্জে একই প্রশ্নটি জিজ্ঞাসা করেছি । কমন লিস্পে রস মেকে ধন্যবাদ , এখানে একটি সমাধান দেওয়া হয়েছে:

(defun solve (n)
  (if (evenp n)
      (/ (+ (expt 4 n) (* 4 (expt 2 n))) 8)
      0))

এর বিজোড় মানগুলির জন্য এটি সর্বদা 0 প্রদান করে n। কারণ n = 500, এসবিসিএল সহ আউটপুট এখানে রয়েছে :

* (time (solve 500))

    Evaluation took:
      0.000 seconds of real time
      0.000000 seconds of total run time (0.000000 user, 0.000000 system)
      100.00% CPU
      51,100 processor cycles
      0 bytes consed

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