গল্ফ স্ট্রিংয়ের ফর্ম্যাট () বিপরীত


13

ফর্ম্যাট পদ্ধতিটি উল্টে দিন।

Formatস্ট্রিং বর্গ (অথবা equivallent যেমন পদ্ধতি sprintf) বেশির ভাগ ভাষায় পাওয়া যায়। এটি মূলত একটি "ফর্ম্যাট" স্ট্রিং নেয় যা কিছু অতিরিক্ত বিন্যাস সহ স্থানধারক এবং সেই স্থানধারকগুলির পরিবর্তে শূন্য বা আরও মান সন্নিবেশ করতে পারে।

আপনার কাজটি আপনার পছন্দের ভাষায় বিপরীত ফাংশন বাস্তবায়ন করা।

এপিআই

পদ্ধতির নামটি হয় format1বা হয় deformat

ইনপুট : 1 ম প্যারামিটারটি মূল ফর্ম্যাট পদ্ধতির মতো "ফর্ম্যাট" স্ট্রিং হবে। ২ য় প্যারামিটারটি বিশদযুক্ত স্ট্রিং হবে (নীচের উদাহরণগুলি দেখুন)। অন্য কোনও পরামিতি প্রয়োজন বা অনুমোদিত নয় allowed

আউটপুট : মানগুলির একটি অ্যারে (বা আপনার পছন্দের পছন্দটির সমতুল্য) যা ফর্ম্যাটটিতে স্থানধারকগুলির সাথে যথাযথভাবে নিষ্কাশিত হয়েছিল।

প্লেসহোল্ডার হয় {0}, {1}, {2}, ইত্যাদি

খারাপ ফর্ম্যাটের ক্ষেত্রে আপনি একটি ত্রুটি নিক্ষেপ করতে পারেন, বা আপনি যা পছন্দ করেন তা ফিরিয়ে দিতে পারেন।

অবৈধ ইনপুট ক্ষেত্রে, আপনি একটি ত্রুটি নিক্ষেপ করতে পারেন, বা আপনার পছন্দসই কিছু ফিরিয়ে দিতে পারেন। অবৈধ ইনপুট যেমন যে উদাহরণস্বরূপ একই বিন্যাসে স্ট্রিং ব্যবহার করে String.Format দ্বারা উত্পন্ন করা যাবে না, হল: '{0}{0}', 'AAB'

উদাহরণ

deformat('{0} {1}', 'hello world') => ['hello', 'world']
deformat('http{0}://', 'https://') => ['s']
deformat('http{0}://', 'http://') => [''] // array of one item which is an empty string
deformat('{0}{1}{0}', 'ABBA') => ['A', 'BB']

অস্পষ্টতা

অস্পষ্টতার ক্ষেত্রে আপনি কোনও উপযুক্ত উত্তর দিতে পারেন। উদাহরণ স্বরূপ:

deformat('{0} {1}', 'Edsger W. Dijkstra')
// both ['Edsger', 'W. Dijkstra'] and ['Edsger W.', 'Dijkstra'] are applicable.

আরও কিছু বিধি

  • এটিকে আরও সহজ করার জন্য, প্রকৃত বিন্যাসকে সমর্থন করার দরকার নেই। শীর্ষস্থানীয় শূন্যগুলি, দশমিক পয়েন্ট বা রাউন্ডিং সম্পর্কিত সমস্ত বিষয় আপনি ভুলে যেতে পারেন। স্ট্রিং হিসাবে মানগুলি উত্পন্ন করুন।
  • এটিকে তুচ্ছ হিসাবে তৈরি করার জন্য, নিয়মিত প্রকাশের অনুমতি নেই
  • আপনাকে ইনপুটগুলিতে কোঁকড়া ধনুর্বন্ধনী যত্ন নেওয়ার দরকার নেই (যেমন 2 য় ইনপুট প্যারামিটারে কোনও {গুলি বা }গুলি থাকবে না )।

জয়লাভ

এটি ! ("এটি স্পার্টা!" হিসাবে পড়া উচিত) স্বল্পতম দৈর্ঘ্যের জয়যুক্ত সঠিক ফাংশনটি। স্ট্যান্ডার্ড লুফোলগুলি নিষিদ্ধ।


উদাহরণস্বরূপ deformat('{0}{1}{0}', 'ABBA') => ['A', 'BB'], আমাদের পরিবর্তে যদি দেওয়া হয় তবে deformat('{0}{1}{0}', 'AAAA')কী হবে ?
xnor

@xnor - চেয়ে আমরা একটি দ্ব্যর্থতা আছে, এবং নিম্নলিখিত প্রতিটি একটি বৈধ আউটপুট হবে: ['', 'AAAA'], ['A', 'AA'],['AA', '']
জ্যাকব

কেউ কি তাহলে আউটপুট দিতে পারত deformat('{0}{1}{0}', 'ABBA') => ['', 'ABBA']? যদি তা হয় তবে প্রতিটি স্ট্রিং কমপক্ষে দুবার উপস্থিত না হওয়া পর্যন্ত একটি সস্তা সমাধান রয়েছে।
xnor

আপনার সস্তা সমাধান জন্য কাজ করবে deformat('{0}_{1}_{0}', 'A_BB_A')?
জ্যাকব

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

উত্তর:


2

হাস্কেল, 220 টি অক্ষর

import Data.Map;f""""=[empty]
f('{':b)d=[insert k m b|(k,('}':a))<-lex b,(m,c)<-[splitAt n d|n<-[0..length d]],b<-f a c,notMember k b||b!k==m]
f(x:b)(y:d)|x==y=f b d;f _ _=[];format1 x y=elems$mapKeys((0+).read)$f x y!!0

যদি আপনি একই প্যাটার্নের জন্য একাধিক উপস্থাপনা ( {1}বনাম {01}) ব্যবহার করেন তবে বিরতি - তাদের সাম্যতা প্রয়োগ করে না, পরিবর্তে একটির উপস্থাপনা বাদে সকলের জন্য ম্যাচ বাতিল করে।

mapKeys((0+).read)$10 টি প্যাটার্নের উপরের ম্যাচের যথাযথ অর্ডারে কোনও ব্যাপার না হলে বা একই দৈর্ঘ্যের প্যাডিংয়ের প্রয়োজন হতে পারে, বা যদি স্ট্রিং ক্রমগুলি প্যাটার্নগুলি গ্রহণযোগ্য হয় তবে 19 অক্ষর বাদ দিয়ে সংরক্ষণ করা যায় । যে কোনও ক্ষেত্রে, যদি প্রথম আর্গুমেন্ট থেকে কোনও প্যাটার্ন বাদ দেওয়া হয় তবে এটি ফলাফল থেকেও বাদ দেওয়া হয়।

!!0শেষ থেকে অপসারণ করা format1প্রথম সমাধানের পরিবর্তে সমস্ত সমাধানের তালিকা ফিরে দেয়।

গল্ফিংয়ের আগে:

import Data.Map
import Control.Monad

cuts :: [a] -> [([a],[a])]
cuts a=[splitAt n a | n <- [0..length a]]

f :: String -> String -> [Map String String]
-- empty format + empty parsed = one interpretation with no binding
f "" "" = [empty]
-- template-start format + some matched = branch search
f ('{':xs) ys = do
    let [(key, '}':xr)] = lex xs
    (match, yr) <- cuts ys
    b <- f xr yr
    guard $ notMember key b || b!key == match
    return $ insert key match b
-- non-empty format + matching parsed = exact match
f (x:xs) (y:ys) | x == y = f xs ys
-- anything else = no interpretation
f _ _ = []

deformat :: String -> String -> [String]
deformat x y = elems $ mapKeys ((0+).read) $ head $ f x y

সেখানে (0+) কি আছে? শুধু ছোট পড়া পড়া হয় না?
গর্বিত হাসেলেলার

@ প্রফাসহেসক্লার readআপনাকে একটি অস্পষ্ট ধরণের সাথে ছেড়ে দেয়। কীগুলি কী হিসাবে পড়তে হবে তা হেসেল জানে না। +0একটি সংখ্যা জোর করে, যা থেকে হাস্কেল ইতিমধ্যে একটি স্বেচ্ছাসেবী পছন্দ করতে সক্ষম এবং পূর্ণসংখ্যার জন্য যায়।
জন ডিভোরাক

2

রুবি, ৩১২ টি অক্ষর

class String
def-@
self[0,1].tap{self[0,1]=''}end
end
def format1 f,s,r=[]
loop{if'{'==c=-f
n,f=f.split('}',2)
[*1..s.length,0].each{|i|next if'{'!=f[0]&&s[i]!=f[0]
if u=format1((g=f.gsub("{#{n}}",q=s[0,i])).dup,s[i..-1],r.dup)
r,s,f=u,s[i..-1],g
r[n.to_i]=q
break
end}else
c!=-s&&return
end
""==c&&break}
r
end

প্রশ্নের পছন্দসই সমাধানের চেয়ে ABBAসমাধান তৈরি করে শূন্য দৈর্ঘ্যের ম্যাচগুলিকে ['', 'ABBA']প্রাধান্য দিয়ে 5 টি অক্ষর সংরক্ষণ করা যেতে পারে । উদাহরণগুলি স্পেসিফিকেশনের অন্তর্নিহিত অংশ হিসাবে ব্যাখ্যা করতে বেছে নিয়েছি।


1

পাইথন, ২০৮ টি অক্ষর যদিও অসম্পূর্ণ।

def format1(i,o):
 i+=" ";o+=" ";x=y=0;s=[]
 while x<len(i):
  if i[x]=="{":
   try:y+=len(s[int(i[x+1])])
   except:
    s+=[""]
    while o[y]!=i[x+3]:s[int(i[x+1])]+=o[y];y+=1
   x+=3
  x+=1;y+=1
 return s

ফাংশনটি উভয় স্ট্রিং একসাথে সাফ করে, যতক্ষণ না এটি ইনপুট স্ট্রিংয়ে একটি খোলার ব্রেস খুঁজে পায়, যা কোনও স্থানধারককে বোঝায়।

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

যদি এটি প্রসারিত না করা হয় তবে মানগুলির তালিকায় এটি একটি নতুন এন্ট্রি যুক্ত করে এবং আউটপুট স্ট্রিং থেকে অক্ষর যুক্ত করা শুরু করে যতক্ষণ না এটি ইনপুট স্ট্রিংয়ের স্থানধারকের পরে অক্ষর না পৌঁছায়।

এটি যখন ইনপুট স্ট্রিংয়ের শেষে পৌঁছে যায়, এটি এখন পর্যন্ত পাওয়া মানগুলি ফেরত দেয়।


এটি সাধারণ ইনপুটগুলির জন্য ভাল কাজ করে তবে এটিতে বেশ কয়েকটি সমস্যা রয়েছে:

  • এটির জন্য ইনপুটটিতে প্রতিটি স্থানধারকের পরে একটি পরিচিত ডিলিমিটারের প্রয়োজন হয়, সুতরাং এটি একে অপরের ঠিক পাশের স্থানধারীদের সাথে কাজ করে না "" {0} {1} "। এই কারণেই আমার উভয় স্ট্রিংয়ে একটি স্পেস চার যুক্ত করতে হবে।

  • এটি ধরে নিয়েছে যে প্রতিটি স্থানধারকের প্রথম উদাহরণগুলি যথাক্রমে রয়েছে যেমন "" { 0 } { 1 } {1} {0} { 2 } "।

  • এটি কেবল প্রথম 10 স্থানধারীদের জন্য কাজ করে কারণ এটি ধরে নেওয়া হয় যে তারা 3 টি অক্ষর দীর্ঘ।

  • এটি মোটেও অস্পষ্ট মামলাগুলি পরিচালনা করে না :(


1

সি ++ 11 কোড, 386 টি অক্ষর

#include <string>
#include <map>
using namespace std;using _=map<int,string>;using X=const char;_ format1(X*p,X*s,_ k=_()){_ r;while(*p!='{'){if(!*p||!*s){return*p==*s?k:r;}if(*p++!=*s++)return r;}int v=0;while(*++p!='}'){v=v*10+(*p-48);}p++;if(k.find(v)!=k.end()){return format1((k[v]+p).c_str(),s,k);}while((r=format1(p,s,k)).empty()){k[v]+=*s++;if(!*s){return*p==*s?k:r;}}return r;}

ফর্ম্যাট 1 ফাংশনে ইনপুট হিসাবে দুটি স্ট্রিং রয়েছে (কনস্ট চর *) এবং কীগুলি পূর্ণসংখ্যার (প্যাটার্ন) সহ একটি হ্যাশম্যাপ দেয় এবং মানটি চিহ্নিত স্ট্রিং। যদি কিছু না পাওয়া যায় বা কোনও ত্রুটি না পাওয়া যায় তবে একটি খালি হ্যাশম্যাপ ফিরে আসে।

ব্যবহার:

for (auto v : format1("{1} {2}", "one two")){
    cout << v.first << "=" << v.second << endl;
}

আউটপুট:

1=one
2=two

উদাহরণ 2:

auto v = format1("{1} {2}", "one two");
cout << v[1] << " and " << v[2] << endl;

আউটপুট:

one and two

নিদর্শনগুলি দশমিক প্রতিনিধিত্বতে রয়েছে, MAXINTউপচে পড়া প্রবাহের চেয়ে বড় ইনপুটগুলি কিন্তু এটি এখনও কার্যকর হয়।

যদিও অন্যান্য প্রোগ্রামিং ভাষাগুলিতে আরও ছোট সমাধান রয়েছে, এটি এখনও সবচেয়ে ছোট সি ++ - এখনও! :)

গল্ফ করার আগে এই কোড:

#include <string>
#include <map>
using namespace std;

using res = map<int,string>;

res format1(const char* p, const char* s, res k=res()){
    res r; // intermediate result, empty until the end
    // match until first '{'
    while (*p != '{'){
        if (!*p || !*s){
            // exit case
            return ((*p == *s) ? k : r); // == 0
        }
        if (*p++ != *s++)
               return r;
    }

    // *p == '{'
    int v = 0;
    while(*++p != '}'){
        v = v*10 + (*p - '0');
    }
    p++; // advance past '}'

    // match back-references
    if (k.find(v) != k.end()){
       return format1((k[v]+p).c_str(), s, k);
    }

    // recursive search
    while ( (r=format1(p, s, k)).empty() ){
        k[v] += *s++;
        if (!*s){
            return *p == *s ? k : r;
        }
    }
    return r;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.