Eliminar elementos únicos de la cadena


12

Encontré esta pregunta, porque parece ser un caso de uso muy común para encontrar caracteres únicos en la cadena. Pero, ¿qué pasa si queremos deshacernos de ellos?

La entrada contiene solo alfabetos en minúsculas. Solo se utilizan letras de la a a la z. La longitud de entrada puede ser de 1 a 1000 caracteres.

Ejemplo:
input: helloworld
output: llool

Objetivo: el código más corto gana
Idioma: cualquiera de los 20 principales idiomas de TIOBE

Respuestas:


7

Perl, 28 24 caracteres (incluye 1 para la opción 'p')

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

Uso:

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

Al principio pensé que podía hacer esto con una mirada hacia adelante negativa y una mirada hacia atrás negativa, pero resulta que las miradas negativas deben tener una longitud fija. Así que fui por expresiones regulares anidadas en su lugar. Gracias a la mafia por la informacion $&.


+1. Ingenuamente pensé que podría tomar esto con mi respuesta de Ruby.
Steven Rumbalski

Intenté esto en texto chino y no funcionó. = (
ixtmixilix

@ixtmixilix - luego ejecuta perl con la -CDSopción
mob

@ixtmixilix No sé lo suficiente sobre Unicode y el soporte de Perl para sugerir una forma de hacerlo funcionar con texto en chino, me temo. Por suerte para mí, la pregunta dice solo minúsculas de la a a la z.
Gareth

1
Reemplace todo $1con $&y puede perder un par de paréntesis.
mafia

12

(GolfScript, 15 13 caracteres)

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

GolfScript no es uno de los 20 mejores, sino un codegolf sin GolfScript ... ( ejecútelo usted mismo )

Versión anterior: ( ejecutar script )

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

1
:;? Intentas confundir deliberadamente a los novatos, ¿verdad? ;)
Peter Taylor

@PeterTaylor Tienes razón. Debería haber elegido un )- sería un smiley entonces :). Desafortunadamente, no encontré una forma de eliminar siquiera el dígito 1. (Nota para los novatos de GolfScript: puede reemplazar cualquiera ;en el código con un x(o cualquier otra letra o dígito, o cualquier carácter que no se use en el script). En este caso especial ;es solo un nombre de variable, y no tiene el significado "pop and descarte". En GolfScript, casi todos los tokens son variables de todos modos, y el uso de símbolos predefinidos es una excelente manera de hacer que los scripts sean aún más ilegibles para los extraños ;-).)
Howard

Otra solución de 13 caracteres::a{]a.@--,(},
Ilmari Karonen

7

J, 12 caracteres

Después de haber ingresado una respuesta Perl válida, aquí hay una respuesta no válida (idioma que no está en el top 20 de TIOBE).

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

Uso:

   a 'helloworld'
llool

Declara un verbo aque genera solo elementos no únicos.



4

Rubí 46 40 36

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

Puede guardar 4 caracteres si está en línea sy lo usa $_para la segunda aparición (el espacio anterior es entonces prescindible).
Howard

@Howard: Buena captura. Gracias. Tengo casi cero experiencia con Ruby.
Steven Rumbalski

2

Perl 44

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

Ejecución:

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


2

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

No esperaba que fuera tan 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(): almacena la entrada como una cadena ( input()= eval(raw_input()))
(Python 3.0: input()se ha convertido en raw_input())

filter(lambda x:a.count(x)>1,a): Filtre a través de todos los caracteres dentro asi se encuentran en amás de una vez ( a.count(x)>1).


Si usa Python 3 en su lugar, puede usar en input()lugar de raw_input(). Aunque tiene que agregar un carácter para un corchete de cierre, ya que printes una función en Python 3.
Strigoides

@Strigoides: He agregado un fragmento de código de Python 3 a mi respuesta.
beary605

El filtro de Python 3 devuelve un iterador ... Tendrá que hacerlo''.join(...)
JBernardo

@JBernardo: :( Dang. Gracias por notificarme. Como puedes ver, no uso 3.0.
beary605

2

sed y coreutils (128)

De acuerdo, esto no es parte de la lista TIOBE, pero es divertido (-:

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

Versión de 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)

Explicación

El primer sed convierte la entrada en un carácter por línea. El segundo sed encuentra caracteres que solo ocurren una vez. Third sed escribe un script sed que elimina caracteres únicos. El último sed ejecuta el script generado.


2

Brachylog (v2), 8 bytes

⊇.oḅlⁿ1∧

Pruébalo en línea!

Presentación de funciones. Técnicamente no compite porque la pregunta tiene una limitación sobre qué idiomas pueden competir (sin embargo, varias otras respuestas ya han ignorado la restricción).

Explicación

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

¿Por qué utiliza CW todas sus soluciones?
Shaggy

1
@Shaggy: a) porque estoy de acuerdo con que otras personas los editen, b) para evitar ganar reputación si son votados. En general, creo que la diversificación de Stack Exchange es un gran perjuicio para el sitio: a veces hay una correlación negativa entre las acciones que puede tomar para mejorar el representante y las acciones que puede tomar para mejorar el sitio. Además, estar en una cuenta de alta reputación apesta; el sitio no deja de molestarte para que realices tareas administrativas, y todo lo que haces es un instrumento contundente (por ejemplo, cuando tienes poca repetición, puedes sugerir una edición, en una alta repetición simplemente se hace pasar).
ais523


1

Pitón (56)

Aquí hay otra alternativa (pocos caracteres más) en Python:

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

Si acepta la salida como una lista (p ['l', 'l', 'o', 'o', 'l']. Ej. ), Podríamos reducirla a 49 caracteres:

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

¡Hola, >1es una buena idea! ¿Puedo incorporar eso en mi solución?
beary605

@ beary605 Claro que no hay problema en absoluto: forma fácil de recortar un personaje: D
arshajii

1

Mathematica 72 63

Ok, Mathematica no está entre los 20 idiomas principales, pero decidí unirme a la fiesta de todos modos.

x es la cadena de entrada.

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

Lecturas de stdin.


1

C # - 77 caracteres

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

Si acepta la salida como una matriz, se reduce a 65 caracteres:

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

1

Ocaml, 139 133

Utiliza ExtString.String de 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

Versión sin 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 función gdevuelve el número de ocurrencias de c en la cadena s. La función freemplaza todos los caracteres, ya sea por la cadena vacía o la cadena que contiene el carácter, dependiendo del número de ocurrencias. Editar: acorté el código en 6 caracteres al abusar de la representación interna de bools :-)

Ah, y ocaml es 0 en el índice TIOBE ;-)


f *** el índice TIOBE.
ixtmixilix

Estoy de acuerdo. Además, gracias por el voto a favor. Ahora puedo comentar :-)
ReyCharles

1

PHP - 70

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

con asunción $ s = 'helloworld'.


1

Java 8, 90 bytes

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

Explicación:

Pruébalo en línea.

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 bytes

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

Pruébalo en línea!

Menos golfizado:

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

Nota: $repeatedCharses una matriz. Por defecto, un Powershell une elementos de la matriz por espacio de caracteres mientras convierte la matriz en cadena. Entonces, la expresión regular contiene espacios (en este ejemplo, [^l o]). Los espacios no afectan el resultado porque la cadena de entrada contiene solo letras.


1

APL (Dyalog Extended) , SBCS de 8 bytes

Función de prefijo tácito anónimo.

∊⊢⊆⍨1<⍧⍨

Pruébalo en línea!

⍧⍨ selfie de recuento (cuenta las ocurrencias de elementos de argumento en el argumento mismo)

1< Máscara booleana donde uno es menor que eso

⊢⊆⍨ particione el argumento por esa máscara (comience una nueva partición en 1s y elimine en 0s)

ϵ nlist (aplanar)


1

JavaScript, 45 bytes

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

1

R , 70 bytes

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

Pruébalo en línea!

Un intento pobre, incluso de un lenguaje TIOBE top 20. Sé que se puede hacer algo en la segunda mitad, pero por el momento, cualquier golf se me escapa.




0

PHP - 137

Código

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

Código normal

$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

Versión mejorada:

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

Por supuesto, esto necesita avisos para apagarse

Editar: Mejora inspirada en @hengky mulyono

Soy tan malo en codegolf :)


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;

sin golf:

#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;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.