সীমাবদ্ধ মেমরি অপ্টিমাইজেশন


9

সম্পাদন করা (অথবা Levenshtein) দূরত্ব দুটি স্ট্রিং মধ্যে একক অক্ষর সন্নিবেশ, মুছে দেওয়া এবং বদল অপরের মধ্যে এক স্ট্রিং রুপান্তর প্রয়োজনীয় ন্যূনতম সংখ্যা। যদি দুটি স্ট্রিংয়ের দৈর্ঘ্য n থাকে তবে এটি সুপরিচিত যে ডিনামিক প্রোগ্রামিংয়ের মাধ্যমে এটি O (n ^ 2) সময়ে করা যেতে পারে। নিম্নলিখিত পাইথন কোড দুটি স্ট্রিং s1এবং এর জন্য এই গণনা সম্পাদন করে s2

def edit_distance(s1, s2):
    l1 = len(s1)
    l2 = len(s2)

    matrix = [range(l1 + 1)] * (l2 + 1)
    for zz in range(l2 + 1):
      matrix[zz] = range(zz,zz + l1 + 1)
    for zz in range(0,l2):
      for sz in range(0,l1):
        if s1[sz] == s2[zz]:
          matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
        else:
          matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
    return matrix[l2][l1]

এই কার্যটিতে আপনাকে সম্পাদনা দূরত্বের গণনা করতে পারার সাথে তীব্র মেমরির সীমাবদ্ধতা থাকতে হবে close আপনার কোডে 1000 32-বিট পূর্ণসংখ্যার সমন্বিত একটি অ্যারে সংজ্ঞায়িত করার অনুমতি দেওয়া হয়েছে এবং এটি আপনার গণনায় আপনি কেবলমাত্র অস্থায়ী স্টোরেজ ব্যবহার করবেন। সমস্ত ভেরিয়েবল এবং ডেটা স্ট্রাকচার এই অ্যারেতে থাকা উচিত। বিশেষত, আপনি 1000 দৈর্ঘ্যের স্ট্রিং হিসাবে উপরের অ্যালগরিদমটি প্রয়োগ করতে সক্ষম হবেন না কারণ এতে আপনার কমপক্ষে 1,000,000 সংখ্যা সঞ্চয় করতে হবে। যেখানে আপনার ভাষায় স্বাভাবিকভাবে 32 বিট ইন্টিজার নেই (উদাহরণস্বরূপ পাইথন) আপনার কেবল এটি নিশ্চিত করা দরকার যে আপনি কখনও অ্যারেতে 2 ^ 32-1 এর চেয়ে বড় সংখ্যা সংরক্ষণ করবেন না।

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

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

আমার কী বাস্তবায়ন করতে হবে?

আপনার কোডটি নিম্নলিখিত ফর্ম্যাটে কোনও ফাইলে পড়তে হবে। এটি তিনটি লাইন থাকবে। প্রথম লাইনটি সত্য সম্পাদনার দূরত্ব। দ্বিতীয়টি স্ট্রিং 1 এবং তৃতীয়টি স্ট্রিং 2। আমি এটি https://bpaste.net/show/6905001d52e8 তে নমুনা ডেটা দিয়ে পরীক্ষা করব যেখানে স্ট্রিংগুলির দৈর্ঘ্য 10,000 রয়েছে তবে এটি এই ডেটার জন্য বিশেষীকরণ করা উচিত নয়। এটি দুটি স্ট্রিংয়ের মধ্যে সন্ধান করতে পারে এমন ক্ষুদ্রতম সম্পাদনার দূরত্বকে আউটপুট করা উচিত।

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

স্কোর

আপনার স্কোর হবে (optimal edit distance/divided by the edit distance you find) * 100। জিনিসগুলি শুরু করতে, লক্ষ্য করুন যে আপনি দুটি স্ট্রিংয়ের মধ্যে অমিলের সংখ্যা গণনা করে একটি স্কোর পেতে পারেন।

আপনি আপনার পছন্দ মতো যে কোনও ভাষা লিনাক্সে অবাধে উপলব্ধ এবং সহজেই ইনস্টল করতে পারেন easy

টাই বিরতি

টাই-ব্রেকের ক্ষেত্রে, আমি আপনার কোডটি আমার লিনাক্স মেশিনে চালিত করব এবং দ্রুততম কোড জিতবে।


চান for(int i=0;i<=5;i++)না কারণ এটি ডাটা সংরক্ষণকারী অনুমতি দেওয়া হবে i?
বিটা ক্ষয়

2
@ বেটাডেহে হ্যাঁ নিয়মগুলি আরও নিবিড়ভাবে অনুসরণ করা সত্ত্বেও আপনি এমন কিছু করবেন যেমন { uint32_t foo[1000]; for (foo[0] = 0; foo[0] < 5; ++foo[0]) printf("%d ", foo[0]); } এটি ধরে নিচ্ছে আপনার 32 বিট সংখ্যার অ্যারে কল করা হবে foo

ফাইলটিতে সত্যিকারের সম্পাদনার দূরত্বটি কী? প্রোগ্রামটি আসলে এটি পড়ার কথা? বা (আরও বোধগম্য বলে মনে হচ্ছে) প্রোগ্রামটি কতটা সফল হয়েছিল তা কেবল আপনার জন্য দেখার জন্য?
feersum

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

bpaste.net/show/6905001d52e8 আমাকে একটি 404 পৃষ্ঠা দেয়!
সার্জিওল

উত্তর:


4

সি ++, স্কোর 92.35

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

প্রোগ্রামটি 1-10 থেকে এন এর সমস্ত মান চেষ্টা করে এবং সেরা স্তরটি দেয় এমন স্তরটি নির্বাচন করে। এন = 10 সাধারণত এখন সেরা যে স্কোরিং পদ্ধতিটি স্ট্রিংয়ের দৈর্ঘ্যটিকে বিবেচনায় রাখে। এন এর উচ্চতর মানগুলি সম্ভবত আরও ভাল হতে পারে তবে তাত্পর্যপূর্ণভাবে আরও বেশি সময় নেয়।

মেমোরির ব্যবহার: যেহেতু প্রোগ্রামটি নিখুঁতভাবে পুনরাবৃত্তিযোগ্য তাই এর খুব কম স্মৃতি দরকার। প্রোগ্রাম স্থিতি ট্র্যাক করতে শুধুমাত্র 19 ভেরিয়েবল ব্যবহার করা হয়। এগুলি বিশ্বব্যাপী ভেরিয়েবল হিসাবে কাজ করার জন্য # ডিজাইন দ্বারা সেট করা হয়েছে।

ব্যবহার: প্রোগ্রামটি ফেয়ারসামের মতোই ব্যবহৃত হয়: প্রথম প্যারামিটারটি ফাইল হিসাবে ধরে নেওয়া হয় এবং কোনও অতিরিক্ত পরামিতি নির্দেশ করে যে সম্পাদনাগুলি প্রদর্শিত হবে। প্রোগ্রামটি সর্বদা অনুমিত সম্পাদনা দূরত্ব এবং স্কোরকে মুদ্রণ করে।

যাচাইকরণ আউটপুট: যাচাইকরণ আউটপুট এটি তিন সারিতে বিন্যাস করেছে:

11011111100101100111100110100 110 0 0000   0 01101
R I          IR     R        D   D D    DDD D     D
01 1111110010 0001110001101000110101000011101011010

উপরের সারিটি লক্ষ্যযুক্ত স্ট্রিং, মাঝেরটি অপারেশনগুলি এবং নীচেটি স্ট্রিংটি সম্পাদনা করা হচ্ছে। অপারেশন লাইনের স্পেসগুলি নির্দেশ করে যে অক্ষরগুলি মেলে। 'আর' ইঙ্গিত করে যে সম্পাদনা স্ট্রিংয়ের লক্ষ্যটি স্ট্রিংয়ের চরিত্রের সাথে প্রতিস্থাপিত হয়েছে এমন অবস্থানে এটির চরিত্র রয়েছে। 'আমি' ইঙ্গিত করে যে সম্পাদনা স্ট্রিংয়ের সেই অবস্থানে লক্ষ্যযুক্ত স্ট্রিংয়ের চরিত্র .োকানো হয়েছে। 'ডি' ইঙ্গিত করে যে সম্পাদনা স্ট্রিংয়ের অক্ষরটি সেই অবস্থানে মুছে ফেলা হয়েছে। সম্পাদনা এবং লক্ষ্যযুক্ত স্ট্রিংগুলিতে স্পেস সন্নিবেশ করা থাকে যখন অন্যটির একটি অক্ষর sertedোকানো বা মুছে ফেলা হয় যাতে তারা লাইন করে।

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <math.h>
#include <fstream>

int memory[1000];
#define first (*(const char **)&memory[0])
#define second (*(const char **)&memory[1])
#define block_ia memory[2]
#define block_ib memory[3]
#define block_n memory[4]
#define block_op memory[5]
#define block_o memory[6]
#define block_x memory[7]
#define n memory[8]
#define opmax memory[9]
#define best_op memory[10]
#define best_score memory[11]
#define score memory[12]
#define best_counter memory[13]
#define la memory[14]
#define lb memory[15]
#define best memory[16]
#define bestn memory[17]
#define total memory[18]

// verification variables
char printline1[0xffff]={};
char *p1=printline1;
char printline2[0xffff]={};
char *p2=printline2;
char printline3[0xffff]={};
char *p3=printline3;


// determine how many characters match after a set of operations
int block(){
    block_ia=0;
    block_ib=0;
    for ( block_x=0;block_x<block_n;block_x++){
        block_o = block_op%3;
        block_op /= 3;
        if ( block_o == 0 ){ // replace
            block_ia++;
            block_ib++;
        } else if ( block_o == 1 ){ // delete
            block_ib++;
        } else { // insert
            if ( first[block_ia] ){ 
                block_ia++;
            }
        }
        while ( first[block_ia] && first[block_ia]==second[block_ib] ){ // find next mismatch
            block_ia++;
            block_ib++;
        }
        if ( first[block_ia]==0 ){
            return block_x;
        }
    }
    return block_n;
}

// find the highest-scoring set of N operations for the current string position
void bestblock(){
    best_op=0;
    best_score=0;
    la = strlen(first);
    lb = strlen(second);
    block_n = n;
    for(best_counter=0;best_counter<opmax;best_counter++){
        block_op=best_counter;
        score = n-block();
        score += block_ia-abs((la-block_ia)-(lb-block_ib));
        if ( score > best_score ){
            best_score = score;
            best_op = best_counter;
        }
    }
}

// prepare edit confirmation record
void printedit(const char * a, const char * b, int o){
    o%=3;
    if ( o == 0 ){ // replace
        *p1 = *a;
        if ( *b ){
            *p2 = 'R';
            *p3 = *b;
            b++;
        } else {
            *p2 = 'I';
            *p3 = ' ';
        }
        a++;
    } else if ( o == 1 ){ // delete
        *p1 = ' ';
        *p2 = 'D';
        *p3 = *b;
        b++;
    } else { // insert
        *p1 = *a;
        *p2 = 'I';
        *p3 = ' ';
        a++;
    }
    p1++;
    p2++;
    p3++;
    while ( *a && *a==*b ){
        *p1 = *a;
        *p2 = ' ';
        *p3 = *b;
        p1++;
        p2++;
        p3++;
        a++;
        b++;
    }
}


int main(int argc, char * argv[]){

    if ( argc < 2 ){
        printf("No file name specified\n");
        return 0;
    }

    std::ifstream file(argv[1]);
    std::string line0,line1,line2;
    std::getline(file,line0);
    std::getline(file,line1);
    std::getline(file,line2);

    // begin estimating Levenshtein distance
    best = 0;
    bestn = 0;
    for ( n=1;n<=10;n++){ // n is the number of operations that can be in a test set
        opmax = (int)pow(3.0,n);
        first = line1.c_str();
        second = line2.c_str();
        while ( *first && *first == *second ){
            first++;
            second++;
        }
        total=0;
        while ( *first && *second ){
            bestblock();
            block_n=1;
            block_op=best_op;
            block();
            total ++;
            first += block_ia;
            second += block_ib;
        }
        // when one string is exhausted, all following ops must be insert or delete
        while(*second){
            total++;
            second++;
        }
        while(*first){
            total++;
            first++;
        }
        if ( !best || total < best ){
            best = total;
            bestn = n;
        }
    }
    // done estimating Levenshtein distance

    // dump info to prove the edit distance actually comes from a valid set of edits
    if ( argc >= 3 ){
        p1 = printline1;
        p2 = printline2;
        p3 = printline3;
        n = bestn;
        opmax = (int)pow(3.0,n);
        first = line1.c_str();
        second = line2.c_str();
        while ( *first && *first == *second ){
            *p1 = *first;
            *p2 = ' ';
            *p3 = *second;
            p1++;
            p2++;
            p3++;
            first++;
            second++;
        }
        while ( *first && *second){
            bestblock();
            block_n=1;
            block_op=best_op;
            block();
            printedit(first,second,best_op);
            first += block_ia;
            second += block_ib;
        }
        while(*second){
            *p1=' ';
            *p2='D';
            *p3=*second;
            p1++;
            p2++;
            p3++;
            second++;
        }
        while(*first){
            *p1=*first;
            *p2='I';
            *p3=' ';
            p1++;
            p2++;
            p3++;
            first++;
        }

        p1 = printline1;
        p2 = printline2;
        p3 = printline3;
        int ins=0;
        int del=0;
        int rep=0;
        while ( *p1 ){
            int a;
            for ( a=0;a<79&&p1[a];a++)
                printf("%c",p1[a]);
            printf("\n");
            p1+=a;
            for ( a=0;a<79&&p2[a];a++){
                ins += ( p2[a] == 'I' );
                del += ( p2[a] == 'D' );
                rep += ( p2[a] == 'R' );
                printf("%c",p2[a]);
            }
            printf("\n");
            p2+=a;
            for ( a=0;a<79&&p3[a];a++)
                printf("%c",p3[a]);
            printf("\n\n");
            p3+=a;
        }
        printf("Best N=%d\n",bestn);
        printf("Inserted = %d, Deleted = %d, Replaced=%d, Total = %d\nLength(line1)=%d, Length(Line2)+ins-del=%d\n",ins,del,rep,ins+del+rep,line1.length(),line2.length()+ins-del);
    }

    printf("%d, Score = %0.2f\n",best,2886*100.0/best);
    system("pause");
    return 0;
}

7

সি ++ 75.0

প্রোগ্রামটি স্বেচ্ছাসেবী পাঠ্য স্ট্রিংয়ের সাথে কাজ করার জন্য ডিজাইন করা হয়েছে। এগুলি কোনও পৃথক দৈর্ঘ্যের হতে পারে যতক্ষণ না ১৩৮২৪ টির বেশি অক্ষরের বেশি। এটিতে 1,897 16-বিট পূর্ণসংখ্যা ব্যবহার করা হয়েছে, যা 949 32-বিট পূর্ণসংখ্যার সমতুল্য। প্রথমে আমি এটি সিতে লিখছিলাম, তবে তখন বুঝতে পেরেছিলাম যে একটি লাইন পড়ার জন্য কোনও কার্যকারিতা নেই।

প্রথম কমান্ড-লাইন যুক্তি একটি ফাইলের নাম হওয়া উচিত। যদি দ্বিতীয় যুক্তি উপস্থিত থাকে তবে সম্পাদনাগুলির একটি সারাংশ মুদ্রিত হয়। ফাইলের প্রথম লাইনটি অগ্রাহ্য করা হয় যখন দ্বিতীয় এবং তৃতীয় স্ট্রিং।

অ্যালগরিদম হল সাধারণ অ্যালগরিদমের দ্বিগুণ অবরুদ্ধ সংস্করণ। এটি মূলত একই সংখ্যক ক্রিয়াকলাপ সম্পাদন করে, তবে অবশ্যই এটি খুব কম নির্ভুল, যেহেতু যদি একটি সাধারণ অনুচ্ছেদ একটি ব্লকের প্রান্তে বিভক্ত হয়ে যায়, সম্ভাব্য সঞ্চয়টির অনেকটাই ক্ষতি হয়।

#include <cstring>
#include <inttypes.h>
#include <iostream>
#include <fstream>

#define M 24
#define MAXLEN (M*M*M)
#define SETMIN(V, X) if( (X) < (V) ) { (V) = (X); }
#define MIN(X, Y) ( (X) < (Y) ? (X) : (Y) )

char A[MAXLEN+1], B[MAXLEN+1];
uint16_t d0[M+1][M+1], d1[M+1][M+1], d2[M+1][M+1];

int main(int argc, char**argv)
{

    if(argc < 2)
        return 1;

    std::ifstream fi(argv[1]);

    std::string Astr, Bstr;
    for(int i = 3; i--;)
        getline(fi, i?Bstr:Astr);
    if(!fi.good()) {
        printf("Error reading file");
        return 5;
    }
    if(Astr.length() > MAXLEN || Bstr.length() > MAXLEN) {
        printf("String too long");
        return 7;
    }

    strcpy(A, Astr.c_str());
    strcpy(B, Bstr.c_str());

    uint16_t lA = Astr.length(), lB = Bstr.length();
    if(!lA || !lB) {
        printf("%d\n", lA|lB);
        return 0;
    }
    uint16_t nbA2, nbB2, bA2, bB2, nbA1, nbB1, bA1, bB1, nbA0, nbB0, bA0, bB0; //block, number of blocks
    uint16_t iA2, iB2, iA1, iB1, jA2, jB2, jA1, jB1; //start, end indices of block

    nbA2 = MIN(M, lA);
    nbB2 = MIN(M, lB);
    for(bA2 = 0; bA2 <= nbA2; bA2++) {
        iA2 = lA * (bA2-1)/nbA2,  jA2 = lA * bA2/nbA2;
        for(bB2 = 0; bB2 <= nbB2; bB2++) {
            if(!(bA2|bB2)) {
                d2[0][0] = 0;
                continue;
            }
            iB2 = lB * (bB2-1)/nbB2,  jB2 = lB * bB2/nbB2;
            d2[bA2][bB2] = ~0;
            if(bB2)
                SETMIN(d2[bA2][bB2], d2[bA2][bB2-1] + (jB2-iB2));
            if(bA2)
                SETMIN(d2[bA2][bB2], d2[bA2-1][bB2] + (jA2-iA2));

            if(bA2 && bB2) {
                nbA1 = MIN(M, jA2-iA2);
                nbB1 = MIN(M, jB2-iB2);
                for(bA1 = 0; bA1 <= nbA1; bA1++) {
                    iA1 = iA2 + (jA2-iA2) * (bA1-1)/nbA1, jA1 = iA2 + (jA2-iA2) * bA1/nbA1;
                    for(bB1 = 0; bB1 <= nbB1; bB1++) {
                        if(!(bA1|bB1)) {
                            d1[0][0] = 0;
                            continue;
                        }
                        iB1 = iB2 + (jB2-iB2) * (bB1-1)/nbB1, jB1 = iB2 + (jB2-iB2) * bB1/nbB1;
                        d1[bA1][bB1] = ~0;
                        if(bB1)
                            SETMIN(d1[bA1][bB1], d1[bA1][bB1-1] + (jB1-iB1));
                        if(bA1)
                            SETMIN(d1[bA1][bB1], d1[bA1-1][bB1] + (jA1-iA1));

                        if(bA1 && bB1) {
                            nbA0 = jA1-iA1;
                            nbB0 = jB1-iB1;
                            for(bA0 = 0; bA0 <= nbA0; bA0++) {
                                for(bB0 = 0; bB0 <= nbB0; bB0++) {
                                    if(!(bA0|bB0)) {
                                        d0[0][0] = 0;
                                        continue;
                                    }
                                    d0[bA0][bB0] = ~0;
                                    if(bB0)
                                        SETMIN(d0[bA0][bB0], d0[bA0][bB0-1] + 1);
                                    if(bA0)
                                        SETMIN(d0[bA0][bB0], d0[bA0-1][bB0] + 1);
                                    if(bA0 && bB0)
                                        SETMIN(d0[bA0][bB0], d0[bA0-1][bB0-1] + (A[iA1 + nbA0 - 1] != B[iB1 + nbB0 - 1]));
                                }
                            }
                            SETMIN(d1[bA1][bB1], d1[bA1-1][bB1-1] + d0[nbA0][nbB0]);
                        }
                    }
                }

                SETMIN(d2[bA2][bB2], d2[bA2-1][bB2-1] + d1[nbA1][nbB1]);
            }
        }
    }
    printf("%d\n", d2[nbA2][nbB2]);

    if(argc == 2)
        return 0;

    int changecost, total = 0;
    for(bA2 = nbA2, bB2 = nbB2; bA2||bB2; ) {
        iA2 = lA * (bA2-1)/nbA2,  jA2 = lA * bA2/nbA2;
        iB2 = lB * (bB2-1)/nbB2,  jB2 = lB * bB2/nbB2;
        if(bB2 && d2[bA2][bB2-1] + (jB2-iB2) == d2[bA2][bB2]) {
            total += changecost = (jB2-iB2);
            char tmp = B[jB2];
            B[jB2] = 0;
            printf("%d %d deleted {%s}\n", changecost, total, B + iB2);
            B[jB2] = tmp;
            --bB2;
        } else if(bA2 && d2[bA2-1][bB2] + (jA2-iA2) == d2[bA2][bB2]) {
            total += changecost = (jA2-iA2);
            char tmp = B[jA2];
            A[jA2] = 0;
            printf("%d %d inserted {%s}\n", changecost, total, A + iA2);
            A[jA2] = tmp;
            --bA2;
        } else {
            total += changecost = d2[bA2][bB2] - d2[bA2-1][bB2-1];
            char tmpa = A[jA2], tmpb = B[jB2];
            B[jB2] = A[jA2] = 0;
            printf("%d %d changed {%s} to {%s}\n", changecost, total, B + iB2, A + iA2);
            A[jA2] = tmpa, B[jB2] = tmpb;
            --bA2, --bB2;
        }
    }


    return 0;
}

প্রথম উত্তরদাতা হওয়ার জন্য আপনাকে ধন্যবাদ! আপনার স্কোর কি?

@ ল্যাম্বিক ঠিক আছে, আমি স্কোরটি গণনা করেছি, ধরে নিলাম এটি কেবলমাত্র একটি উদাহরণের উপর ভিত্তি করে।
feersum

এটা অসাধারণ. আপনি কি মনে করেন যে এটি আরও বেশি স্কোর পাওয়া সম্ভব?

3

পাইথন, 100

বরাদ্দ করা মেমরির সীমাতে আমি সম্পাদনার দূরত্বটি নিখুঁতভাবে গণনা করতে পরিচালিত করেছিলাম। দুঃখের বিষয়, এই এন্ট্রি চ্যালেঞ্জের দুটি নিয়ম লঙ্ঘন করেছে, চিঠিতে যদি আত্মায় না হয়।

প্রথমত, আমি আসলে আমার ডেটা 1000 32-বিট ইনটগুলিতে সঞ্চয় করি নি। 10000-অক্ষরযুক্ত স্ট্রিংয়ের জন্য, আমার প্রোগ্রামটি দুটি 10000-উপাদান অ্যারে তৈরি করে যা কেবলমাত্র +1, 0, বা -1 ধারণ করে। টেরিনারি সংখ্যার প্রতি 1.585 বিট-এ, এই 20000 টি ট্রিটগুলি 31700 বিটগুলিতে প্যাক করা সম্ভব হবে, আমার 16 টি অবশিষ্ট 16-বিট পূর্ণসংখ্যার জন্য 300 বিট যথেষ্ট পরিমাণে রেখে।

দ্বিতীয়ত, আমি সম্পাদনাগুলি দেখানোর জন্য প্রয়োজনীয় মোডটি প্রয়োগ করি নি। আমি পর্যায়ক্রমে একটি মোড প্রয়োগ করেছি যা সম্পূর্ণ সম্পাদনা ম্যাট্রিক্স প্রিন্ট করে। এই ম্যাট্রিক্স থেকে সম্পাদনার পাথ গণনা করা একেবারেই সম্ভব, তবে এটি বাস্তবায়নের জন্য আমার কাছে এখনই সময় নেই।

#!/usr/bin/env python

import sys

# algorithm originally from
# https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows

print_rows = False
if len(sys.argv) > 2:
    print_rows = True

def LevenshteinDistance(s, t):
    # degenerate cases
    if s == t:
        return 0
    if len(s) == 0:
        return len(t)
    if len(t) == 0:
        return len(s)

    # create two work vectors of integer distance deltas

    # these lists will only ever contain +1, 0, or -1
    # so they COULD be packed into 1.585 bits each
    # 15850 bits per list, 31700 bits total, leaving 300 bits for all the other variables

    # d0 is the previous row
    # initialized to 0111111... which represents 0123456...
    d0 = [1 for i in range(len(t)+1)]
    d0[0] = 0        
    if print_rows:
        row = ""
        for i in range(len(t)+1):
            row += str(i) + ", "
        print row

    # d1 is the row being calculated
    d1 = [0 for i in range(len(t)+1)]

    for i in range(len(s)-1):
        # cummulative values of cells north, west, and northwest of the current cell
        left = i+1
        upleft = i
        up = i+d0[0]
        if print_rows:
            row = str(left) + ", "
        for j in range(len(t)):
            left += d1[j]
            up += d0[j+1]
            upleft += d0[j]
            cost = 0 if (s[i] == t[j]) else 1
            d1[j + 1] = min(left + 1, up + 1, upleft + cost) - left
            if print_rows:
                row += str(left+d1[j+1]) + ", "

        if print_rows:
            print row

        for c in range(len(d0)):
            d0[c] = d1[c]

    return left+d1[j+1]

with open(sys.argv[1]) as f:
    lines = f.readlines()

perfect = lines[0]
string1 = lines[1]
string2 = lines[2]
distance = LevenshteinDistance(string1,string2)
print "edit distance: " + str(distance)
print "score: " + str(int(perfect)*100/distance) + "%"

উদাহরণ ইনপুট:

2
101100
011010

ভার্বোজ আউটপুট উদাহরণ:

0, 1, 2, 3, 4, 5, 6,
1, 1, 1, 2, 3, 4, 5,
2, 1, 2, 2, 2, 3, 4,
3, 2, 1, 2, 3, 2, 3,
4, 3, 2, 1, 2, 3, 3,
5, 4, 3, 2, 1, 2, 3,
6, 5, 4, 3, 2, 2, 2,
edit distance: 2
score: 100%
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.