স্ট্রিং ইনপ্লেসে শব্দের বিপরীত ক্রম


17

কাজটি

  • আপনার সাথে মিলে যায় এমন একটি পরিবর্তনীয় স্ট্রিং [a-z]+( [a-z]+)*
  • আপনার অবশ্যই এটিকে স্ট্রিংয়ে রূপান্তর করতে হবে যা একই শব্দগুলি রয়েছে তবে বিপরীত ক্রমে যাতে "হ্যালো ওখানে সবাই" "সেখানে সবাইকে হ্যালো" হয়ে যায়।
  • আপনি অতিরিক্ত মেমরির একটি ধ্রুবক পরিমাণের চেয়ে বেশি ব্যবহার করার অনুমতি নেই (সুতরাং আপনি কেবলমাত্র বরাদ্দ করা বাফারে পুরো স্ট্রিং বা কোনও পুরো শব্দই অনুলিপি করার প্রয়োজন নেই)।
  • কোনও সময়ের সীমাবদ্ধতা নেই। আশাহীনভাবে অদক্ষ হয়ে যাওয়া আপনার স্কোরের ক্ষতি করবে না।
  • আপনার পছন্দের ভাষা যদি স্ট্রিংয়ের পরিবর্তনের অনুমতি না দেয় তবে অক্ষরের অ্যারে গ্রহণযোগ্য বিকল্প।

তোমার ফলাফল

  • আপনার স্কোরটি স্ট্রিং উপাদানগুলিতে আপনি যে পরিমাণ দায়িত্ব তৈরি করেছেন তা নিখুঁতভাবে গণনা করা হয় (ছোট স্কোর সেরা)। আপনি যদি কোনও লাইব্রেরির ফাংশন ব্যবহার করেন যা স্ট্রিংয়ে লেখেন তবে এর লেখাগুলিও গণনা করে।
  • ধরুন বরাদ্দকরণ সংখ্যা আপনি ইনপুট জন্য প্রয়োজন গুলি হল এন (গুলি) । তারপরে আপনার স্কোরটি এন (গুলি) / দৈর্ঘ্য (গুলি) এর সমস্ত ইনপুট গুলি (উপরে উল্লিখিত রেজেক্সের সাথে মিলে ) সর্বাধিক (পেডেন্টালি সুপ্রিমাম ) । আপনি যদি এটিকে নিখুঁতভাবে গণনা করতে না পারেন তবে আপনি প্রমাণ করতে পারেন এমন সর্বনিম্ন উপরের সীমাটি ব্যবহার করতে পারেন।
  • আপনি যদি একটি টাই ভাঙ্গতে পারেন আপনি যদি প্রমাণ করতে পারেন যে আপনার অ্যালগোরিদম asympototically কম অ্যাসাইনমেন্ট ব্যবহার করে (এটি যদি আপনার একই স্কোর হয় এমনকি, নীচে দেখুন)। আপনি যদি এটি না করতে পারেন তবে আপনি অতিরিক্ত অতিরিক্ত মেমরি ব্যবহার করছেন তা দেখিয়ে টাই ভেঙে ফেলতে পারেন। তবে, প্রথম টাই-ব্রেক শর্তটি সর্বদা প্রাধান্য নেয় takes
  • কিছু ইনপুটগুলির জন্য প্রতিটি চরিত্রের পরিবর্তন হওয়া দরকার, সুতরাং 1 এর চেয়ে কম স্কোর করা সম্ভব নয়।
  • আমি স্কোর 2 সহ একটি সাধারণ অ্যালগরিদম সম্পর্কে ভাবতে পারি (তবে আমি এটিতে প্রবেশ করছি না)।

সুপ্রিমা এবং সম্পর্ক সম্পর্কিত নোটগুলি

  • সংখ্যার সংখ্যার একটি সুপ্রেম হ'ল ক্ষুদ্রতম সংখ্যা যা তাদের কোনওটির চেয়ে ছোট নয়। এটি অনেকটা সেটের সর্বাধিকের মতো, some 2/3, 3/4, 4/5, 5/6, ... some এর মতো কিছু অসীম সেটগুলির সর্বাধিক একক উপাদান নেই, তবে তারপরেও উচ্চপদ থাকবে, এই ক্ষেত্রে 1।
  • যদি আপনি আমার স্কোর 2 (বলুন) এর অ্যালগোরিদমের উপর কেবল অবিচ্ছিন্ন অ্যাসাইনমেন্টগুলি "সংরক্ষণ" করতে পরিচালনা করেন তবে আপনার স্কোরটি এখনও 2 হবে কারণ আপনি নিজের ইনপুটটি যত বড় আকারের হয়ে যান 2 এর কাছাকাছি চলে যাবেন। যাইহোক, আপনি যদি টাই-ব্রেক এ জিতেন তবে তা যদি আসে।

1
এই সমস্ত যদি তাদের স্মৃতি ব্যবহারের জন্য টাই-ব্রেকিং স্কোর -২ জমা দিতে আসে তবে আমি কিছুটা দুঃখ পাব। আমি বেশিরভাগ ক্ষেত্রে এই প্রশ্নটি অবাক করেই পোস্ট করেছিলাম যে কেউ যদি 2 এর চেয়ে কম স্কোর পরিচালনা করতে পারে তবে
বেন মিলউড

1
আমার কাছে কোনও আনুষ্ঠানিক প্রমাণ নেই, তবে আমার অন্তর্নিহিততা আমাকে বলেছে যে স্থির-স্থান সীমাবদ্ধতার সাথে, 2 এর চেয়ে ভাল করা অসম্ভব যদি আপনি কেবল স্থানের জন্য পরিবর্তনশীল ঘোষণা গণনা করেন তবে আমি প্রতারণা করতে এবং পুনরাবৃত্তি করতে পারি। তবে এটি কেবল little-omega(1)স্ট্যাকের উপরে রেখে স্থানটিকে ছদ্মবেশ দেয় ।
ভুল

2
@ ব্যাকছুবিলে হ্যাঁ, তবে এটি ক্রমাগত অতিরিক্ত স্মৃতি।
মার্টিন এন্ডার

4
আপনি যদি কঠোরভাবে নিয়মগুলি প্রয়োগ করেন তবে এই জাতীয় প্রোগ্রামটি লেখা অসম্ভব। স্ট্রিংটি নির্বিচারে দৈর্ঘ্যের হতে পারে এবং আপনার কমপক্ষে কিছু ধরণের ভেরিয়েবলের প্রয়োজন হবে যা একটি সূচক সঞ্চয় করে। সুতরাং আমি কেবল আপনার ভেরিয়েবলের সীমা অতিক্রম করতে স্ট্রিংটি যথেষ্ট দীর্ঘ করতে হবে। কমপক্ষে একটি সূচকে সফলভাবে সঞ্চয় করতে আপনার প্রয়োজনীয় মেমরি স্ট্রিং দৈর্ঘ্যের সাথে বাড়বে grow
ইচবিনকিনবাউম

3
@ আইচবিনকিনবাউম ঠিক আছে, O(1)অতিরিক্ত স্থান দিয়ে এই কাজটি করা অসম্ভব । আপনার O(log n)একটি সূচক অবস্থান সংরক্ষণ করার জন্য স্থান প্রয়োজন , যেহেতু একটি কে-বিট পূর্ণসংখ্যা কেবল তাদের মধ্যে দৈর্ঘ্যের স্ট্রিংয়ের জন্য সঞ্চয় করতে পারে 2^k। স্ট্রিংয়ের দৈর্ঘ্য সীমাবদ্ধ করা চ্যালেঞ্জকে বরং অর্থহীন করে তোলে, যেহেতু প্রতিটি অ্যালগরিদমকে O(1)এইভাবে স্থানের প্রয়োজন হবে ।
ডেনিস

উত্তর:


4

পাইথন, স্কোর: 2 1.5 1.25

এটি প্রিমোর উত্তর এবং আমার উত্তরের মধ্যে সরাসরি সংমিশ্রণ। তাই ক্রেডিটও তাকে!

প্রমাণটি এখনও চলছে, তবে এখানে কোডটি খেলতে হবে! আপনি যদি ১.২৫ এর চেয়ে বেশি স্কোরের একটি পাল্টা উদাহরণ খুঁজে পেতে পারেন (বা যদি কোনও বাগ থাকে) তবে আমাকে জানান!

বর্তমানে সবচেয়ে খারাপ পরিস্থিতি হ'ল:

আ ... এএ ডিসিবি ... সিবিডি

যেখানে "a", "b", "c", এবং "" (স্পেস) অক্ষরগুলির ঠিক এন থাকে এবং ঠিক দুটি "d" গুলি থাকে। স্ট্রিংয়ের দৈর্ঘ্য 4n + 2 এবং অ্যাসাইনমেন্টের সংখ্যা 5n + 2 , 5/4 = 1.25 এর স্কোর দেয় ।

অ্যালগরিদম দুটি ধাপে কাজ করে:

  1. এই kযে এই ধরনের string[k]এবং string[n-1-k]শব্দ সীমা রয়েছে
  2. অ্যালগরিদমকে বিপরীত করে কোনও শব্দ চালান string[:k]+string[n-1-k:](অর্থাত্ প্রথম kএবং শেষ kঅক্ষরের সংক্ষিপ্তকরণ) ছোট সংশোধন করে।

nস্ট্রিং দৈর্ঘ্য যেখানে ।

উন্নতি এই অ্যালগরিদম দেয় পদক্ষেপ 2. মধ্যে "ছোট পরিবর্তন" থেকে আসে এটি মূলত যে জ্ঞান যোগসূত্র স্ট্রিং, অবস্থানে অক্ষর kএবং k+1শব্দ সীমানা (যা মানে তারা একটি শব্দ স্পেস বা প্রথম / শেষ চরিত্র হয়) হয়, এবং তাই আমরা সরাসরি অক্ষর অবস্থানে প্রতিস্থাপন করতে পারেন kএবং k+1চূড়ান্ত স্ট্রিং সংশ্লিষ্ট অক্ষর দিয়ে, কয়েক বরাদ্দকরণ সংরক্ষণ। এটি হোস্ট ওয়ার্ড-রিভার্সাল অ্যালগরিদম থেকে সবচেয়ে খারাপ কেসটি সরিয়ে দেয়

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

কোডটি "কনকেনটেটেড" স্ট্রিংয়ে বিপরীত অ্যালগরিদম শব্দটি চালানোর ক্ষেত্রে এই চারটি কেস পরিচালনা করতে দীর্ঘতর:

  1. কখন kপাওয়া যায় না ( f_long = -2)
  2. কখন string[k] != ' ' and string[n-1-k] != ' '( f_long = 0)
  3. কখন string[k] != ' ' and string[n-1-k] == ' '( f_long = 1)
  4. কখন string[k] == ' ' and string[n-1-k] != ' '( f_long = -1)

আমি নিশ্চিত যে কোডটি ছোট করা যেতে পারে। বর্তমানে এটি দীর্ঘ কারণ আমার শুরুতে পুরো অ্যালগরিদমের সুস্পষ্ট ছবি ছিল না। আমি নিশ্চিত যে এটি একটি সংক্ষিপ্ত কোডে উপস্থাপনের জন্য ডিজাইন করতে পারে =)

নমুনা রান (প্রথমটি আমার, দ্বিতীয়টি প্রিমোর):

স্ট্রিং প্রবেশ করান: একটি বিসি ডিএফ গিজ
"গিজ ডিএফ বিসি এ": 9, 13, 0.692
"গিজ ডিএফ বিসি এ": 9, 13, 0.692
স্ট্রিং প্রবেশ করান: ab cdefghijklmnopqrstuvw xyz
"zyxwvutsrqponMLkjihgf edc ab": 50, 50, 1.000
"zyxwvutsrqponMLkjihgf edc ab": 51, 50, 1.020
স্ট্রিং প্রবেশ করুন: abcdefg hijklmnopqrstuvwx
"hijklmnopqrstuvwx gfedcb a": 38, 31, 1.226
"hijklmnopqrstuvwx gfedcb a": 38, 31, 1.226
স্ট্রিংটি প্রবেশ করান: একটি বিসি ডি এফজি হাই জে কে এলএম নো পিক আরএস টু ভিডাব্লু এক্সওয়াই জেডি
"জেডিসি এক্স ভি ভি টু আরএসপিউ নো এলএম জে কে হি এফজি ডি বিসি এ": 46, 40, 1.150
"জেডিসি এক্স ভি ভি টু আরএসপিউ নো এলএম জে কে হি এফজি ডি বিসি এ": 53, 40, 1.325
স্ট্রিং লিখুন: aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa dcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbd
"Dcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbd aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa একটি": 502, 402, 1,249
"Dcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbd aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa একটি": 502, 402, 1,249

আপনি দেখতে পাচ্ছেন যে তৃতীয় উদাহরণের হোস্ট ওয়ার্ড-রিভার্সাল অ্যালগরিদমের সবচেয়ে খারাপ ক্ষেত্রে ব্যতীত স্কোর প্রায় একই রকম, যার জন্য আমার পদ্ধতির ১.২৫ এরও কম স্কোর পাওয়া যায়

DEBUG = False

def find_new_idx(string, pos, char, f_start, f_end, b_start, b_end, f_long):
    if DEBUG: print 'Finding new idx for s[%d] (%s)' % (pos, char)
    if f_long == 0:
        f_limit = f_end-1
        b_limit = b_start
    elif f_long == 1:
        f_limit = f_end-1
        b_limit = b_start+1
    elif f_long == -1:
        f_limit = f_end-2
        b_limit = b_start
    elif f_long == -2:
        f_limit = f_end
        b_limit = b_start

    if (f_start <= pos < f_limit or b_limit < pos < b_end) and char == ' ':
        word_start = pos
        word_end = pos+1
    else:
        if pos < f_limit+1:
            word_start = f_start
            if DEBUG: print 'Assigned word_start from f_start (%d)' % f_start
        elif pos == f_limit+1:
            word_start = f_limit+1
            if DEBUG: print 'Assigned word_start from f_limit+1 (%d)' % (f_limit+1)
        elif b_limit <= pos:
            word_start = b_limit
            if DEBUG: print 'Assigned word_start from b_limit (%d)' % b_limit
        elif b_limit-1 == pos:
            word_start = b_limit-1
            if DEBUG: print 'Assigned word_start from b_limit-1 (%d)' % (b_limit-1)
        i = pos
        while f_start <= i <= f_limit or 0 < b_limit <= i < b_end:
            if i==f_limit or i==b_limit:
                cur_char = 'a'
            elif i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ':
                word_start = i+1
                if DEBUG: print 'Assigned word_start from loop'
                break
            i -= 1

        if b_limit <= pos:
            word_end = b_end
            if DEBUG: print 'Assigned word_end from b_end (%d)' % b_end
        elif b_limit-1 == pos:
            word_end = b_limit
            if DEBUG: print 'Assigned word_end from b_limit (%d)' % (b_limit)
        elif pos < f_limit+1:
            word_end = f_limit+1
            if DEBUG: print 'Assigned word_end from f_limit+1 (%d)' % (f_limit+1)
        elif pos == f_limit+1:
            word_end = f_limit+2
            if DEBUG: print 'Assigned word_end from f_limit+2 (%d)' % (f_limit+2)
        i = pos
        while f_start <= i <= f_limit or 0 < b_limit <= i < b_end:
            if i==f_limit or i==b_limit:
                cur_char = 'a'
            elif i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ':
                word_end = i
                if DEBUG: print 'Assigned word_end from loop'
                break
            i += 1
    if DEBUG: print 'start, end: %d, %d' % (word_start, word_end)
    word_len = word_end - word_start
    offset = word_start-f_start
    result = (b_end-offset-(word_end-pos)) % b_end
    if string[result] == ' ' and (b_start == -1 or result not in {f_end-1, b_start}):
        return len(string)-1-result
    else:
        return result

def process_loop(string, start_idx, f_start, f_end, b_start, b_end=-1, f_long=-2, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    count = 0
    while pos != start_idx or not processed_something:
        count += 1
        if DEBUG and count > 20:
            print '>>>>>Break!<<<<<'
            break
        new_pos = find_new_idx(string, pos, tmp, f_start, f_end, b_start, b_end, f_long)
        if DEBUG:
            if dry_run:
                print 'Test:',
            else:
                print '\t',
            print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif pos == new_pos:
            break
        elif tmp == string[new_pos]:
            pass
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def reverse(string, f_start, f_end, b_start, b_end=-1, f_long=-2):
    if DEBUG: print 'reverse: %d %d %d %d %d' % (f_start, f_end, b_start, b_end, f_long)
    if DEBUG: print
    if DEBUG: print ''.join(string)
    assignments = 0
    n = len(string)
    if b_start == -1:
        for i in range(f_start, f_end):
            if string[i] == ' ':
                continue
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, -1, f_end, dry_run=i) for j in range(f_start, i) if string[j] != ' '):
                continue
            if DEBUG:
                print
                print 'Finished test'
            assignments += process_loop(string, i, f_start, f_end, -1, f_end)
            if DEBUG: print
            if DEBUG: print ''.join(string)
        for i in range(f_start, (f_start+f_end-1)/2):
            if (string[i] == ' ' and string[n-1-i] != ' ') or (string[i] != ' ' and string[n-1-i] == ' '):
                string[i], string[n-1-i] = string[n-1-i], string[i]
                assignments += 2
    else:
        for i in range(f_start, f_end)+range(b_start, b_end):
            if string[i] == ' ' and i not in {f_end-1, b_start}:
                continue
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, b_start, b_end, f_long, i) for j in range(f_start, f_end)+range(b_start, b_end) if j<i and (string[j] != ' ' or j in {f_end-1, b_start})):
                continue
            assignments += process_loop(string, i, f_start, f_end, b_start, b_end, f_long)
            if DEBUG: print
            if DEBUG: print ''.join(string)
        for i in range(f_start, f_end-1):
            if (string[i] == ' ' and string[n-1-i] != ' ') or (string[i] != ' ' and string[n-1-i] == ' '):
                string[i], string[n-1-i] = string[n-1-i], string[i]
                assignments += 2
    return assignments

class SuperList(list):
    def index(self, value, start_idx=0):
        try:
            return self[:].index(value, start_idx)
        except ValueError:
            return -1

    def rindex(self, value, end_idx=-1):
        end_idx = end_idx % (len(self)+1)
        try:
            result = end_idx - self[end_idx-1::-1].index(value) - 1
        except ValueError:
            return -1
        return result

def min_reverse(string):
    assignments = 0
    lower = 0
    upper = len(string)
    while lower < upper:
        front = string.index(' ', lower) % (upper+1)
        back = string.rindex(' ', upper)
        while abs(front-lower - (upper-1-back)) > 1 and front < back:
            if front-lower < (upper-1-back):
                front = string.index(' ', front+1) % (upper+1)
            else:
                back = string.rindex(' ', back)
            if DEBUG: print lower, front, back, upper
        if front > back:
            break
        if DEBUG: print lower, front, back, upper
        if abs(front-lower - (upper-1-back)) > 1:
            assignments += reverse(string, lower, upper, -1)
            lower = upper
        elif front-lower < (upper-1-back):
            assignments += reverse(string, lower, front+1, back+1, upper, -1)
            lower = front+1
            upper = back+1
        elif front-lower > (upper-1-back):
            assignments += reverse(string, lower, front, back, upper, 1)
            lower = front
            upper = back
        else:
            assignments += reverse(string, lower, front, back+1, upper, 0)
            lower = front+1
            upper = back
    return assignments

def minier_find_new_idx(string, pos, char):
    n = len(string)
    try:
        word_start = pos - next(i for i, char in enumerate(string[pos::-1]) if char == ' ') + 1
    except:
        word_start = 0
    try:
        word_end = pos + next(i for i, char in enumerate(string[pos:]) if char == ' ')
    except:
        word_end = n
    word_len = word_end - word_start
    offset = word_start
    result = (n-offset-(word_end-pos))%n
    if string[result] == ' ':
        return n-result-1
    else:
        return result

def minier_process_loop(string, start_idx, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    while pos != start_idx or not processed_something:
        new_pos = minier_find_new_idx(string, pos, tmp)
        #print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if pos == new_pos:
            break
        elif dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif tmp == string[new_pos]:
            pass
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def minier_reverse(string):
    assignments = 0
    for i in range(len(string)):
        if string[i] == ' ':
            continue
        if any(minier_process_loop(string, j, dry_run=i) for j in range(i) if string[j] != ' '):
            continue
        assignments += minier_process_loop(string, i)
    n = len(string)
    for i in range(n/2):
        if string[i] == ' ' and string[n-i-1] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
        elif string[n-i-1] == ' ' and string[i] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
    return assignments

def main():
    while True:
        str_input = raw_input('Enter string: ')
        string = SuperList(str_input)
        result = min_reverse(string)
        n = len(string)
        print '"%s": %d, %d, %.3f' % (''.join(string), result, n, 1.0*result/n)
        string = SuperList(str_input)
        result2 = minier_reverse(string)
        print '"%s": %d, %d, %.3f' % (''.join(string), result2, n, 1.0*result2/n)

if __name__ == '__main__':
    main()

পাইথন, স্কোর: 1.5

সূত্রের মাধ্যমে অ্যাসাইনমেন্টের সঠিক সংখ্যাটি প্রায় অনুমান করা যায়:

n <= 1.5 * দৈর্ঘ্য (স্ট্রিং)

সবচেয়ে খারাপ অবস্থা হচ্ছে:

abcdefghi jklmnopqrstuvwxyzzz

37 স্ট্রিংয়ের সাথে 55 এসাইনমেন্টের সাথে দৈর্ঘ্য 37।

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

উদাহরণস্বরূপ, পূর্ববর্তী সবচেয়ে খারাপ ক্ষেত্রে:

AB | AB | গ

আমরা প্রথমে "আব" এবং "সি" (4 অ্যাসাইনমেন্ট) এর উপরে শব্দটি বিপরীত করব:

গ | AB | AB

আমরা জানি যে সীমানায় এটি স্থান ছিল (হ্যান্ডেল করার জন্য অনেকগুলি কেস রয়েছে, তবে আপনি এটি করতে পারেন), তাই আমাদের সীমানায় স্থানটি এনকোড করার দরকার নেই, এটি পূর্ববর্তী অ্যালগরিদম থেকে মূল উন্নতি is ।

তারপরে অবশেষে আমরা পেতে মাঝারি চারটি অক্ষরটিতে দৌড়েছি:

সিবিএ আব

মোট 8 টি কার্যভারে, সমস্ত 8 টি অক্ষর পরিবর্তিত হওয়ায় এই মামলার অনুকূল।

এটি পূর্ববর্তী অ্যালগরিদমের সবচেয়ে খারাপ কেসটি সরিয়ে দেয় কারণ আগের অ্যালগরিদমের সবচেয়ে খারাপ কেসটি নির্মূল করা হয়।

কিছু নমুনা রান দেখুন (এবং @ প্রিমোর উত্তরটির সাথে তুলনা করুন - এটি দ্বিতীয় লাইন):

স্ট্রিং প্রবেশ করান: আমি কিছু করতে পারি
"আমি কিছু করতে পারি": 20, 17
"আমি কিছু করতে পারি": 17, 17
স্ট্রিং প্রবেশ করুন: abcdef ghijklmnopqrs
"ghijklmnopqrs fedcb a": 37, 25
"ghijklmnopqrs fedcb a": 31, 25
স্ট্রিং প্রবেশ করুন: abcdef ghijklmnopqrst
"ghijklmnopqrst fedcb a": 38, 26
"ghijklmnopqrst fedcb a": 32, 26
স্ট্রিং প্রবেশ করুন: abcdefghi jklmnozzzzzzzzzzzzzzzzz
"jklmnozzzzzzzzzzzzzzzzz ihgfedcb a": 59, 41
"jklmnozzzzzzzzzzzzzzzzz ihgfedcb a": 45, 41
স্ট্রিং প্রবেশ করুন: abcdefghi jklmnopqrstuvwxyzzz
"jklmnopqrstuvwxyzzz ihgfedcb a": 55, 37
"jklmnopqrstuvwxyzzz ihgfedcb a": 45, 37
স্ট্রিং প্রবেশ করুন: আব আববাববাবাক
"কাবাববাববা আব": 30, 30
"কাবাববাববা আব": 31, 30
স্ট্রিং প্রবেশ করান: আব আববাববাবস
"সিবাবাবাবাবা আব": 32, 32
"সিবাবাবাবাবা আব": 33, 32
স্ট্রিং প্রবেশ করুন: abc d abc
"abc d abc": 0, 9
"abc d abc": 0, 9
স্ট্রিং প্রবেশ করুন: abc dca
"এসিডি এবিসি": 6, 9
"এসিডি এবিসি": 4, 9
স্ট্রিং প্রবেশ করুন: abc ababababababc
"সিবাবাববাবা এবিসি": 7, 29
"সিবাবাববাবা এবিসি": 5, 29

প্রিমোর উত্তরটি সাধারণত ভাল তবে কিছু ক্ষেত্রে আমার 1 পয়েন্ট সুবিধা থাকতে পারে =)

এছাড়াও তার কোডটি আমার চেয়ে অনেক ছোট ha

DEBUG = False

def find_new_idx(string, pos, char, f_start, f_end, b_start, b_end, f_long):
    if DEBUG: print 'Finding new idx for s[%d] (%s)' % (pos, char)
    if f_long == 0:
        f_limit = f_end-1
        b_limit = b_start
    elif f_long == 1:
        f_limit = f_end-1
        b_limit = b_start+1
    elif f_long == -1:
        f_limit = f_end-2
        b_limit = b_start
    elif f_long == -2:
        f_limit = f_end
        b_limit = b_start

    if (f_start <= pos < f_limit or b_limit < pos < b_end) and (char == ' ' or char.isupper()):
        word_start = pos
        word_end = pos+1
    else:
        if pos < f_limit+1:
            word_start = f_start
            if DEBUG: print 'Assigned word_start from f_start (%d)' % f_start
        elif pos == f_limit+1:
            word_start = f_limit+1
            if DEBUG: print 'Assigned word_start from f_limit+1 (%d)' % (f_limit+1)
        elif b_limit <= pos:
            word_start = b_limit
            if DEBUG: print 'Assigned word_start from b_limit (%d)' % b_limit
        elif b_limit-1 == pos:
            word_start = b_limit-1
            if DEBUG: print 'Assigned word_start from b_limit-1 (%d)' % (b_limit-1)
        i = pos
        if not (i < f_limit and b_limit < i):
            i -= 1
        while f_start <= i < f_limit or 0 < b_limit < i < b_end:
            if i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ' or cur_char.isupper():
                word_start = i+1
                if DEBUG: print 'Assigned word_start from loop'
                break
            i -= 1

        if b_limit <= pos:
            word_end = b_end
            if DEBUG: print 'Assigned word_end from b_end (%d)' % b_end
        elif b_limit-1 == pos:
            word_end = b_limit
            if DEBUG: print 'Assigned word_end from b_limit (%d)' % (b_limit)
        elif pos < f_limit+1:
            word_end = f_limit+1
            if DEBUG: print 'Assigned word_end from f_limit+1 (%d)' % (f_limit+1)
        elif pos == f_limit+1:
            word_end = f_limit+2
            if DEBUG: print 'Assigned word_end from f_limit+2 (%d)' % (f_limit+2)
        i = pos
        if not (i < f_limit and b_limit < i):
            i += 1
        while f_start <= i < f_limit or 0 < b_limit < i < b_end:
            if i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ' or cur_char.isupper():
                word_end = i
                if DEBUG: print 'Assigned word_end from loop'
                break
            i += 1
    if DEBUG: print 'start, end: %d, %d' % (word_start, word_end)
    word_len = word_end - word_start
    offset = word_start-f_start
    return (b_end-offset-(word_end-pos)) % b_end

def process_loop(string, start_idx, f_start, f_end, b_start, b_end=-1, f_long=-2, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    count = 0
    while pos != start_idx or not processed_something:
        count += 1
        if count > 20:
            if DEBUG: print 'Break!'
            break
        new_pos = find_new_idx(string, pos, tmp, f_start, f_end, b_start, b_end, f_long)
        #if dry_run:
        #    if DEBUG: print 'Test:',
        if DEBUG: print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if pos == new_pos:
            break
        elif dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif tmp == string[new_pos]:
            pass
        elif tmp == ' ':
            if b_start!=-1 and new_pos in {f_end-1, b_start}:
                tmp, string[new_pos] = string[new_pos], tmp
            else:
                tmp, string[new_pos] = string[new_pos], '@'
            assignments += 1
        elif string[new_pos] == ' ':
            if b_start!=-1 and new_pos in {f_end-1, b_start}:
                tmp, string[new_pos] = string[new_pos], tmp
            else:
                tmp, string[new_pos] = string[new_pos], tmp.upper()
            assignments += 1
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def reverse(string, f_start, f_end, b_start, b_end=-1, f_long=-2):
    if DEBUG: print 'reverse: %d %d %d %d %d' % (f_start, f_end, b_start, b_end, f_long)
    if DEBUG: print
    if DEBUG: print ''.join(string)
    assignments = 0
    if b_start == -1:
        for i in range(f_start, (f_start+f_end)/2):
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, -1, f_end, dry_run=i) for j in range(f_start, i)):
                continue
            assignments += process_loop(string, i, f_start, f_end, -1, f_end)
            if DEBUG: print
            if DEBUG: print ''.join(string)
    else:
        for i in range(f_start, f_end):
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, b_start, b_end, f_long, i) for j in range(f_start, i)):
                continue
            assignments += process_loop(string, i, f_start, f_end, b_start, b_end, f_long)
            if DEBUG: print
            if DEBUG: print ''.join(string)
    for i in range(len(string)):
        if string[i] == '@':
            string[i] = ' '
            assignments += 1
        if string[i].isupper():
            string[i] = string[i].lower()
            assignments += 1
    return assignments

class SuperList(list):
    def index(self, value, start_idx=0):
        try:
            return self[:].index(value, start_idx)
        except ValueError:
            return -1

    def rindex(self, value, end_idx=-1):
        end_idx = end_idx % (len(self)+1)
        try:
            result = end_idx - self[end_idx-1::-1].index(value) - 1
        except ValueError:
            return -1
        return result

def min_reverse(string):
    # My algorithm
    assignments = 0
    lower = 0
    upper = len(string)
    while lower < upper:
        front = string.index(' ', lower) % (upper+1)
        back = string.rindex(' ', upper)
        while abs(front-lower - (upper-1-back)) > 1 and front < back:
            if front-lower < (upper-1-back):
                front = string.index(' ', front+1) % (upper+1)
            else:
                back = string.rindex(' ', back)
            if DEBUG: print lower, front, back, upper
        if front > back:
            break
        if DEBUG: print lower, front, back, upper
        if abs(front-lower - (upper-1-back)) > 1:
            assignments += reverse(string, lower, upper, -1)
            lower = upper
        elif front-lower < (upper-1-back):
            assignments += reverse(string, lower, front+1, back+1, upper, -1)
            lower = front+1
            upper = back+1
        elif front-lower > (upper-1-back):
            assignments += reverse(string, lower, front, back, upper, 1)
            lower = front
            upper = back
        else:
            assignments += reverse(string, lower, front, back+1, upper, 0)
            lower = front+1
            upper = back
    return assignments

def minier_find_new_idx(string, pos, char):
    n = len(string)
    try:
        word_start = pos - next(i for i, char in enumerate(string[pos::-1]) if char == ' ') + 1
    except:
        word_start = 0
    try:
        word_end = pos + next(i for i, char in enumerate(string[pos:]) if char == ' ')
    except:
        word_end = n
    word_len = word_end - word_start
    offset = word_start
    result = (n-offset-(word_end-pos))%n
    if string[result] == ' ':
        return n-result-1
    else:
        return result

def minier_process_loop(string, start_idx, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    while pos != start_idx or not processed_something:
        new_pos = minier_find_new_idx(string, pos, tmp)
        #print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if pos == new_pos:
            break
        elif dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif tmp == string[new_pos]:
            pass
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def minier_reverse(string):
    # primo's answer for comparison
    assignments = 0
    for i in range(len(string)):
        if string[i] == ' ':
            continue
        if any(minier_process_loop(string, j, dry_run=i) for j in range(i) if string[j] != ' '):
            continue
        assignments += minier_process_loop(string, i)
    n = len(string)
    for i in range(n/2):
        if string[i] == ' ' and string[n-i-1] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
        elif string[n-i-1] == ' ' and string[i] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
    return assignments

def main():
    while True:
        str_input = raw_input('Enter string: ')
        string = SuperList(str_input)
        result = min_reverse(string)
        print '"%s": %d, %d' % (''.join(string), result, len(string))
        string = SuperList(str_input)
        result2 = minier_reverse(string)
        print '"%s": %d, %d' % (''.join(string), result2, len(string))

if __name__ == '__main__':
    main()

পাইথন, স্কোর: asympototically 2, সাধারণ ক্ষেত্রে খুব কম

পুরানো কোড স্থান সীমাবদ্ধতার কারণে সরানো হয়েছে

ধারণা প্রতিটি সূচক মাধ্যমে পুনরুক্তি করতে, এবং প্রতিটি সূচির জন্য i, আমরা চরিত্র নিয়ে নতুন অবস্থান নিরূপণ j, অবস্থানে চরিত্র মুখস্থ jএ চরিত্র নির্ধারণ iকরতে jসূচিতে অক্ষর দিয়ে, এবং পুনরাবৃত্তি j। যেহেতু নতুন অবস্থান গণনা করার জন্য আমাদের স্থানের তথ্য দরকার, তাই আমি পুরানো স্থানটিকে নতুন চিঠির বড় আকারের সংস্করণ হিসাবে এবং নতুন স্থানটিকে '@' হিসাবে এনকোড করি।


যদি আপনি স্ট্রিংয়ের দৈর্ঘ্যের দিক থেকে খারাপ অবস্থার শব্দের সংখ্যা হ্রাস করতে পারেন (বলুন, length(string)/3প্রতিটি শব্দকে জোর করে সবচেয়ে খারাপ অবস্থায় কমপক্ষে দৈর্ঘ্য 2 কমপক্ষে 2 করা যেতে পারে), তবে স্কোরটি কম হবে 2 (উপরের উদাহরণে এটি হবে 1.67)
জাস্টহেল্ফ

1
আমি আমার সাথে একটি সোয়াপ কাউন্টার যুক্ত করেছি; আপনার প্রকৃতপক্ষে সবচেয়ে খারাপ ক্ষেত্রে (তবে সাধারণ ক্ষেত্রে নয়) আমার জন্য মারধর করে। এটি ঠিক করার কোনও উপায় খুঁজে বের করা দরকার;)
প্রিমো

লাইন 127: if any(process_loop(...) for j in range(...))এই প্রক্রিয়া লুপ থেকে অ্যাসাইনমেন্ট গণনা করা প্রয়োজন হবে না?
primo

এটি কোনও অ্যাসাইনমেন্ট করে না। যদি আপনি দেখতে পান তবে dry_runপ্যারামিটারটি অ-শূন্যে সেট করা হয়েছে (মানটি i)। এর ভিতরে process_loop, যদি dry_runশূন্য হয় না তবে এটি কোনও কার্য সম্পাদন করবে না।
জাস্টহেল্ফ

1
আমার মনে হয় আমার এখন আরও ভাল ছবি আছে। অপরিহার্যভাবে, উভয়ের পক্ষে সবচেয়ে খারাপ পরিস্থিতি দূর করার জন্য, দুটি সবচেয়ে খারাপ পদ্ধতির দুটি পৃথক পদ্ধতি একত্রিত করা হয়। আমি এটা পছন্দ করি. আমি সাধারণভাবে মনে করি, এটি গ্রহণের জন্য সর্বোত্তম পন্থা হতে পারে, যদিও মনে হয় সম্ভবত দু'টি (বা আরও) সম্পূর্ণ ভিন্ন পদ্ধতির একত্রিত হতে পারে নিকৃষ্টতম পরিস্থিতি আরও কমিয়ে আনতে।
প্রিমো

14

পার্ল, স্কোর 1.3̅

প্রতিটি অ-স্পেস ক্যারেক্টারের জন্য একটি অ্যাসাইনমেন্ট করা হয় এবং প্রতিটি স্পেস ক্যারেক্টারের জন্য দুটি অ্যাসাইনমেন্ট দেওয়া হয়। যেহেতু স্পেস অক্ষরগুলি মোট অক্ষরের সংখ্যার অর্ধেকের বেশি হতে পারে না, তাই সবচেয়ে খারাপের স্কোর 1.5

অ্যালগরিদম পরিবর্তন হয়নি, তবে আমি নীচের অংশের উপরের প্রান্তটি প্রমাণ করতে পারি। আসুন দুটি পর্যবেক্ষণ করি:

  1. স্পেসগুলি থেকে সরাসরি জুড়ে ফাঁকা স্থানগুলিকে অদলবদল করার দরকার নেই।
  2. স্পেসগুলি থেকে সরাসরি একক অক্ষরের শব্দগুলি মূল পর্বের সময় অদলবদল করা হয় না, তবে কেবল একবারে শেষ হয়।

তারপরে এটি দেখা যায় যে তাত্ত্বিক 'সবচেয়ে খারাপ ক্ষেত্রে' তাত্পর্যপূর্ণভাবে 1/2 স্পেসের সাথে মোটেও খারাপ পরিস্থিতি নয়: ab c d e f g h i ...

$ echo ab c d e f g h i j k l m n o p q r s t u v w x y z|perl reverse-inplace.pl
z y x w v u t s r q p o n m l k j i h g f e d c ab
swaps: 51; len: 50
ratio: 1.02

আসলে, এটি বেশ ভাল ক্ষেত্রে।

উপরের এক এবং দু'টি পর্যবেক্ষণ রোধ করার জন্য, প্রতিটি এক-বর্ণের শব্দের তিন বা ততোধিক অক্ষরের মধ্যবর্তী স্থানে প্রতিস্থাপন করা প্রয়োজন। এটি অসম্পূর্ণভাবে 1/3 স্পেস সহ একটি নিকৃষ্টতম পরিস্থিতি প্রস্তাব করবে:a bcd a bcd a ... bc

$ echo a bcd a bcd a bcd a bcd a bcd a bc|perl reverse-inplace.pl
bc a bcd a bcd a bcd a bcd a bcd a
swaps: 45; len: 34
ratio: 1.32352941176471

বা সমতুল্য, কেবলমাত্র দুটি চরিত্রের শব্দ: a bc de fg hi jk ...

$ echo a bc de fg hi jk lm no pq rs tu vx xy|perl reverse-inplace.pl
xy vx tu rs pq no lm jk hi fg de bc a
swaps: 49; len: 37
ratio: 1.32432432432432

কারণ সবচেয়ে খারাপ ক্ষেত্রে এসিম্পটোটিকভাবে 1/3 স্পেস রয়েছে, সবচেয়ে খারাপ ক্ষেত্রে স্কোর হয়ে 1.3

#!perl -l
use warnings;

$words = <>;
chomp($words);
$len = length($words);
$words .= ' ';
$spaces = 0;
# iterate over the string, count the spaces
$spaces++ while $words =~ m/ /g;

$origin = 0;
$o = vec($words, $origin, 8);
$cycle_begin = $origin;
$swaps = 0;

# this possibly terinates one iteration early,
# if the last char is a one-cycle (i.e. moves to its current location)
# one-cycles previous to the last are iterated, but not swapped.
while ($i++ < $len - $spaces || !$was_cycle) {
  $w_start = rindex($words, ' ', $origin);
  $w_end = index($words, ' ', $origin);
  $pos = ($origin - $w_start) - 1;
  $target = $len - ($w_end - $pos);
  $t = vec($words, $target, 8);

  if ($t == 32) {
    $target = $len - $target - 1;
    $t = vec($words, $target, 8);
  }

  # char is already correct, possibly a one-cycle
  if ($t != $o) {
    $swaps += 1;
    vec($words, $target, 8) = $o;
  }

  $origin = $target;
  $o = $t;
  if ($origin == $cycle_begin) {
    if ($i < $len - $spaces) {
      # backtrack through everything we've done up to this point
      # to find the next unswapped char ...seriously.
      $origin += 1;
      if (vec($words, $origin, 8) == 32) {
        $origin += 1;
      }
      $bt_origin = 0;
      $bt_cycle_begin = 0;
      while ($bt_cycle_begin < $origin) {
        $w_start = rindex($words, ' ', $bt_origin);
        $w_end = index($words, ' ', $bt_origin);
        $pos = ($bt_origin - $w_start) - 1;
        $target = $len - ($w_end - $pos);
        $t = vec($words, $target, 8);

        if ($t == 32) {
          $target = $len - $target - 1;
          $t = vec($words, $target, 8);
        }

        if ($target == $bt_cycle_begin) {
          $bt_origin = ++$bt_cycle_begin;
          if (vec($words, $bt_origin, 8) == 32) {
            $bt_origin = ++$bt_cycle_begin;
          }
        } else {
          $bt_origin = $target;
        }

        if ($target == $origin) {
          $origin += 1;
          if (vec($words, $origin, 8) == 32) {
            $origin += 1;
          }
          $bt_origin = $bt_cycle_begin = 0;
        }
      }
    }

    $cycle_begin = $origin;
    $o = vec($words, $origin, 8);
    $was_cycle = 1;
  } else {
    $was_cycle = 0;
  }
}

for $i (0..$len/2-1) {
  $mirror = $len - $i - 1;
  $o = vec($words, $i, 8);
  $m = vec($words, $mirror, 8);
  # if exactly one is a space...
  if (($o == 32) ^ ($m == 32)) {
    $swaps += 2;
    vec($words, $mirror, 8) = $o;
    vec($words, $i, 8) = $m;
  }
}

chop($words);
print $words;
print "swaps: $swaps; len: $len";
print 'ratio: ', $swaps/$len;

সম্পাদনা: একটি সোয়াপ কাউন্টার এবং অনুপাত যুক্ত হয়েছে।

স্ট্যান্ডিন থেকে ইনপুট নেওয়া হয়। নমুনা ব্যবহার:

$ echo where in the world is carmen sandiego|perl reverse-inplace.pl
sandiego carmen is world the in where
swaps: 35; len: 37
ratio: 0.945945945945946

পদ্ধতি

শুরু করার জন্য, স্ট্রিংয়ের প্রথম অক্ষরটি তার চূড়ান্ত গন্তব্যে স্থানান্তরিত হয়। সবেমাত্র প্রতিস্থাপন করা চরিত্রটি তার গন্তব্য ইত্যাদিতে স্থানান্তরিত হয়, ইত্যাদি দুটি শর্তের একটি পূরণ না হওয়া অবধি এটি অব্যাহত থাকে:

  1. চরিত্রটি একটি স্থানের সাথে অদলবদল করা উচিত।
    যখন এটি ঘটে তখন চরিত্রটি হয় না স্থানের সাথে অদলবদল , বরং স্থানটির আয়নার অবস্থানে থাকে। অ্যালগরিদম সেই অবস্থান থেকে চালিয়ে যায়।
  2. একটি চক্র পৌঁছেছে।
    লক্ষ্যটি যখন বর্তমান চক্রের প্রাথমিক প্রারম্ভিক অবস্থানে ফিরে আসে, পরবর্তী স্বেচ্ছাপূর্ণ অক্ষর (বা বরং, কোনও স্বেচ্ছাকৃত চরিত্রটি করবে) খুঁজে পাওয়া দরকার। অবিচ্ছিন্ন মেমরির সীমাবদ্ধতার মধ্যে এটি করার জন্য, এই বিন্দু পর্যন্ত তৈরি করা সমস্ত অদলবদলকে আবার ট্র্যাক করা হবে।

এই পর্বের পরে, প্রতিটি অ-স্থান অক্ষরকে একবারে সরিয়ে নেওয়া হয়েছে। শেষ করতে, সমস্ত স্থানের অক্ষরগুলি তাদের আয়না অবস্থানগুলিতে অক্ষরগুলির সাথে অদলবদল করা হয়, প্রতি স্থানের জন্য দুটি অ্যাসাইনমেন্ট ক্রিয়াকলাপ প্রয়োজন।


বাহ, এটা দুর্দান্ত। আপনি ব্যাখ্যা করতে পারবেন কেন স্থানটির আয়নার অবস্থানটিতে চরিত্রটি স্থাপন করা সঠিক উত্তর দেয়?
justhalf

1
@ নিক্লাস, আমি মনে করি এটি সম্ভব নয়। কারণ ব্যাকট্রাকিং করতে আপনার স্থানের অবস্থান সম্পর্কিত তথ্য প্রয়োজন। আপনি যদি সেই তথ্যটি ওভাররাইড করেন, আপনি ব্যাকট্র্যাকিং করতে পারবেন না।
justhalf

1
আমি এখানে আমার উত্তরে আমার অ্যালগরিদমের সাথে একটি তুলনা করছি: কোডগলফ.স্ট্যাকেক্সেঞ্জারওয়ে
a

1
@ আসফাল্ফ চূড়ান্ত স্ট্রিংয়ে, সমস্ত স্পেস তাদের মিরর অবস্থায় থাকবে। অতএব, স্থানটি প্রতিস্থাপনকারী চরিত্রটি সংরক্ষণ করার জন্য আমরা নিরাপদে এই অবস্থানটি ব্যবহার করতে পারি এবং শেষে তাদের স্যুইচ করতে পারি।
প্রিমো

1
সাবাশ. আমার অনুরূপ ধারণা ছিল তবে কেবল জায়গাগুলি রেখে আর সেগুলি আয়না করার কথা ভাবিনি।
ইচবিনকিনবাউম 13:25 এ 18

7

রুবি, স্কোর 2

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

def revstring(s, a, b)
  while a<b
    h = s[a]
    s[a] = s[b]
    s[b] = h
    a += 1
    b -= 1
  end
  s
end

def revwords(s)
  revstring(s, 0, s.length-1)
  a = 0
  while a<s.length
    b = a+1
    b += 1 while b<s.length and s[b]!=" "
    revstring(s, a, b-1)
    a = b+1
  end
  s
end

ব্যবহার:

> revwords("hello there everyone")
"everyone there hello"

স্ট্রিংকে উল্টানোর জন্য আপনি কেন রুবি অন্তর্নির্মিত ফাংশনটি ব্যবহার করেন নি? এটি স্কোর পরিবর্তন করতে হবে?
এএল

ব্যবহার, এস [এ], এস [বি] = এস [বি], এস [এ]
থাহা কেপি

5

সি ++: স্কোর 2

#include<iostream>
#include<algorithm>

void rev(std::string& s)
{
    std::reverse(s.begin(),s.end());
    std::string::iterator i=s.begin(),j=s.begin();
    while(i!=s.end())
    {
        while(i!=s.end()&&(*i)==' ')
            i++;
        j=i;
        while(i!=s.end()&&(*i)!=' ')
            i++;
        std::reverse(j,i);
    }
}

int main()
{
    std::string s;
    getline(std::cin,s);
    rev(s);
    std::cout<<s;
}

2
আমি এটি পরীক্ষা করেছি। ভাল কাজ করে!
ব্যাচুসবেল

2

Rebol

reverse-words: function [
    "Reverse the order of words. Modifies and returns string (series)"
    series [string!] "At position (modified)"
  ][
    first-time: on
    until [
        reverse/part series f: any [
            if first-time [tail series]
            find series space
            tail series
        ]
        unless first-time [series: next f]
        first-time: off
        tail? series
    ]

    series: head series
]

আমি এই জন্য স্কোরিং সম্পর্কে অস্পষ্ট। এই কোডটিতে কোনও সরাসরি স্ট্রিং অ্যাসাইনমেন্ট নেই। সমস্ত কিছু এক দ্বারা পরিচালিত হয়reverse/part জায়গায় স্থানান্তরিত করে এবং পুরো স্ট্রিংয়ের শুরুতে vers

কোড সম্পর্কে কিছু বিশদ:

  • স্ট্রিং ( series) দিয়ে লুপ করুন যতক্ষণ না এটি পৌঁছে যায়tail?

  • লুপে প্রথমবার সম্পূর্ণ বিপরীতে স্ট্রিং করুন - reverse/part series tail series(যা এর মতো reverse series)

  • তারপরে আরও পুনরাবৃত্তিতে পাওয়া প্রতিটি শব্দকে বিপরীত করুন - reverse/part series find series space

  • নিঃশব্দ শব্দটি খুঁজে পেয়ে আবার ফিরে আসে tail seriesযাতে এটি শেষ শব্দটিকে স্ট্রিংয়ে উল্টে দেয় -reverse/part series tail series

অভ্যন্তরীণ পয়েন্টারটির মাধ্যমে রেবোল একটি স্ট্রিংকে ট্র্যাভারস করার অনুমতি দেয় । আপনি এটি দেখতে পাবেন series: next f(স্থানের পরে পয়েন্টার স্থানান্তর করুন তাই পরবর্তী শব্দের শুরুতে) এবংseries: head series (পয়েন্টারটি আবার মাথার দিকে পুনরায় সেট করুন)।

সিরিজ দেখুনআরও তথ্যের জন্য ।

রেবোল কনসোলে ব্যবহারের উদাহরণ:

>> reverse-words "everyone there hello"
== "hello there everyone"

>> x: "world hello"
== "world hello"

>> reverse-words x
== "hello world"

>> x
== "hello world"

>> reverse-words "hello"
== "hello"

প্রথম পাসে প্রতিটি অক্ষর একবার স্থির করা হয় এবং দ্বিতীয় পাসে প্রতিটি অ-স্থানের অক্ষর আবার স্থান করে দেওয়া হয়। তুলনামূলকভাবে কয়েকটি স্পেস সহ নির্বিচারে বৃহত ইনপুটগুলির জন্য, স্কোরটি 2 এ পৌঁছেছে
প্রিমো

2

সি: স্কোর 2

এটি কেবল একবারে প্রতিটি শব্দের বিপরীত করে পুরো স্ট্রিংটি ফ্লিপ করে।

#include <stdio.h>
#include <string.h>

void reverse(char *s,unsigned n){
    char c;
    unsigned i=0,r=1;
    while(i < n){ //no swap function in C 
        c=s[i];
        s[i++]=s[n];
        s[n--]=c;
    }
}

unsigned wordlen(char *s){
    unsigned i=0;
    while (s[i] != ' ' && s[i]) ++i;
    return i;
}

int main(int argc, char **argv) {
    char buf[]="reverse this also";
    char *s=buf;
    unsigned wlen=0,len=strlen(s)-1;
    reverse(s,len);  //reverse entire string
    while(wlen<len){  // iterate over each word till end of string
      wlen=wordlen(s);
      reverse(s,wlen-1);
      s+=wlen+1;
      len-=wlen;
    }
    printf("%s\n",buf);
    return 0;
}

3
এটি একটি কোড-উত্তর মাত্র। আপনার কোডে কী চলছে তার একটি ব্যাখ্যা যুক্ত করার বিষয়ে বিবেচনা করুন।
জাস্টিন

1

পাইথন: স্কোর 2

হাওয়ার্ডের অ্যালগরিদমের প্রায় অনুরূপ, তবে বিপরীতে বিপরীত পদক্ষেপগুলি হয় (প্রথমে শব্দগুলি ফ্লিপ করে তারপরে পুরো স্ট্রিংটি ফ্লিপ করে)। অতিরিক্ত স্মৃতি ব্যবহার 3 বাইট আকারের ভেরিয়েবল হল: i, j, এবং t। প্রযুক্তিগতভাবে, findএবং lenকিছু অভ্যন্তরীণ ভেরিয়েবল ব্যবহার করছে তবে তারা কেবল সহজেই পুনরায় ব্যবহার করতে পারে iবাj কোনও ক্রিয়া ক্ষতি ছাড়াই।

দ্রুত সম্পাদনা: অক্ষরগুলি পৃথক হলে কেবল অদল-বদল করে স্ট্রিং অ্যাসাইনমেন্টে সঞ্চয় করা হয়, সুতরাং আমি নোট # 2 থেকে কিছু অতিরিক্ত পয়েন্ট ধরতে পারি।

from sys import stdin

def word_reverse(string):
    # reverse each word
    i=0
    j=string.find(' ')-1
    if j == -2: j=len(string)-1
    while True:
        while i<j:
            if string[i] != string[j]:
                t = string[i]
                string[i] = string[j]
                string[j] = t
            i,j = i+1,j-1
        i=string.find(' ', i)+1
        if i==0: break
        j=string.find(' ', i)-1
        if j == -2: j=len(string)-1
    # reverse the entire string
    i=0
    j=len(string)-1
    while i<j:
        if string[i] != string[j]:
            t = string[i]
            string[i] = string[j]
            string[j] = t
        i,j = i+1,j-1
    return string

for line in stdin.readlines():
    # http://stackoverflow.com/a/3463789/1935085
    line = line.strip() # no trailing newlines ore spaces to ensure it conforms to '[a-z]+( [a-z]+)*'
    print word_reverse(bytearray(line))

1

দল

আমি স্কোরিং পুরোপুরি না বুঝতে স্বীকার করব (আমার মনে হয় এটি দুটি) .. তবে আমি বলব - এটি কাজটি করে

@echo off

setLocal enableDelayedExpansion
set c=
set s=

for %%a in (%~1) do set /a c+=1 & echo %%a >> f!c!

for /L %%a in (!c!, -1, 1) do (
    set /p t=<f%%a
    set s=!s!!t!
    del f%%a
)

echo !s!

ইনপুটটিকে প্রথম স্ট্যান্ডার্ড ইনপুট মান হিসাবে নেওয়া হয় এবং তাই কোটেশন চিহ্ন দ্বারা ঘিরে রাখা দরকার -
কল: script.bat "hello there everyone"
আউট:everyone there hello

হয়তো অন্য কেউ আমাকে স্কোর করতে পারে (ধরে নিলাম আমি অন্য কোনও উপায়ে নিজেকে অযোগ্য ঘোষণা করেছি)।


-2

জাভাস্ক্রিপ্ট

function reverseWords(input) {
    if (input.match(/^[a-z]+( [a-z]+)*$/g)) {
        return input.split(' ').reverse().join(' ');
    }
}

ব্যবহার:

> reverseWords('hello there everyone');
'everyone there hello'

আমি অদ্ভুত অনুভূতি পেয়েছি যা আমি কিছু মিস করেছি ...


3
হ্যাঁ, এটি স্থানে নেই কারণ আপনি ইনপুট স্ট্রিংটি পরিবর্তন করেন না। জাভাস্ক্রিপ্টে এটি সম্ভব না হওয়ায় আপনাকে অক্ষরের একটি অ্যারে (যেমন কোড পয়েন্ট ইন্টিজার বা একক-অক্ষরযুক্ত স্ট্রিং) দিয়ে স্ট্রিংগুলি অনুকরণ করতে হবে।
মার্টিন ইন্ডার

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