Eindeutige Elemente aus der Zeichenfolge entfernen

12

Ich bin auf diese Frage gestoßen, weil es sehr häufig vorkommt, eindeutige Zeichen in Strings zu finden. Aber was ist, wenn wir sie loswerden wollen?

Die Eingabe enthält nur Kleinbuchstaben. Es werden nur Buchstaben von a bis z verwendet. Die Eingabelänge kann zwischen 1 und 1000 Zeichen liegen.

Beispiel:
input: helloworld
output: llool

Ziel: Kürzester Code gewinnt
Sprache: Eine der Top 20 der TIOBE-Sprachen

user14742
quelle

Antworten:

7

Perl, 28 24 Zeichen (enthält 1 für die Option 'p')

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

Verwendung:

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

Zuerst dachte ich, ich könnte dies mit negativem Look-Ahead und negativem Look-Behind tun, aber es stellt sich heraus, dass negative Look-Behinds eine feste Länge haben müssen. Also habe ich mich stattdessen für verschachtelte reguläre Ausdrücke entschieden. Vielen Dank an Mob für den $&Tipp.

Gareth
quelle
+1. Ich dachte naiv, ich könnte dieses Ding mit meiner Ruby-Antwort aufnehmen.
Steven Rumbalski
Ich habe es mit chinesischem Text versucht und es hat nicht geklappt. = (
ixtmixilix
@ixtmixilix - dann starte perl mit der -CDSOption
mob
@ixtmixilix Ich weiß nicht genug über Unicode und Perls Unterstützung, um einen Weg vorzuschlagen, wie es mit chinesischem Text funktioniert. Zum Glück sagt mir die Frage nur Kleinbuchstaben a bis z.
Gareth
1
Ersetzen Sie alles $1durch $&und Sie können ein paar Klammerpaare verlieren.
Mob
12

(GolfScript, 15 bis 13 Zeichen)

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

GolfScript gehört nicht zu den Top 20, sondern ein Codegolf ohne GolfScript ... ( führen Sie es selbst aus )

Vorgängerversion: ( Skript ausführen )

1/:;{;\-,;,(<},
Howard
quelle
1
:;? Sie versuchen absichtlich, Neulinge zu verwirren, nicht wahr? ;)
Peter Taylor
@PeterTaylor Du hast recht. Ich hätte ein wählen sollen )- es würde es dann zu einem Smiley machen :). Leider habe ich keine Möglichkeit gefunden, die Ziffer 1 zu eliminieren. (Hinweis für GolfScript-Neulinge: Sie können jede Ziffer ;im Code durch eine x(oder einen anderen Buchstaben oder eine Ziffer - oder ein anderes im Skript nicht verwendetes Zeichen) ersetzen . In diesem speziellen Fall ;handelt es sich nur um einen Variablennamen - und hat nicht die Bedeutung "pop and discard". In GolfScript sind sowieso fast alle Token Variablen, und die Verwendung vordefinierter Symbole ist eine großartige Möglichkeit, Skripte für Außenstehende noch unlesbarer zu machen ;-).)
Howard
Eine weitere 13-Zeichen-Lösung::a{]a.@--,(},
Ilmari Karonen
7

J, 12 Zeichen

Nachdem Sie eine gültige Perl-Antwort eingegeben haben, ist hier eine ungültige Antwort (Sprache nicht in den Top 20 von TIOBE).

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

Verwendung:

   a 'helloworld'
llool

Deklariert ein Verb, adas nur nicht eindeutige Elemente ausgibt.

Gareth
quelle
5

GolfScript (14 Zeichen)

:x{{=}+x\,,(},

Online-Demo

Könnte sich nicht qualifizieren, um zu gewinnen, aber es ist nützlich, einen Maßstab zu haben.

Peter Taylor
quelle
4

Ruby 46 40 36

gets.chars{|c|$><<c if$_.count(c)>1}
Steven Rumbalski
quelle
Sie können 4 Zeichen sparen, wenn Sie diese inline eingeben sund $_für den zweiten Auftritt verwenden (der Platz davor ist dann entbehrlich).
Howard
@ Howard: Schöner Fang. Vielen Dank. Ich habe ungefähr keine Erfahrung mit Ruby.
Steven Rumbalski
2

Perl 44

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

Ausführung:

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

K, 18

{x@&x in&~1=#:'=x}
tmartin
quelle
Sie können ein Byte speichern, indem Sie 1<#anstelle von~1=#
J. Sendra den
2

Python 2.7 ( 52 51), Python 3 (52)

Ich hätte nicht gedacht, dass es so kurz ist.

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(): Eingabe als String speichern ( input()= eval(raw_input()))
(Python 3.0: input()wurde in umgewandelt raw_input())

filter(lambda x:a.count(x)>1,a): Durchsuchen Sie alle Zeichen in, awenn sie amehrmals vorkommen ( a.count(x)>1).

beary605
quelle
Wenn Sie Python 3 verwenden stattdessen, können Sie verwenden , input()statt raw_input(). Obwohl Sie ein Zeichen für eine schließende Klammer hinzufügen müssen, ist da printeine Funktion in Python 3.
Strigoides
@ Strigoides: Ich habe meiner Antwort einen Python 3-Codeausschnitt hinzugefügt.
beary605
Der Filter von Python 3 gibt einen Iterator zurück ... Das müssen Sie tun''.join(...)
JBernardo
@JBernardo: :( Dang. Danke, dass du mich benachrichtigt hast. Wie du sehen kannst, verwende ich kein 3.0.
beary605 16.10.12
2

sed und coreutils (128)

Zugegeben, das ist nicht Teil der TIOBE-Liste, aber es macht Spaß (-:

<<<$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)

De-Golf-Version:

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)

Erläuterung

Die erste Sed wandelt die Eingabe in ein Zeichen pro Zeile um. Der zweite Satz findet Zeichen, die nur einmal vorkommen. Third Sed schreibt ein Sed-Skript, das eindeutige Zeichen löscht. Die letzte Sed führt das generierte Skript aus.

Thor
quelle
2

Brachylog (v2), 8 Bytes

⊇.oḅlⁿ1∧

Probieren Sie es online!

Funktionsübergabe. Technisch nicht konkurrierend, da die Frage beschränkt ist, welche Sprachen konkurrieren dürfen (mehrere andere Antworten haben die Einschränkung jedoch bereits ignoriert).

Erläuterung

⊇.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.
ais523
quelle
Warum CW Sie alle Ihre Lösungen?
Shaggy
1
@ Shaggy: a) weil es mir gut geht, wenn andere Leute sie bearbeiten, b) um nicht an Ansehen zu gewinnen, wenn sie sich dafür interessieren. Im Allgemeinen halte ich die Gamififkation von Stack Exchange für einen großen Nachteil für die Website. Manchmal besteht eine negative Korrelation zwischen den Maßnahmen, die Sie zur Verbesserung der Wiederholung ergreifen können, und den Maßnahmen, die Sie zur tatsächlichen Verbesserung der Website ergreifen können. Darüber hinaus ist es zum Kotzen, ein hohes Ansehen zu haben. Die Site fordert Sie immer wieder dazu auf, Verwaltungsaufgaben zu erledigen, und alles, was Sie tun, ist ein stumpfes Instrument (z. B. können Sie bei niedriger Wiederholungszahl eine Bearbeitung vorschlagen , bei hoher Wiederholungszahl wird sie nur erzwungen).
ais523
2

Japt , 6 5 Bytes

ÆèX É

-1 Byte dank @Oliver

Probieren Sie es online!

Quintec
quelle
2
Willkommen bei Japt! Es gibt tatsächlich eine Abkürzung für o@:Æ
Oliver
@ Oliver Eine weitere Verknüpfung, die ich verpasst habe, cool, danke :)
Quintec
@ Oliver, die bessere Frage ist, wie zum Teufel habe ich es vermisst ?! : \
Shaggy
1

Python (56)

Hier ist eine weitere (einige Zeichen länger) Alternative in Python:

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

Wenn Sie die Ausgabe als Liste akzeptieren (z. B. ['l', 'l', 'o', 'o', 'l']), können wir sie auf 49 Zeichen reduzieren :

a=raw_input();print[c for c in a if a.count(c)>1]
arshajii
quelle
Hey, >1ist eine gute Idee! Darf ich das in meine Lösung einbauen?
beary605
@ beary605 Sicher kein Problem - einfache Möglichkeit , einen Charakter aus zu trimmen: D
arshajii
1

Mathematica 72 63

Okay, Mathematica ist nicht unter den Top 20 Sprachen, aber ich habe mich trotzdem dazu entschlossen, der Party beizutreten.

x ist die Eingabezeichenfolge.

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

Perl (55)

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

Liest von stdin.

QuasarDonkey
quelle
1

77 Zeichen

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

Wenn Sie die Ausgabe als Array akzeptieren, werden nur 65 Zeichen ausgegeben :

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

Ocaml, 139, 133

Verwendet ExtLibs ExtString.String

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

Nicht Golf Version

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

Die Funktion ggibt die Anzahl der Vorkommen von c in der Zeichenfolge s zurück. Die Funktionf ersetzt alle Zeichen entweder durch die leere Zeichenfolge oder durch die Zeichenfolge, die das Zeichen enthält, je nach Anzahl der Vorkommen. Edit: Ich habe den Code um 6 Zeichen gekürzt, indem ich die interne Darstellung von Bools missbraucht habe :-)

Oh, und ocaml ist 0 im TIOBE-Index ;-)

ReyCharles
quelle
f *** der TIOBE-Index.
ixtmixilix
Genau. Danke auch für die positive Bewertung. Jetzt kann ich kommentieren :-)
ReyCharles
1

PHP - 70

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

mit Annahme $ s = 'helloworld'.

hengky mulyono
quelle
1

Java 8, 90 Bytes

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

Erläuterung:

Probieren Sie es online aus.

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
Kevin Cruijssen
quelle
1

PowerShell , 59 Byte

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

Probieren Sie es online!

Weniger golfen:

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

Hinweis: $repeatedCharsist ein Array. Standardmäßig fügt eine PowerShell Array-Elemente durch ein Leerzeichen zusammen, während das Array in einen String konvertiert wird. Der reguläre Ausdruck enthält also Leerzeichen (in diesem Beispiel [^l o]). Leerzeichen wirken sich nicht auf das Ergebnis aus, da die Eingabezeichenfolge nur Buchstaben enthält.

mazzy
quelle
1

APL (Dyalog Extended) , 8 Bytes SBCS

Anonyme implizite Präfixfunktion.

∊⊢⊆⍨1<⍧⍨

Probieren Sie es online!

⍧⍨ count-in selfie (zähle das Vorkommen von Argumentelementen im Argument selbst)

1< Boolesche Maske, bei der man kleiner ist

⊢⊆⍨ Partitioniere das Argument durch diese Maske (beginne eine neue Partition mit Einsen und entferne sie mit Nullen)

ϵ nlist (Abflachen)

Adam
quelle
1

JavaScript, 45 Bytes

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

R , 70 Bytes

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

Probieren Sie es online!

Ein schlechter Versuch, selbst aus einer TIOBE-Top-20-Sprache. Ich weiß, dass in der zweiten Hälfte etwas getan werden kann, aber im Moment entgehen mir alle Golfplätze.

Sumner18
quelle
0

PHP - 137

Code

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

Normaler Code

$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;
Wahyu Kristianto
quelle
0

PHP - 83 78

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

Verbesserte Version:

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

Natürlich müssen dazu Hinweise ausgeschaltet werden

Bearbeiten: Verbesserung von @hengky mulyono inspiriert

Ich bin so schlecht im Codegolf :)

milo5b
quelle
0

C ++, 139 Bytes

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;
}
zelcon
quelle