İki sıralı listeyi birleştir


14

Sıralamayı Birleştir

Bu meydan okumada, birleştirme sıralama birleştirme alt yordamını uygulayacak. Özellikle, her biri artan sırada sıralanmış ve bunları artan sırada sıralanmış tek bir listede birleştiren iki liste alan bir işlev veya program veya fiil veya benzeri oluşturmalısınız. Gereksinimler:

- Algoritmanız girişin boyutunda asimptotik olarak doğrusal bir zaman almalıdır. Lütfen O (n ^ 2) solüsyonları vermeyi bırakın.

  • Bir listeyi sıralayabilen, bir listeyi birleştirebilen veya buna benzer herhangi bir yerleşik işlevi kullanamazsınız. Yazarın takdirine bağlı.
  • Kod, tekrarlanan öğeleri işleyebilmelidir.
  • Boş listeler için endişelenme.

Örnekler:

merge([1],[0,2,3,4])
[0,1,2,3,4]

merge([1,5,10,17,19],[2,5,9,11,13,20])
[1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20]

Bu , bu yüzden en kısa kod kazanabilir!


Bir liste içinde mi yoksa sadece iki liste arasında mı yinelenen öğeleri ele almalıyız?
Keith Randall

Her ikisini de söyleyelim. Fikir, bunu birleştirme sıralaması yapmak için kullanabilmenizdir.
isaacg

Giriş dizilerini tıkamak mı?
skibrianski

3
Algoritmanın nasıl yorumlanacağından emin değilim asimtotik olarak doğrusal bir süre gerekir . Algoritmalar zaman almaz, uygulamalar yapar. Golfscript cevabımın yürütme süresi Ruby yorumlayıcıyla O (korkutucu), ancak Online Golfscript Test Cihazı çok daha iyi davranıyor ve aslında doğrusal olabilir (kaynak kodu olmadan gerçek bir anlatım yolu yok). b=a;b=b.lengthDemek istediğim : dizinin tamamını çoğaltabilir a(ve her öğe için yürütüldüğünde O (n ^ 2) süresiyle sonuçlanabilir) veya yalnızca diziye (O (n) saat) başvuruyu çoğaltabilir. Hangisi önemlidir?
Dennis

1
Sanırım bu gibi durumlarda, bunu anlamak için elinizden gelenin en iyisini yapın, ancak dürüstçe söyleyemiyorsanız, bahsettiğiniz ikinci alternatif gibi, işlerin güzel çalıştığını varsayabilirsiniz. Dilinizde standart bir tercüman yoksa, tercümanın iyi çalıştığını varsayabilirsiniz.
isaacg

Yanıtlar:


8

Rebmu ( 35 32 karakter)

u[iG^aNXa[rvA]apGtkFaM?fA]apGscA

Ölçek

>> rebmu/args [u[iG^aNXa[rvA]apGtkFaM?fA]apGscA] [[1 5 10 17 19] [2 5 9 11 13 20]] 
== [1 2 5 5 9 10 11 13 17 19 20]

>> rebmu/args [u[iG^aNXa[rvA]apGtkFaM?fA]apGscA] [[2 5 9 11 13 20] [1 5 10 17 19]] 
== [1 2 5 5 9 10 11 13 17 19 20]

hakkında

Rebmu , kısaltma gerektiren durumlar için düzenli kodun 'mantarlaştırılmasına' izin veren bir Rebol lehçesidir. Unmushed, kod biraz şöyle çalışır:

u [                     ; until
    i g^ a nx a [       ; if greater? args next args
       rv a             ; reverse args
    ]                   ; (we want the block containing the next value first)

    ap g tk f a         ; append output take first args
    m? f a              ; empty? first args
]                       ; (first block is now empty)

ap g sc a               ; append output second args
                        ; (add the remainder of the second)

Bu, O (n) gereksinimini karşılayana kadar, blok en fazla girişin uzunluğu kadar çok ilmeklediğine inanıyorum (ve reversesadece blokların değil, giriş bloklarının konteynerinin sırasını değiştirir). Kullanmak takebelki bir özgürlüktür, ancak yine de küçük bir verimlilik vuruşu.

Rebol ( 83 75 karakter)

Sadece biraz farklı: Rebol'da, yollar firstveya ' dan daha kısa bir ifadedir second. aiki bloğu içeren giriş bloğudur:

until[if a/2/1 < a/1/1[reverse a]append o:[]take a/1 tail? a/1]append o a/2

5

OP'nin çözümleri:

Haskell 49 44 40

k@(p:r)%l@(q:s)|p>=q=q:k%s|0<1=l%k
a%_=a

Python 131 105 101 99 93

@Evpok sayesinde:

f=lambda u,v:v and(v[-1]<u[-1]and f(v,u)or[b.append(a)for a,b in[(v.pop(),f(u,v))]]and b)or u

1
a%b=a++bAna karakter eşleşmesinden sonra, birkaç karakteri tıraş edecek boş listeleri işlemek için yazabilirsiniz .
swish

ilk listenin içeriği biterse Haskell çözümü başarısız olmaz mı?
John Dvorak

İlk işleve bakarsanız, yinelenen olarak kısaltılmış listeye sahip işlevi ikinci bağımsız değişken olarak, uzatılmış listeyi de ilk bağımsız değişken olarak çağırır ya da bağımsız değişkenleri değiştirir. Bu nedenle, ilk argüman asla kısalmaz. OP tarafından boş başlamadığı için, asla boşalmayacaktır.
isaacg

4

Python (79)

from itertools import*
def m(*a):
 while any(a):yield min(compress(a,a)).pop(0)

Python (95, jeneratör döndürmemize izin verilmiyorsa)

from itertools import*
def m(*a):
 r=[]
 while any(a):r+=[min(compress(a,a)).pop(0)]
 return r

Itertools tüm dünyevi sorunların çözümüdür.

Bonus: Bunlardan ikisi keyfi sayıda listede çalışır ve boş listeler hakkında endişelenir (olduğu gibi, 2 boş liste alırlar ve boş bir liste döndürürler veya 1 boş ve 1 boş olmayan liste alırlar, ve boş olmayanı döndürürler. Verilmeyen 2 özelliğin bir başka özelliği de argüman olmadan çalışır ve boş bir liste döndürür.)

Ungolfed:

from itertools import *  # Import all items from itertools
def m(*a):               # Define the function m, that takes any number of arguments, 
                         #  and stores those arguments in list a
    r=[]                 # Create an empty list r                         
    while any(a):        # While any element in a returns True as value:
        b=compress(a,a)  # Remove any element from a that isn't True (empty lists)
                         #  The example in the official documentation is this one:
                         #  compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
        c=min(b)         # Sort the lists by first value, and take the first one of these.
        d=c.pop(0)       # Take the first element from c
        r.append(d)      # Append this first element to r
    return r             # Gives back r

Jeneratörsüz çözümlerinizde (her seferinde 4 karakter tasarrufu sağlar) r+=[...]yerine kullanınr.append(...)
hlt

Bunun herhangi bir suçunu kastetmiyorum, ancak cevabınız özellikle golf için yapılan değişikliklerle başka bir dilde kod içeriyorsa, bunu aşağıya indireceğim. Bu bir utanç, gerçek python cevapları iyi.
undergroundmonorail

Onları farklı gönderilere ayırırsanız, python olanını oylayacağım.
undergroundmonorail

4
@undergroundmonorail Tüm GolfScript cevaplarını indiriyor musunuz?
Evpok

1
@Evpok Şimdi bahsettiğinize göre, metaya da atabilir ve orada ne söylemek zorunda olduklarını görebilir.
Aprıʇǝɥʇuʎs

3

C - 75

Bu, NULLsonlandırılmış diziler üzerinde çalışır int *, ancak işaretçiler için uygun karşılaştırma işlevini **b < **a(örn strcmp(*b, *a) < 0.) Kullanarak ikame etmek için eşit derecede iyi çalışır .

void m(int**a,int**b,int**c){while(*a||*b)*c++=!*a||*b&&**b<**a?*b++:*a++;}

Ungolfed:

void merge(int **a, int **b, int **c)
{
    while(*a || *b)
        *c++ = !*a || *b && **b < **a
            ? *b++
            : *a++;
}

3

Golfscript, 29 27 30 29 26 bayt

~{.0=@.0=@<{}{\}if(@@.}do;~]p

veya

~{.0=@.0=@>{\}*(@@.}do;~]p

Nasıl çalışır

Komuta

golfscript merge.gs <<< '[2 3] [1 4]'

aşağıdaki gibi işlenir:

~            # Interpret the input string.
             #
             # STACK: [2 3] [1 4]
{            #
    .@=0.@=0 # Duplicate the two topmost arrays of the stack and extract their first 
             # elements. This reverses the original order of the first copy.
             #
             # STACK: [1 4] [2 3] 2 1
             #
    >        # Check if the respective first elements of the arrays are ordered.
             #
             # STACK: [1 4] [2 3] 1
             #
    {\}*     # If they are not, swap the arrays. This brings the array with the smallest
             # element to the top of the stack.
             #
             # STACK: [2 3] [1 4]
             #
    (@@      # Shift the first element of the array on top of the stack and rotate it
             # behind the arrays.
             #
             # STACK: 1 [2 3] [4]
             #
    .        # Duplicate the topmost array.
             #
             # STACK: 1 [2 3] [4] [4]
             #
}do          # Repeat this process if the array is non-empty.
             #
             # STACK: 1 [2 3] [4] -> 1 2 [4] [3] -> 1 2 3 [4] []
             #
;~           # Delete the empty array from the stack and dump the non-empty array.
             #
             # STACK: 1 2 3 4
             #
]p           # Combine all elements on the stack into a single array, the to a string and
             # print.

Çıktı:

[1 2 3 4]

Dizilerin yığın halinde çoğaltılması onu O (n ^ 2) yapar mı?
swish

@swish: Ben bilgisayar bilimcisi değilim ama bunun uygulamaya bağlı olduğunu söyleyebilirim. Tercüman aslında tüm dizileri çoğaltırsa, sanırım öyle yapar.
Dennis

Çok benzer diziler (örn. [1 1 1 ... 2]Ve ) için önceki sürüm O (n ^ 2) idi [1 1 1 ... 3], çünkü dizileri karşılaştırmak (ilk öğeleri yerine) bu durumda çok yavaş olacaktır.
Dennis

Yeni sürümde gerçekleşen tek dizi işlemi, çoğaltma, değiştirme ve yığın üzerinde döndürmedir. Çoğaltılan diziler yalnızca tek öğeleri ayıklamak ve boşlukları boşluksuzluk için test etmek için kullanıldığından (Golfscript'teki her iki yıkıcı işlem), yukarıdaki kod O (n) zamanda çalıştırılabilir (referansları çoğaltarak, takas ederek ve döndürerek) dizileri). Gerçek performans tercümana bağlıdır.
Dennis

2

J - 42 33

Buradan değiştirilmiş sürüm + @algorithmshark'ın yorumu

k=:(m}.),~0{]
m=:k~`k@.(>&{.) ::,

kher iki dizinin birleştirilmiş kuyruklarına doğru dizinin başını ekler. k~aynıdır, ancak diziler çevrilir. (>&{.)kafaları karşılaştırıyor. Dizilerden biri boşsa kod bir hata atar, bu durumda yalnızca birleştirme işlevini döndürürüz ,.


Beri o 'Küstah /:~ a,byasak cevap (birlikte olan [:/:~,), sen misin içermez kısa cevap ediyoruz çekim /:, doğru mu?
Dane

Sorunun "Boş listeler için endişelenme" yazdığını belirteceğim.
Dane

@Dane Özyinelemenin durması için gereken boşluk testi.
swish

m=:k~`k@.(>&{.)`,@.(0=*&#)2 karakter tasarruf eder.
algorithmmshark

Aslında, her şeyi 33 karaktere düşürebilirsiniz: k=:(m}.),~0{]ve m=:k~`k@.(>&{.) ::,. Biz kullanmak 0{listesi boşken hata atmak ve sonra o hatayı ve çıkış yakalamak ,.
algorithmmshark

2

JavaScript (ES6), 69 79 bayt

f=(a,b,c=[])=>(x=a[0]<b[0]?a:b).length?f(a,b,c.concat(x.shift())):c.concat(a,b)

Nasıl çalışır

f = (a, b, c = []) =>          // `f' is a function that takes arguments `a', `b' and `c' -
                               // `c' defaults to `[]' - which returns the following
                               // expression:
                               //
 (x = a[0] < b[0] ? a : b)     // Store the array among `a' and `b' with the smaller first 
                               // element in `x'.
                               //
 .length ?                     // If it's non-empty,
                               //
  f(a, b, c.concat(x.shift())) // append the first element of array `x' to array `c' and run
                               // `f' again;
                               //
  : c.concat(a,b)              // otherwise, append the arrays `a' and `b' to `c'.
                               //
)

Dizileri <f([123, 456, 789], [1, 2, 3, 4, 5]) => [1, 123, 2, 3, 4, 456, 5, 789]
işleçle

@nderscore: Doğru. Yine de işe yaramazdı, çünkü tüm dizileri karşılaştırmak O (n) olmayabilir. Aynı şey, dizinin tamamını bir dizeye dönüştürmek zorunda kalan boşluk testi için de geçerli gibi görünüyor.
Dennis

Evet, dizi-> dize türü dönüşüm için big-o ne olduğundan emin değilim.
nderscore

1
Bir diziyi birleştirmek []ve sonra dizeye dönüştürmek O (n) süresi gerektirir. Dizinin tüm n öğesi için bir kez yapılması O (n ^ 2) zaman alır.
Dennis

Mantıklı. Anladım.
nderscore

2

Python (63) (69) (71)

def m(a,b):
 if a[0]>b[0]:a,b=b,a
 return[a.pop(0)]+(m(a,b)if a else b)

OP'nin diğer cevapların çalışma süreleri hakkındaki yorumlarını görmeden önce bunu yazdım, bu yüzden algoritmada O (n) olan ama uygulamada olmayan başka bir çözüm.


Hangi algoritmaların O (1) gibi dizilerin önünden alıntıları vardır? Liste karşılaştırmalarında hangi algoritmalar O (1) alır? Ayrıca, daha başka ... eğer ... başka ... ve ... veya ...
isaacg

@isaacg Vur, muhtemelen O (n) liste karşılaştırmasını yapan tekrarları unutmuştum. Bu optimizasyonu 6 karakter daha yaptım. Bağlantılı bir listede O (1) 'den çıkarabilir ve öne ekleyebilirsiniz. Nasıl döndürebileceğinizi görmüyorum ... ve ... ya da ... değeri döndürerek güzel oynayın
xnor

Tamam, şimdi nasıl yapılacağını görüyorum ... ve ... ya da ... ama ihtiyaç duyulan ebeveynler nedeniyle karakterleri kaydetmiyor. return[a.pop(0)]+(a and m(a,b)or b)
xnor

@isaacg: O (1) 'de bir dizinin önünü çıkarmak için, dizi işaretçisini ikinci öğeyi gösterecek şekilde artırın ve ilk öğe tarafından kullanılan belleği serbest bırakın.
Wrzlprmft

@Wrzlprmft Dizinin her iki öğesi de boolean değerine bakılmaksızın değerlendirildiği için dizi hile elde edemedim, bu da boş bir liste olduğunda bir hata atar. "Tembel dizi" yapmanın kısa bir yolu var mı?
xnor

2

Haskell, 35 bayt

a#b@(c:d)|a<[c]=b#a|0<1=c:a#d
a#_=a

Haskell, 30 bayt (rakip olmayan)

Bu rakip olmayan sürüm yalnızca ayrık elemanlara sahip ave bvarsa doğrusal çalışma zamanını garanti eder ; aksi halde hala düzgün çalışır ancak ikinci dereceden zamanı kullanabilir.

a#b|a<b=b#a|c:d<-b=c:a#d
a#_=a

2

PHP 91 98 91 bayt

edit # 1: Empty $b, kıvırcık ayraçlarda (+7) ek bir koşul gerektirir.
düzenleme # 2: küçük golfings
düzenlemek # 3: ikinci sürüm eklendi

oldukça basit. En güzel kısmı içindeki üçlü array_shift
(bu kıvrımlar olmadan denerseniz başarısız olur)

function m($a,$b){for($c=[];$a|$b;)$c[]=array_shift(${$a&(!$b|$a[0]<$b[0])?a:b});return$c;}

veya

function m($a,$b){for($c=[];$a|$b;)$c[]=array_shift(${$a?!$b|$a[0]<$b[0]?a:b:b});return$c;}

ungolfed

function m($a,$b)
{
    $c=[];
    while($a||$b)
    {
        $c[] = array_shift(${
            $a&&(!$b||$a[0]<$b[0])
                ?a
                :b
        });
#       echo '<br>', outA($a), ' / ', outA($b) , ' -> ', outA($c);
    }
    return $c;
}

Ölçek

$cases = array (
    [1],[0,2,3,4], [0,1,2,3,4],
    [1,5,10,17,19],[2,5,9,11,13,20], [1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20],
    [1,2,3],[], [1,2,3],
    [],[4,5,6], [4,5,6],
);
function outA($a) { return '['. implode(',',$a). ']'; }
echo '<table border=1><tr><th>A</th><th>B</th><th>expected</th><th>actual result</th></tr>';
while ($cases)
{
    $a = array_shift($cases);
    $b = array_shift($cases);
#   echo '<hr>', outA($a), ' / ', outA($b) , ' -> ', outA($c);
    $expect = array_shift($cases);
    $result=m($a,$b);
    echo '<tr><td>',outA($a),'</td><td>',outA($b),'</td><td>', outA($expect), '</td><td>', outA($result),'</td></tr>';
}
echo '</table>';

Ben öyle olmadığını basit hale neden anlayamadık $a&(!$b|$a[0]<$b[0])?$a:$byerine${$a&(!$b|$a[0]<$b[0])?a:b}
Jörg Hülsermann

1
@ JörgHülsermann array_shiftParametre referans olarak kullanılır. Bu bir değişken olmalıdır; bir ifade işe yaramaz.
Titus

1

Git, 124 karakter

func m(a,b[]int)(r[]int){for len(a)>0{if len(b)==0||a[0]>b[0]{a,b=b,a}else{r=append(r,a[0]);a=a[1:]}};return append(r,b...)}

1

JavaScript - 133

function m(a,b){c=[];for(i=j=0;i<a.length&j<b.length;)c.push(a[i]<b[j]?a[i++]:b[j++]);return c.concat(a.slice(i)).concat(b.slice(j))}

OP'lerle aynı yaklaşım.


1

perl, 87 karakter / perl 5.14, 78 + 1 = 79 karakter

Bu uygulama girdi dizisi referanslarını zorlar. Bunun dışında, oldukça basittir: her iki dizinin de bir şeyleri varken, ikisinin altını kaydırın. Ardından kalan bitlerle birleştirilen birleştirilmiş biti döndürün (@ $ x veya @ $ y'den yalnızca biri kalır). Düz perl5, 87 karakter:

sub M{($x,$y,@o)=@_;push@o,$$x[0]>$$y[0]?shift@$y:shift@$x while@$x&&@$y;@o,@$x,@$y}

Perl 5.14.0 ve onun yeni dizili diziref kayması: 78 karakter + 1 karakter penaltı = 79 karakter:

sub M{($x,$y,@o)=@_;push@o,shift($$x[0]>$$y[0]?$y:$x)while@$x&&@$y;@o,@$x,@$y}

*yerine &&bir bayt kaydeder. Ve daha da fazlasısub M{map{shift(!@$x+@$y*($$y[0]<$$x[0])?$y:$x)}map@$_,($x,$y)=@_}
user2846289

@VadimR, vay. iyi iş. Devam edin ve isterseniz - bir dizi üzerine basmak yerine asla çift harita hile yapmayı düşünmezdim.
skibrianski

1

Java: 144

Bu oldukça basit. İki diziyi alıp bir, birleştirilmiş sürüm, golf edilmiş ve derleme sarmalayıcısı olmadan döndüren bir işlev:

int[]m(int[]a,int[]b){int A=a.length,B=b.length,i,j;int[]c=new int[A+B];for(i=j=0;i+j<A+B;c[i+j]=j==B||i<A&&a[i]<b[j]?a[i++]:b[j++]);return c;}

Ungolfed (derlenebilir ve çalıştırılabilir sarıcı ile):

class M{
    public static void main(String[]args){
        int[]a=new int[args[0].split(",").length];
        int i=0;
        for(String arg:args[0].split(","))
            a[i++]=Integer.valueOf(arg);
        int[]b=new int[args[1].split(",").length];
        int j=0;
        for(String arg:args[1].split(","))
            b[j++]=Integer.valueOf(arg);
        int[]c=(new M()).m(a,b);
        for(int d:c)
            System.out.printf(" %d",d);
        System.out.println();
    }
    int[]m(int[]a,int[]b){
        int A=a.length,B=b.length,i,j;
        int[]c=new int[A+B];
        for(i=j=0;i+j<A+B;c[i+j]=j==B||i<A&&a[i]<b[j]?a[i++]:b[j++]);
        return c;
    }
}

Örnek yürütmeler:

$ javac M.java
$ java M 10,11,12 0,1,2,20,30
 0 1 2 10 11 12 20 30
$ java M 10,11,12,25,26 0,1,2,20,30
 0 1 2 10 11 12 20 25 26 30

Kısaltmak için herhangi bir ipucu takdir edilecektir.


1

Scala, 97 bayt

O (n) ile özyinelemeli çözelti. Kodu kısaltmak için bazen değiştirilebilir 2 parametre değiştirilerek bir işlem yapılır, yani f (a, b) f (b, a) 'yı çağırır.

type L=List[Int];def f(a:L,b:L):L=if(a==Nil)b else if(a(0)<=b(0))a(0)::f(a.drop(1),b) else f(b,a)

Ungolfed:

type L=List[Int]

def f(a:L, b:L) : L =
  if (a == Nil)
    b 
  else 
    if (a(0) <= b(0))
      a(0) :: f(a.drop(1), b) 
    else
      f(b,a)

A boş değilse, ancak b boşsa istisna
Dan Osipov

1

APL (32)

{⍺⍵∊⍨⊂⍬:⍺,⍵⋄g[⍋g←⊃¨⍺⍵],⊃∇/1↓¨⍺⍵}

Açıklama:

{⍺⍵∊⍨⊂⍬                               if one or both of the arrays are empty
        :⍺,⍵                           then return the concatenation of the arrays
             ⋄g[⍋g←⊃¨⍺⍵]              otherwise return the sorted first elements of both arrays
                          ,⊃∇/        followed by the result of running the function with
                               1↓¨⍺⍵}  both arrays minus their first element

1

LISP, 117 bayt

Algoritma , girişlerdeki en kısa listenin uzunluğu olan n + 1yinelemelerle sona erer n.

(defun o(a b)(let((c(car a))(d(car b)))(if(null a)b(if(null b)a(if(< c d)(cons c(o(cdr a)b))(cons d(o a(cdr b))))))))


0

Python - 69 bayt

def m(A,B):
    C=[]
    while A and B:C+=[[A,B][A>B].pop(0)]
    return C+A+B

Giriş ve çıkış sırası azalacaksa, bu 61 bayta kısaltılabilir :

def m(A,B):
    C=[]
    while A+B:C+=[[A,B][A<B].pop(0)]
    return C

Ve eğer jeneratörlere izin verilirse 45 bayta kadar :

def m(A,B):
    while A+B:yield[A,B][A<B].pop(0)

Bu kesinlikle O (n) değildir. .pop (0) ve + = hem O (n) kez yaptığınız O (n) işlemidir.
isaacg

Şimdiye kadar listelerin Python'da liste olarak uygulanmadığını ve o zaman bile pop(0)O (1) ' +=de uygulanabileceğini ve en azından O (n)' den daha iyi uygulanabileceğini bilmiyordum (bağlantıya bakınız). Bu arada, çözümünüz benimki kadar sık kullanır +=(yani appendve extend). Her neyse, tüm bunlar bir uygulama sorusu (bildiğim kadarıyla), bu yüzden listelerin liste olarak uygulandığı (kurgusal) bir Python uygulamasında, işlevim O (n). Sonunda sorunuz algoritmanın O (n) olmasını gerektirdi ve benim.
Wrzlprmft

Aslında, ekleme ve genişletme python'da + = 'den farklı uygulanır. + = yeni bir liste oluştururken .append ve .extend varolan listeyi değiştirir.
isaacg

0

Perl 6: 53 karakter

sub M(\a,\b){{shift a[0]>b[0]??b!!a}...{a^b},a[],b[]}

XOR ( ) doğru olana kadar hangisinden küçük aveya bküçük bir değere sahip olun . Sonra kalanları döndürün , dizileri listeye ( ) düzleştirin ( ).aba^b[]a[],b[]

Bir dizinin başlangıcından kaymanın O (n) olduğu varsayılarak, en kötü durum iki karşılaştırma ve eleman başına bir kaydırmadır, bu nedenle algoritma O (n) olur.


0

JavaScript (ES5) 90 86 90 bayt

function f(a,b){for(o=[];(x=a[0]<b[0]?a:b).length;)o.push(x.shift());return o.concat(a,b)}

edit: (90 -> 86) Üçlü for döngüsü durumuna taşındı. Fikir Dennis'den çalındı.

edit: (86 -> 90) O (n) şartı kırdığı için Array to String cast kaldırıldı .


0

Mathematica, 137 135

m[a_,b_]:=(l=a;Do[Do[If[b[[f]]<=l[[s]],(l=Insert[l,b[[f]],s];Break[]),If[s==Length@l,l=l~Append~b[[f]]]],{s,Length@l}],{f,Length@b}];l)

Giriş:

m[{2,2,4,6,7,11},{1,2,3,3,3,3,7}]

Çıktı:

{1, 2, 2, 2, 3, 3, 3, 3, 4, 6, 7, 7, 11}

Ungolfed:

mergeList[a_, b_] := (
    list = a;
    Do[
        Do[(
            If[
                b[[f]] <= list[[s]],
                (list = Insert[list, b[[f]], s]; Break[]),
                If[
                    s == Length@list,
                    list = list~Append~b[[f]]
                ]
        ]),
        {s, Length@list}
    ],
    {f, Length@b}
    ];
    list
)

Muhtemelen daha iyisini yapabilirdi.


m[a:{x___,y_},b:{___,z_}]:=If[y<z,b~m~a,{x}~m~b~Join~{y}];{}~m~b_=b;
alephalpha

0

R, 80

Scala ve diğer dillerde olduğu gibi aynı çözüm. X [-1] 'in O (1) olduğundan emin değilim.

f=function(a,b)if(length(a)){if(a[1]<=b[1])c(a[1],f(a[-1],b))else f(b,a)}else b

0

Mathematica, 104 bayt

Reap[{m,n}=Length/@{##};i=k=1;Do[If[k>n||TrueQ[#[[i]]<#2[[k]]],Sow@#[[i++]],Sow@#2[[k++]]],n+m]][[2,1]]&

Anonim işlev, iki giriş listesinin uzunluğunu değişkenlerde depolar mve ndaha sonra Dodöngünün her yinelemesi, Sowo listenin sayacını ( ibirincisi, kikincisi için) bir arttırır. Sayaçlardan biri listenin uzunluğunu aşarsa, Ififade her zaman Sowdiğer listeden bir öğe olur. n+mOperasyonlardan sonra tüm elemanlar halledildi. Reapveya [[2,1]]çıktısının bir kısmı , Sown sırayla oldukları öğelerin listesidir .

İç emin değilim (bir listenin bir bölümüne bir O(1)işlem erişiyor ya da değil), ama zamanlamaları girdi listesi uzunluğu açısından makinemde oldukça doğrusal görünüyordu.

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.