জাভাতে স্ট্রিংগুলি সংযুক্ত করার সময় মেমরিতে কতটি স্ট্রিং তৈরি হয়?


17

আমাকে জাভাতে অপরিবর্তনীয় স্ট্রিং সম্পর্কে জিজ্ঞাসা করা হয়েছিল। আমাকে একটি ফাংশন লেখার দায়িত্ব দেওয়া হয়েছিল যা একটি স্ট্রিংয়ের সাথে "a" এর সংখ্যার সাথে যুক্ত ছিল।

আমি যা লিখেছি:

public String foo(int n) {
    String s = "";
    for (int i = 0; i < n; i++) {
        s = s + "a"
    }
    return s;
}

তখন আমাকে জিজ্ঞাসা করা হয়েছিল যে এই প্রোগ্রামটি কতগুলি স্ট্রিং উত্পন্ন করবে তা ধরে নিয়েই আবর্জনা সংগ্রহের ঘটনা ঘটবে না। N = 3 এর জন্য আমার চিন্তাভাবনা ছিল

  1. ""
  2. "A"
  3. "A"
  4. "এএ"
  5. "A"
  6. "AAA"
  7. "A"

মূলত লুপের প্রতিটি পুনরাবৃত্তিতে 2 টি স্ট্রিং তৈরি করা হয়। তবে উত্তরটি n 2 ছিল । এই ফাংশনটির মাধ্যমে মেমরিতে কী স্ট্রিং তৈরি হবে এবং কেন সেভাবে হয়?


15
আপনি যদি এই কাজের প্রস্তাব পান, পালিয়ে যান, খুব দ্রুত চালান .......
mattnz

@ ম্যাট্টনজ একাধিক কারণে (এবং কেবল লিখিত কোডের কারণে নয়)।

3
এটি ও (এন ^ 2) রানটাইম নেয় যতক্ষণ না জেআইটি লুপটিকে অনুকূল করে না, তবে এটি এন ^ 2 স্ট্রিং তৈরি করে না।
ব্যবহারকারী 2357112 মনিকা

উত্তর:


26

তখন আমাকে জিজ্ঞাসা করা হয়েছিল যে এই প্রোগ্রামটি কতগুলি স্ট্রিং উত্পন্ন করবে তা ধরে নিয়েই আবর্জনা সংগ্রহের ঘটনা ঘটবে না। এন = 3 এর জন্য আমার চিন্তাভাবনাগুলি ছিল (7)

স্ট্রিং 1 ( "") এবং 2 ( "a") প্রোগ্রামটির ধ্রুবক, এগুলি জিনিসগুলির অংশ হিসাবে তৈরি হয় না তবে 'অভ্যন্তরীণ' হয় কারণ সেগুলি সংকলক সম্পর্কে জেনে থাকা স্থির হয়। উইকিপিডিয়ায় স্ট্রিং ইন্টার্নিংয়ের বিষয়ে আরও পড়ুন ।

এটি "a"স্ট্রিং # 2 এর সমান হওয়ায় গণনা থেকে 5 এবং 7 টি স্ট্রিংও সরিয়ে দেয় । এটি স্ট্রিং # 3, # 4, এবং # 6 ছেড়ে দেয়। আপনার কোডটি ব্যবহার করে উত্তরটি হ'ল "3 টি স্ট্রিং এন = 3 এর জন্য তৈরি করা হয়েছে"।

N এর গণনা 2 স্পষ্টত ভুল কারণ এন = 3, এই 9 হবে এবং এমনকি আপনার সবচেয়ে খারাপ ক্ষেত্রে উত্তর, ছিল শুধুমাত্র 7. যদি আপনার অ-অন্তরীণ স্ট্রিং সঠিক ছিল দ্বারা, উত্তর করা উচিত 2n + 1 টি হয়েছে।

সুতরাং, আপনি কিভাবে এটি করা উচিত প্রশ্ন ?

স্ট্রিং যেহেতু পরিবর্তনযোগ্য, তাই আপনি একটি পরিবর্তনীয় জিনিস চাই - এমন কিছু যা আপনি নতুন অবজেক্ট তৈরি না করেই পরিবর্তন করতে পারেন। এটি স্ট্রিংবিল্ডার

প্রথম দেখার বিষয় কনস্ট্রাক্টররা। এক্ষেত্রে আমরা জানি যে স্ট্রিংটি কত দিন হবে এবং এমন একটি নির্মাতা রয়েছে StringBuilder(int capacity) যার অর্থ আমরা আমাদের প্রয়োজন হিসাবে যথাযথভাবে বরাদ্দ করি।

এর পরে, স্ট্রিং"a" হওয়ার দরকার নেই , বরং এটি একটি চরিত্র হতে পারে । বনাম কল করার সময় এটির কিছুটা ছোটখাটো পারফরম্যান্স রয়েছে - এর সাথে , পদ্ধতিটি স্ট্রিংটি কত দীর্ঘ তা খুঁজে বের করা এবং সে সম্পর্কে কিছু কাজ করা উচিত। অন্যদিকে, সর্বদা হ'ল এক অক্ষর দীর্ঘ।'a'append(String)append(char)append(String)char

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

সুতরাং, আপনি যখন এটি একসাথে রেখেছেন তখন এটি কেমন দেখাচ্ছে?

public String foo(int n) {
    StringBuilder sb = new StringBuilder(n);
    for (int i = 0; i < n; i++) {
        sb.append('a');
    }
    return sb.toString();
}

একটি স্ট্রিংবিল্ডার এবং একটি স্ট্রিং তৈরি করা হয়েছে। ইন্টার্নযুক্ত করার জন্য কোনও অতিরিক্ত স্ট্রিংয়ের প্রয়োজন নেই।


Eclipse এ আরও কিছু সাধারণ প্রোগ্রাম লিখুন। পিএমডি ইনস্টল করুন এবং আপনার লেখা কোডটিতে এটি চালান। এটি কী সম্পর্কে অভিযোগ করে তা নোট করুন এবং সেগুলি ঠিক করুন। এটির সাথে একটি লুপ + একটি স্ট্রিং পরিবর্তনের পাওয়া যেত, এবং যদি আপনি StringBuilder যে পরিবর্তিত, এটা হতো হয়তো প্রাথমিক ধারণক্ষমতা পাওয়া গিয়েছিলো, কিন্তু এটা অবশ্যই এর মধ্যে পার্থক্য ধরতে হবে .append("a")এবং.append('a')


9

প্রতিটি পুনরাবৃত্তিতে অপারেটর Stringদ্বারা একটি নতুন তৈরি করা হয় +এবং নির্ধারিত হয় s। ফিরে আসার পরে, তাদের সমস্ত কিন্তু শেষগুলি আবর্জনা-সংগৃহীত।

স্ট্রিং ধ্রুবকগুলি প্রতিবার পছন্দ করে ""এবং তৈরি "a"হয় না, এগুলি ইন্টার্নযুক্ত স্ট্রিং । যেহেতু স্ট্রিংগুলি পরিবর্তনযোগ্য নয় তাই এগুলি অবাধে ভাগ করা যায়; এটি স্ট্রিং ধ্রুবকগুলির সাথে ঘটে।

দক্ষতার CONCATENATE স্ট্রিং, ব্যবহার করা StringBuilder


সাক্ষাত্কারের লোকেরা আসলে আক্ষরিক ছিল কিনা তা নিয়ে বিতর্ক করেছিল এবং সিদ্ধান্ত নিয়েছিল যে প্রতিবার আক্ষরিক তৈরি হয়েছিল। তবে এটি আরও অর্থবোধ করে।
আহালবার্ট

6
কোনও ভাষা কী করে আপনি কীভাবে "বিতর্ক" করেন, আপনি অবশ্যই স্পেসিফিকেশনটি পড়েন এবং নিশ্চিতভাবে জানেন, বা এর সংজ্ঞা দেওয়া হয়নি এবং তাই সঠিক উত্তর নেই .....
ম্যাটনজ

@ ম্যাটনজ এটি বাস্তবায়নের বিবরণে আসে এমনকি আপনি যে সংকলক / রানটাইমটি ব্যবহার করছেন তা কী তা জেনে রাখা আকর্ষণীয় হতে পারে। এটি বিশেষত পারফরম্যান্সের ক্ষেত্রে প্রযোজ্য।
সুইভ

1
@ এসভিক: অনুমান করে আপনি প্রচুর পরিমাণে অর্জন করতে পারেন, তারপরে সংকলকটি আপগ্রেড করা হয়, একটি অনুকূলকরণ পরিবর্তিত হয় The আচরণের ফলে বাগের কারণ হয় কারণ আপনি অনির্দিষ্ট আচরণের পরিবর্তে সংজ্ঞায়িত আচরণের উপর নির্ভর করেছিলেন। অপ্টিমাইজেশন সম্পর্কে তারা কী বলেছে তা আপনি জানেন - ক) এটি বিশেষজ্ঞদের কাছে ছেড়ে দিন এবং খ) আপনার এখনও কোনও বিশেষজ্ঞ নয়। :) নির্ভরতা যদি কেবল পারফরম্যান্স ভিত্তিতে হয় তবে ভাষার স্পেসিফিকেশনে এখনও নির্ভর করে তবে আপনি কেবল পারফরম্যান্সই শিথিল করেন। অনেক সময় আমি এমন কোড দেখেছি যা অপ্রত্যাশিত বা সংকলক নির্দিষ্ট আচরণ বিরতিতে নির্ভর করেছিল অপ্রত্যাশিত উপায়ে (বেশিরভাগ সি এবং সি ++)।
mattnz

@mattnz সুতরাং আপনি কীভাবে পারফরম্যান্সের সাথে সম্পর্কিত সিদ্ধান্ত নেওয়ার প্রস্তাব করবেন? সাধারণত, স্পেসিফিকেশন / ডকুমেন্টেশন থেকে আপনি যে সেরাটি পেতে পারেন তা হ'ল বি-ও জটিলতা, তবে এটি যথেষ্ট নয়। যাই হোক না কেন, কার্য সম্পাদন সর্বদা বাস্তবায়নের উপর নির্ভর করে, তাই আমি মনে করি যে কর্মক্ষমতা আসে তখন প্রয়োগের বিবরণগুলির উপর নির্ভর করা ঠিক আছে।
সোভিক

4

মাইকেলটি যেমন তার উত্তরে ব্যাখ্যা করে, আপনার কোড ও (এন) স্ট্রিংগুলি বরাদ্দ করে। তবে এটি ও (এন 2 ) মেমরির বাইটগুলিও বরাদ্দ করে এবং ও (এন 2 ) সময়ে চলে।

এটি ও (এন 2 ) বাইটগুলি বরাদ্দ করে , কারণ আপনি যে স্ট্রিংগুলি বরাদ্দ করছেন তার দৈর্ঘ্য 0, 1, 2,…, n-1, n, যা (n 2 + n) / 2 = O (n 2 ) এর সমান ।

সময়টি ও (এন 2 ), কারণ আই-তম স্ট্রিং বরাদ্দ করার জন্য (আই -1) -তারা স্ট্রিংয়ের অনুলিপি প্রয়োজন, যার দৈর্ঘ্য আই -1 রয়েছে। এর অর্থ প্রতিটি বরাদ্দ করা বাইটের অনুলিপি করতে হবে, যা O (n 2 ) সময় নেবে take

সাক্ষাত্কার বলতে কি বোঝাতে চাইছেন?


না সমীকরণ (ঢ ^ 2 + N) / 2, কেমন হওয়া উচিত এখানে ?
হেজেড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.