Dizeden benzersiz öğeleri kaldırma


12

Bu soruya geldim, çünkü dizede benzersiz karakterler bulmak çok yaygın bir kullanım örneği gibi görünüyor. Ama ya onlardan kurtulmak istiyorsak?

Giriş yalnızca küçük harfli alfabe içerir. Yalnızca a ile z arasındaki harfler kullanılır. Giriş uzunluğu 1 ila 1000 karakter arasında olabilir.

Örnek:
input: helloworld
output: llool

Amaç: En kısa kod kazanır
Dil: TIOBE dillerinin ilk 20'sinden herhangi biri

Yanıtlar:


7

Perl, 28 24 karakter ('p' seçeneği için 1 içerir)

s/./$&x(s!$&!$&!g>1)/eg

Kullanımı:

> perl -pe 's/./$&x(s!$&!$&!g>1)/eg'
helloworld
llool

İlk başta bunu negatif ileriye bakma ve olumsuz geriye bakma ile yapabileceğimi düşündüm, ancak olumsuz bakışların sabit bir uzunluğa sahip olması gerektiği ortaya çıktı. Bunun yerine iç içe normal ifadelere gittim. İçin teşekkür grubu mafya için $&ucu.


+1. Saf bir şekilde bu cevabı Ruby cevabımla alabileceğimi düşündüm.
Steven Rumbalski

Çince metin üzerinde bu çalıştı ve hile yapmadı. = (
ixtmixilix

@ixtmixilix - ile daha sonra çalıştırmak perl -CDSseçenek
güruh

@ixtmixilix Unicode ve Perl'in desteği hakkında korkuyorum, Çince metinlerle çalışmasını sağlayacak bir yol önerdim. Neyse ki benim için soru sadece a'dan z'ye küçük harf diyor.
Gareth

1
Tümünü değiştir $1ile $&ve parantez birkaç çiftleri kaybedebilir.
mafya

12

(GolfScript, 15 13 karakter)

:;{.;?);>?)},

GolfScript ilk 20'den değil, GolfScript içermeyen bir codegolf ... ( kendiniz çalıştırın )

Önceki Sürüm: ( komut dosyasını çalıştır )

1/:;{;\-,;,(<},

1
:;? Kasten yenileri karıştırmaya çalışıyorsunuz, değil mi? ;)
Peter Taylor

@PeterTaylor Haklısın. Bir tane seçmeliydim )- o zaman bir surat yapar :). Ne yazık ki, 1 rakamını bile ortadan kaldırmanın bir yolunu bulamadım. (GolfScript yeni başlayanlar için not: koddaki herhangi birini ;bir x(veya başka bir harf veya rakam - veya komut dosyasında aksi halde kullanılmayan herhangi bir karakterle değiştirebilirsiniz). Bu özel durumda ;sadece bir değişken adı vardır ve "pop and at" anlamına gelmez. GolfScript'te neredeyse tüm jetonlar zaten değişkenlerdir ve önceden tanımlanmış semboller kullanmak komut dosyalarını yabancıların ;-) için daha da okunmaz hale getirmenin harika bir yoludur.
Howard

Başka bir 13 karakterlik çözüm::a{]a.@--,(},
Ilmari Karonen

7

J, 12 karakter

Geçerli bir Perl cevabı girdikten sonra, geçersiz (TIOBE ilk 20'de olmayan dil) cevabı.

a=:#~1<+/@e.

Kullanımı:

   a 'helloworld'
llool

aYalnızca benzersiz olmayan öğeler veren bir fiili bildirir .



4

Yakut 46 40 36

gets.chars{|c|$><<c if$_.count(c)>1}

Satır içi sve $_ikinci görünüm için kullanırsanız 4 karakter kaydedebilirsiniz (önceki boşluk daha sonra dağıtılabilir).
Howard

@Howard: İyi yakaladın. Teşekkürler. Ruby ile neredeyse sıfır deneyimim var.
Steven Rumbalski

2

Perl 44

$l=$_;print join"",grep{$l=~/$_.*$_/}split""

Yürütme:

perl -lane '$l=$_;print join"",grep{$l=~/$_.*$_/}split""' <<< helloworld
llool


2

Python 2,7 ( 52 51), Python 3 (52)

Çok kısa olmasını beklemiyordum.

2.7: a=raw_input();print filter(lambda x:a.count(x)>1,a)

3.0: a=input();print''.join(i for i in a if a.count(x)>1)

raw_input(): girdiyi dize olarak sakla ( input()= eval(raw_input()))
(Python 3.0: input()dönüştürüldü raw_input())

filter(lambda x:a.count(x)>1,a): Birden fazla abulunursa içindeki tüm karakterleri filtreleyin a( a.count(x)>1).


Bunun yerine piton 3 kullanıyorsanız, kullanabilirsiniz input()ziyade raw_input(). Kapatma köşeli ayraç için bir karakter eklemek zorunda olmanıza rağmen print, python 3'te bir işlev olduğu için
Strigoides

@Strigoides: Cevabıma bir Python 3 kod snippet'i ekledim.
beary605

Python 3'ün filtresi yineleyici döndürüyor ... Yapmanız gerekecek''.join(...)
JBernardo

@JBernardo: :( Dang. Beni bilgilendirdiğiniz için teşekkür ederim. Gördüğünüz gibi 3.0 kullanmıyorum.
beary605

2

sed ve coreutils (128)

Verilen bu TIOBE listesinin bir parçası değil, ama eğlenceli (-:

<<<$s sed 's/./&\n/g'|head -c -1|sort|uniq -c|sed -n 's/^ *1 (.*)/\1/p'|tr -d '\n'|sed 's:^:s/[:; s:$:]//g\n:'|sed -f - <(<<<$s)

Golfçü olmayan sürüm:

s=helloworld
<<< $s sed 's/./&\n/g'        \
| head -c -1                  \
| sort                        \
| uniq -c                     \
| sed -n 's/^ *1 (.*)/\1/p'   \
| tr -d '\n'                  \
| sed 's:^:s/[:; s:$:]//g\n:' \
| sed -f - <(<<< $s)

açıklama

İlk sed, girişi satır başına bir karaktere dönüştürür. İkinci sed yalnızca bir kez oluşan karakterleri bulur. Üçüncü sed, benzersiz karakterleri silen bir sed komut dosyası yazar. Son sed, oluşturulan komut dosyasını yürütür.


2

Brachylog (v2), 8 bayt

⊇.oḅlⁿ1∧

Çevrimiçi deneyin!

İşlev gönderme. Teknik olarak rakipsizdir, çünkü sorunun hangi dillerin rekabet etmesine izin verildiği konusunda bir sınırlaması vardır (ancak, diğer bazı cevaplar zaten kısıtlamayı ihmal etmiştir).

açıklama

⊇.oḅlⁿ1∧
⊇         Find {the longest possible} subset of the input
  o       {for which after} sorting it,
   ḅ        and dividing the sorted input into blocks of identical elements,
    lⁿ1     the length of a resulting block is never 1
 .     ∧  Output the subset in question.

Neden tüm çözümlerinizi CW yapıyorsunuz?
Shaggy

1
@Shaggy: a) çünkü onları düzenleyen diğer insanlarla iyiyim, b) oyları kaldırılırsa itibar kazanmamak için. Genel olarak, Stack Exchange'in gamififkasyonunun siteye büyük bir zarar verdiğini düşünüyorum - bazen temsilciyi geliştirmek için yapabileceğiniz eylemler ile siteyi gerçekten geliştirmek için atabileceğiniz eylemler arasında negatif bir korelasyon vardır. Buna ek olarak, yüksek bir itibar saymak berbattır; site yönetici görevleri yapmak için sizi rahatsız ediyor ve yaptığınız her şey künt bir araçtır (örneğin düşük rep'de olduğunuzda bir düzenleme önerebilirsiniz , yüksek rep'de sadece zorlanır).
ais523

2

Japt , 6 5 bayt

ÆèX É

@Oliver sayesinde -1 bayt

Çevrimiçi deneyin!


2
Japt'e Hoşgeldiniz! Aslında bir kısayol var o@:Æ
Oliver

@Oliver Kaçırdığım başka bir kısayol, havalı, teşekkürler :)
Quintec

@Oliver, daha iyi bir soru feck vermedi nasıl ben onu özlüyorum ?! : \
Shaggy

1

Python (56)

İşte Python'da başka (birkaç karakter daha uzun) alternatif:

a=raw_input();print''.join(c for c in a if a.count(c)>1)

Çıktıyı bir liste olarak kabul ederseniz (örn. ['l', 'l', 'o', 'o', 'l']), 49 karaktere kadar kaynatabiliriz :

a=raw_input();print[c for c in a if a.count(c)>1]

Hey, >1iyi bir fikir! Bunu çözümüme dahil edebilir miyim?
beary605

@ beary605 Hiç sorun değil - bir karakteri düzeltmenin kolay yolu: D
arshajii

1

Mathematica 72 63

Tamam, Mathematica en iyi 20 dil arasında değil, ama yine de partiye katılmaya karar verdim.

x girdi dizesidir.

"" <> Select[y = Characters@x, ! MemberQ[Cases[Tally@y, {a_, 1} :> a], #] &]

1

Perl (55)

@x=split//,<>;$s{$_}++for@x;for(@x){print if($s{$_}>1)}

Stdin'den okur.


1

77 karakter

Func<string,string>F=s=>new string(s.Where(c=>s.Count(d=>c==d)>1).ToArray());

Çıktıyı dizi olarak kabul ederseniz 65 karaktere kadar kaynar :

Func<string,char[]>F=s=>s.Where(c=>s.Count(d=>c==d)>1).ToArray();

1

Ocaml, 139 133

ExtLib'in ExtString.String'ini kullanır

open ExtString.String
let f s=let g c=fold_left(fun a d->a+Obj.magic(d=c))0 s in replace_chars(fun c->if g c=1 then""else of_char c)s

Golfsiz sürüm

open ExtString.String
let f s =
  let g c =
    fold_left
      (fun a c' -> a + Obj.magic (c' = c))
      0
      s
  in replace_chars
  (fun c ->
    if g c = 1
    then ""
    else of_char c)
  s

İşlev g, s dizesindeki c oluşum sayısını döndürür. İşlev f, oluşum sayısına bağlı olarak tüm karakterleri boş dize veya karakter içeren dize ile değiştirir. Düzenleme: Ben bools :-) iç temsilini kötüye kullanarak kodu 6 karakter kısaltılmış

Oh, ve ocaml TIOBE endeksinde 0 ;-)


f *** TIOBE endeksi.
ixtmixilix

Katılıyorum. Ayrıca, upvote için teşekkürler. Şimdi :-)
ReyCharles

1

PHP - 70

while($x<strlen($s)){$c=$s[$x];echo substr_count($s,$c)>1?$c:'';$x++;}

$ s = 'helloworld' ile.


1

Java 8, 90 bayt

s->{for(char c=96;++c<123;s=s.matches(".*"+c+".*"+c+".*")?s:s.replace(c+"",""));return s;}

Açıklama:

Çevrimiçi deneyin.

s->{                         // Method with String as both parameter and return-type
  for(char c=96;++c<123;     //  Loop over the lowercase alphabet
    s=s.matches(".*"+c+".*"+c+".*")?
                             //   If the String contains the character more than once
       s                     //    Keep the String as is
      :                      //   Else (only contains it once):
       s.replace(c+"",""));  //    Remove this character from the String
  return s;}                 //  Return the modified String

1

PowerShell , 59 bayt

"$args"-replace"[^$($args|% t*y|group|?{$_.Count-1}|% n*)]"

Çevrimiçi deneyin!

Daha az golf:

$repeatedСhars=$args|% toCharArray|group|?{$_.Count-1}|% name
"$args"-replace"[^$repeatedСhars]"

Not: $repeatedCharsbir dizidir. Varsayılan olarak, bir Powershell dizi öğelerini space char ile birleştirirken diziyi dizeye dönüştürür. Yani, normal ifade boşluklar içeriyor (Bu örnekte [^l o]). Giriş dizesi yalnızca harf içerdiğinden, boşluklar sonucu etkilemez.


1

APL (Dyalog Genişletilmiş) , 8 bayt SBCS

Anonim zımni önek fonksiyonu.

∊⊢⊆⍨1<⍧⍨

Çevrimiçi deneyin!

⍧⍨ count-in selfie (bağımsız değişkendeki bağımsız değişken öğelerinin sayısını say)

1< Birinden daha az olan Boole maskesi

⊢⊆⍨ bağımsız değişkeni bu maske ile bölümlendirin (1'lerde yeni bir bölüm başlatmak ve 0'larda kaldırmak)

ϵ nlist (düzleştir)


1

JavaScript, 45 bayt

s=>[...s].filter(c=>s.match(c+'.*'+c)).join``

1

R , 70 bayt

a=utf8ToInt(scan(,''));intToUtf8(a[!a%in%names(table(a)[table(a)<2])])

Çevrimiçi deneyin!

TIOBE ilk 20 dilinden bile kötü bir girişim. İkinci yarıda bir şeylerin yapılabileceğini biliyorum, ama şu anda herhangi bir golf benden kaçıyor.




0

PHP - 137

kod

implode('',array_intersect(str_split($text),array_flip(array_filter(array_count_values(str_split($text)),function($x){return $x>=2;}))));

Normal Kod

$text   = 'helloworld';
$filter = array_filter(array_count_values(str_split($text)), function($x){return $x>=2;});
$output = implode('',array_intersect(str_split($text),array_flip($filter)));

echo $output;

0

PHP - 83 78

<?for($a=$argv[1];$i<strlen($a);$r[$a[$i++]]++)foreach($ras$k=>$c)if($c>1)echo$k

Gelişmiş versiyon:

<?for($s=$argv[1];$x<strlen($s);$c=$s[$x++]) echo substr_count($s,$c)>1?$c:'';

Elbette bunun kapatılması için bildirimlere ihtiyacı var

Edit: @hengky mulyono'dan ilham alan geliştirme

Ben codegolf çok kötüyüm :)


0

C ++, 139 bayt

string s;cin>>s;string w{s}; auto l=remove_if(begin(s),end(s),[&w](auto&s){return count(begin(w),end(w),s)==1;});s.erase(l,end(s));cout<<s;

ungolfed:

#include <algorithm>
#include <string>
#include <iostream>

int main() {
  using namespace std;
  string s;
  cin >> s;
  const string w{s};
  auto l = remove_if(begin(s), end(s), [&w](auto& s) {
                                         return count(begin(w), end(w), s) == 1;
                                       });
  s.erase(l, end(s));
  cout << s;
  return 0;
}
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.