Rimozione di elementi univoci dalla stringa


12

Sono arrivato a questa domanda, perché sembra essere un caso d'uso molto comune trovare caratteri unici nella stringa. E se volessimo liberarcene?

L'input contiene solo alfabeti minuscoli. Vengono utilizzate solo le lettere dalla a alla z. La lunghezza di input può essere compresa tra 1 e 1000 caratteri.

Esempio:
input: helloworld
output: llool

Obiettivo: vince il codice più breve
Lingua: una delle prime 20 lingue TIOBE

Risposte:


7

Perl, 28 24 caratteri (include 1 per l'opzione 'p')

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

Uso:

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

All'inizio ho pensato di poterlo fare con un look-ahead negativo e un look-behind negativo, ma risulta che i look-behind negativi devono avere una lunghezza fissa. Quindi ho optato per le regex nidificate. Grazie a mob per l'informazione $&.


+1. Pensavo ingenuamente di poter prendere questa cosa con la mia risposta di Ruby.
Steven Rumbalski,

ho provato questo sul testo cinese e non ha funzionato. = (
ixtmixilix,

@ixtmixilix - quindi esegui perl con l' -CDSopzione
mob

@ixtmixilix Non so abbastanza dell'unicode e del supporto di Perl per suggerire un modo per farlo funzionare con il testo cinese, temo. Fortunatamente per me la domanda dice solo lettere minuscole dalla a alla z.
Gareth,

1
Sostituisci tutto $1con $&e puoi perdere un paio di parentesi.
mob,

12

(GolfScript, 15 13 caratteri)

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

GolfScript non è uno dei primi 20, ma un codegolf senza GolfScript ... (eseguilo tu stesso )

Versione precedente: ( esegui script )

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

1
:;? Stai deliberatamente cercando di confondere i neofiti, vero? ;)
Peter Taylor,

@PeterTaylor Hai ragione. Avrei dovuto scegliere un )- sarebbe diventato uno smiley allora :). Sfortunatamente, non ho trovato il modo di eliminare nemmeno la cifra 1. (Nota per i neofiti di GolfScript: è possibile sostituire qualsiasi ;nel codice con un x(o qualsiasi altra lettera o cifra - o qualsiasi altro carattere non utilizzato nello script in altro modo). In questo caso speciale ;è solo un nome di variabile - e non ha il significato di "pop and scarard". In GolfScript quasi tutti i token sono comunque variabili e l'uso di simboli predefiniti è un ottimo modo per rendere gli script ancora più illeggibili per gli estranei ;-).)
Howard,

Un'altra soluzione da 13 caratteri::a{]a.@--,(},
Ilmari Karonen,

7

J, 12 caratteri

Dopo aver inserito una risposta Perl valida, ecco una risposta non valida (lingua non presente nella top 20 di TIOBE).

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

Uso:

   a 'helloworld'
llool

Dichiara un verbo ache genera solo elementi non univoci.



4

Ruby 46 40 36

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

Puoi salvare 4 caratteri se sei in linea se lo usi $_per il secondo aspetto (lo spazio precedente è quindi superfluo).
Howard,

@Howard: bella cattura. Grazie. Ho circa zero esperienze con Ruby.
Steven Rumbalski,

2

Perl 44

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

Esecuzione:

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


2

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

Non mi aspettavo che fosse così corto.

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(): memorizza l'input come stringa ( input()= eval(raw_input()))
(Python 3.0: input()è stato trasformato in raw_input())

filter(lambda x:a.count(x)>1,a): Filtra tutti i caratteri all'interno ase sono stati trovati in apiù di una volta ( a.count(x)>1).


Se invece usi python 3, puoi usare input()invece di raw_input(). Anche se devi aggiungere un carattere per una parentesi print
quadra

@Strigoides: ho aggiunto uno snippet di codice Python 3 alla mia risposta.
beary605,

Il filtro di Python 3 restituisce un iteratore ... Dovrai farlo''.join(...)
JBernardo,

@JBernardo: :( Dang. Grazie per avermelo avvisato. Come puoi vedere, non uso 3.0.
beary605

2

sed e coreutils (128)

Concesso questo non fa parte dell'elenco TIOBE, ma è divertente (-:

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

Versione senza golf:

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)

Spiegazione

Il primo sed converte l'input in un carattere per riga. La seconda sed trova personaggi che si presentano solo una volta. Third sed scrive una sceneggiatura di sed che elimina personaggi unici. L'ultimo sed esegue lo script generato.


2

Brachylog (v2), 8 byte

⊇.oḅlⁿ1∧

Provalo online!

Invio di funzioni. Tecnicamente non competitivo perché la domanda ha una limitazione su quali linguaggi sono autorizzati a competere (tuttavia, molte altre risposte hanno già ignorato la restrizione).

Spiegazione

⊇.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.

Perché CW tutte le tue soluzioni?
Shaggy,

1
@Shaggy: a) perché sto bene con altre persone che li modificano, b) per evitare di guadagnare reputazione se vengono votati. In generale, penso che la gamififcation di Stack Exchange sia un enorme danno per il sito - a volte c'è una correlazione negativa tra le azioni che puoi intraprendere per migliorare il rappresentante e le azioni che puoi intraprendere per migliorare effettivamente il sito. Inoltre, essere con un alto numero di reputazione fa schifo; il sito continua a tormentarti per eseguire le attività di amministrazione e tutto ciò che fai è uno strumento contundente (ad esempio quando sei a bassa rep puoi suggerire una modifica, ad alta rep viene semplicemente forzato).
ais523,

2

Japt , 6 5 byte

ÆèX É

-1 byte grazie a @Oliver

Provalo online!


2
Benvenuto in Japt! In realtà esiste una scorciatoia per o@:Æ
Oliver,

@Oliver Un'altra scorciatoia che mi mancava, fico, grazie :)
Quintec,

@Oliver, la domanda migliore è come mi è mancato il diavolo ?! : \
Shaggy

1

Python (56)

Ecco un'altra alternativa (qualche carattere in più) in Python:

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

Se si accetta l'output come elenco (ad esempio ['l', 'l', 'o', 'o', 'l']), è possibile ridurlo a 49 caratteri:

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

Ehi, >1è una buona idea! Posso incorporarlo nella mia soluzione?
beary605,

@ beary605 Sicuramente nessun problema - un modo semplice per tagliare un personaggio: D
arshajii,

1

Mathematica 72 63

Ok, Mathematica non è tra le prime 20 lingue, ma ho deciso comunque di unirmi alla festa.

x è la stringa di input.

"" <> 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)}

Legge da stdin.


1

C # - 77 caratteri

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

Se si accetta l'output come un array, si riduce a 65 caratteri:

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

1

Ocaml, 139 133

Utilizza ExtString.String di ExtLib

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

Versione senza golf

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

La funzione grestituisce il numero di occorrenze di c nella stringa s. La funzione fsostituisce tutti i caratteri con la stringa vuota o la stringa contenente il carattere in base al numero di occorrenze. Modifica: ho abbreviato il codice di 6 caratteri abusando della rappresentazione interna dei bool :-)

Oh, e ocaml è 0 sull'indice TIOBE ;-)


f *** l'indice TIOBE.
ixtmixilix,

Sono d'accordo. Inoltre, grazie per l'upgrade. Ora posso commentare :-)
ReyCharles il

1

PHP - 70

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

con asumption $ s = 'helloworld'.


1

Java 8, 90 byte

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

Spiegazione:

Provalo online.

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 byte

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

Provalo online!

Meno golf:

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

Nota: $repeatedCharsè un array. Per impostazione predefinita, un Powershell unisce gli elementi dell'array con il carattere spazio mentre converte l'array in stringa. Quindi, regexp contiene spazi (in questo esempio [^l o]). Gli spazi non influiscono sul risultato perché la stringa di input contiene solo lettere.


1

APL (Dyalog Extended) , 8 byte SBCS

Funzione prefisso tacito anonimo.

∊⊢⊆⍨1<⍧⍨

Provalo online!

⍧⍨ conto alla rovescia selfie (conta le occorrenze di elementi argomento nell'argomento stesso)

1< Maschera booleana in cui uno è inferiore a quello

⊢⊆⍨ partiziona l'argomento da quella maschera (iniziando una nuova partizione su 1s e rimuovendo su 0s)

ϵ nlist (appiattisci)


1

JavaScript, 45 byte

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

1

R , 70 byte

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

Provalo online!

Un tentativo scadente, anche da una delle prime 20 lingue di TIOBE. So che si può fare qualcosa per la seconda metà, ma al momento qualsiasi golf mi sfugge.




0

PHP - 137

Codice

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

Codice normale

$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

Versione migliorata:

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

Naturalmente ciò richiede che gli avvisi vengano disattivati

Modifica: miglioramento ispirato a @hengky mulyono

Sono così cattivo con codegolf :)


0

C ++, 139 byte

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.