Komünistik Substring Normalizasyonu


13

Bir dize ise T uzunluğunun K görünür K bir dize veya daha fazla kez S , o zaman olduğu potansiyel komünist . Örneğin, 10içinde 10/10göründüğü için, potansiyel olarak komünistik olan 2 kez ve uzunluğa sahiptir 2 . Bu alt dizelerin çakışamayacağını unutmayın.

Bir komünistik dönüşümü bu dize alır biri , T ve her bir karakteri hareket t i arasında T için i meydana T de S . Dolayısıyla, önceki örnek için, komünistik dönüşüm 1/0; ilk kez 10değiştirilen ilk karakter bulunur ve ikinci kez bulunur.10100

Bir komünistik normalleştirme tüm bu dizeleri alan bir fonksiyonudur , T ile K ≥ 2 ve gerçekleştirir bir komünistçe dönüşüm onlara.

Algoritma ile ilgili bazı özellikler:

  1. İlk önce en uzun geçerli dizeler T üzerinde komünistik dönüşümler gerçekleştirin . T'nin ilk oluşumlarını destekleyin .
  2. Ardından, bir sonraki en uzun dizelerde, sonra bir sonraki-bir sonraki-en uzun dizelerde komünist dönüşümler gerçekleştirin.
  3. Dizede böyle bir dizgi bulunmayana kadar yineleyin.

Test durumlarındaki "Merhaba, Merhaba" örneği gibi bazı dizelerin iki farklı şekilde yorumlanabileceğini unutmayın. Tell için kullanabilirsiniz , ancak kullanabilirsiniz . Bu durumda, kodunuz her iki seçeneği de seçebilir. Gösterilen test durumu kullanır , ancak farklı ve eşit derecede geçerli bir çıktı alabilirsiniz. llollo


Göreviniz komünist normalleşmeyi uygulamaktır. Giriş yalnızca yazdırılabilir ASCII karakterlerinden (0x20 - 0x7E, boşluktan tilde) oluşur. Bu görevi çözmek için bir program veya işlev yazabilirsiniz; giriş STDIN, dize / karakter dizisi bağımsız değişkeni, ARGV bağımsız değişkeni vb. satır olarak alınabilir.

Test senaryoları

'123' -> '123'
'111' -> '111'
'1111' -> '11'
'ABAB' -> 'AB'
'111111111' -> '111'
'asdasdasd' -> 'asd'
'10/10' -> '1/0'
'100/100+100' -> '1/0+0'
'   +   +   ' -> ' + '
'Hello, hello, dear fellow!' -> 'Hel he, dear feow!' OR 'Heo hl, dear flow!'
'11122333/11122333/11122333' -> '112/13' OR '132/23'

'ababab1ababab' -> 'a1bab'
'1ab2ab3ab4ab5ab6' -> '1a2b3a4b5ab6'

Test senaryosu çalıştı

Biçim, 'string', 'substring'her değiştirme adımındadır. Değiştirilen bitler parantez içine alınmıştır.

'11[122]333/11[122]333/11[122]333', '122'
'111[333]/112[333]/112[333]', '333'
'1113/11[23]/11[23]', '23'
'11[13]/112/1[13]', '13'
'1[11]/[11]2/13', '11'
'1[/1]12[/1]3', '/1'
'112/13', ''

Başka bir test örneği:

'Hello, hello, dear fellow!', 'llo'
'Hel, hel, dear feow!', 'l,'
'Hel he, dear feow!', ''

Referans kodu (Python)

Bunu algoritmayı görselleştirmek için yararlı bulabilirsiniz.

#!/usr/bin/env python

import re

def repeater(string):
    def repeating_substring(substring):
        return (string.count(substring) == len(substring)) and string.count(substring) > 1

    return repeating_substring

def get_substrings(string):
    j = 1
    a = set()
    while True:
        for i in range(len(string) - j+1):
            a.add(string[i:i+j])
        if j == len(string):
            break
        j += 1
    return list(a)

def replace_each_instance(string, substring):
    assert `string`+',', `substring`
    for i in substring:
        string = re.sub(re.escape(substring), i, string, 1)

    return string


def main(s):
    repeats = repeater(s)
    repeating_substr = filter(repeater(s), get_substrings(s))

    while repeating_substr:
        repeating_substr.sort(lambda x,y: cmp(len(y), len(x)))
        s = replace_each_instance(s, repeating_substr[0])
        repeating_substr = filter(repeater(s), get_substrings(s))

    return s

assert main('123') == '123'
assert main('111') == '111'
assert main('1111') == '11'
assert main('ABAB') == 'AB'
assert main('111111111') == '111'
assert main('asdasdasd') == 'asd'
assert main('10/10') == '1/0'
assert main('100/100+100') == '1/0+0'
assert main('   +   +   ') == ' + '
assert main('Hello, hello, dear fellow!') == 'Hel he, dear feow!'
assert main('11122333/11122333/11122333') == '112/13'

@ ConorO'Brien'e bu mücadelenin orijinal fikrini paylaştığı için teşekkürler.


Test durumlarda: ababab1ababab,1ab2ab3ab4ab5ab6
Zgarb

Neden değişiklik yok? abher iki dizede de en az iki kez oluşur.
Zgarb

@Zgarb test cihazım kötü gibi görünüyor, daha sonra düzeltirim. Test senaryolarını elle düzeltmek.
Rɪᴋᴇʀ

Yanıtlar:


2

Pyth, 22 bayt

u.xse.iLcGdf>cGTlTt#.:

Test odası

Programın ne yaptığını görmek için şuna bir göz atın:

iç organlar

Özellikle, program her zaman en uzun yedek parçaların nihai değişimini kullanır.

Açıklama:

u.xse.iLcGdf>cGTlTt#.:
u.xse.iLcGdf>cGTlTt#.:G)GQ    Implicit
u                        Q    Starting with the input, repeat the following
                              until a fixed point is reached.
                    .:G)      Construct all substrings of the current value
                              ordered smallest to largest, front to back.
                  t#          Filter on having more than 1 element.
                              These are the eligible substrings.
           f                  Filter these substrings on
             cGT              Chop the current value on the substring,
            >   lT            Then remove the first len(substring) pieces.
                              The result is nonempty if the substring is
                              one we're looking for. 
                              Chopping gives nonoverlapping occurrences.
     .iL                      Interlace the substrings with
        cGd                   Chop the current value on that substring
   se                         Take the final result, make it a string.
 .x                     G     If there weren't any, the above throws an error,
                              So keep the current value to halt.

4

JavaScript (ES6), 121 bayt

f=(s,j=2,o,m=s.match(`(.{${j}})(.*\\1){${(j-1)}}`))=>m?f(s,j+1,s.split(m[1]).map((e,i)=>e+(m[1][i]||'')).join``):o?f(o):s

Yinelemeli olarak desenle eşleşir:

(.{2})(.*\1){1}  //2 characters, repeated 1 time 
(.{3})(.*\1){2}  //3 characters, repeated 2 times 
(.{4})(.*\1){3}  //4 characters, repeated 3 times 
etc.

… Kalıp bulunana kadar. (Bu, önce en uzun dizenin işlenmesini garanti eder.)

Daha sonra, maçta bölünerek ve maçın karakterlerinin her birine katılarak en son bulunan model üzerinde "komünistik dönüşümleri" gerçekleştirir. ( mapbu amaçla kullanılır. Çok kötü joinbir geri arama almaz.)

Sonunda artık komünist olmayana kadar bu yeni dizgeyi geri çekiyor .

Test senaryoları:


1

Temiz , 420 ... 368 bayt

import StdEnv,StdLib
l=length
%q=any((==)q)
?_[]=[]
?a[(y,x):b]|isPrefixOf a[x:map snd b]=[y: ?a(drop(l a-1)b)]= ?a b
$s=sortBy(\a b=l a>l b)(flatten[[b: $a]\\(a,b)<-map((flip splitAt)s)[0..l s-1]])
f s#i=zip2[0..]s
#r=filter(\b=l(?b i)>=l b&&l b>1)($s)
|r>[]#h=hd r
#t=take(l h)(?h i)
=f[if(%n t)(h!!hd(elemIndices n t))c\\(n,c)<-i|not(%n[u+v\\u<-t,v<-[1..l h-1]])]=s

Çevrimiçi deneyin!


Bu cevap geçersiz. Buraya bakın. Bu değiştirilmelidir, test durumlarına bakın.
Rɪᴋᴇʀ

@Riker ilginç, çünkü referans çözümünün doğrudan bir limanı. Düzeltilene kadar silerim.
18

@Riker şimdi düzeltildi.
Οurous
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.