Удаление уникальных элементов из строки

12

Я натолкнулся на этот вопрос, потому что, похоже, это очень распространенный вариант поиска уникальных символов в строке. Но что, если мы хотим избавиться от них?

Ввод содержит только строчные буквы. Используются только буквы от а до я. Длина ввода может быть от 1 до 1000 символов.

Пример:
вход: helloworld
выход: llool

Цель: выигрывает
самый короткий код Язык: любой из 20 лучших языков TIOBE

user14742
источник

Ответы:

7

Perl, 28 24 символа (включает 1 для опции 'p')

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

Использование:

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

Сначала я думал, что смогу сделать это с негативным прогнозом и негативным прогнозом, но оказывается, что негативные ретроспективы должны иметь фиксированную длину. Поэтому вместо этого я использовал вложенные регулярные выражения. Спасибо толпе за $&чаевые.

Gareth
источник
+1. Я наивно думал, что смогу взять эту вещь с моим ответом Руби.
Стивен Румбальски
Я попробовал это на китайском тексте, и это не сработало. = (
ixtmixilix
@ixtmixilix - затем запустите Perl с -CDSопцией
моб
@ixtmixilix Я не знаю достаточно о юникоде и поддержке его Perl, чтобы предложить способ заставить его работать с китайским текстом, я боюсь. К счастью для меня вопрос говорит только строчные буквы от а до я.
Гарет
1
Заменить все $1с , $&и вы можете потерять пару пар скобок.
моб
12

(GolfScript, 15 13 символов)

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

GolfScript не входит в топ-20, но является Codegolf без GolfScript ... ( запустите его самостоятельно )

Предыдущая версия: ( запустить скрипт )

1/:;{;\-,;,(<},
Говард
источник
1
:;? Вы сознательно пытаетесь запутать новичков, не так ли? ;)
Питер Тейлор
@PeterTaylor Ты прав. Я должен был выбрать )- это сделало бы это смайликом тогда :). К сожалению, я не нашел способа даже исключить цифру 1. (Примечание для новичков в GolfScript: вы можете заменить любое ;в коде на x(или любую другую букву или цифру - или любой символ, не используемый в сценарии иным образом). В этом особом случае ;это просто имя переменной - и не имеет значения «pop and discard». В GolfScript почти все токены являются переменными в любом случае, и использование предопределенных символов - отличный способ сделать сценарии еще более нечитаемыми для посторонних ;-).)
Говард
Другое решение с 13 символами::a{]a.@--,(},
Ильмари Каронен,
7

J, 12 символов

Введя правильный Perl-ответ, вот неверный (язык не входит в топ-20 TIOBE).

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

Использование:

   a 'helloworld'
llool

Объявляет глагол, aкоторый выводит только не уникальные предметы.

Gareth
источник
5

GolfScript (14 символов)

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

Онлайн демо

Может не претендовать на победу, но полезно иметь критерий.

Питер Тейлор
источник
4

Руби 46 40 36

gets.chars{|c|$><<c if$_.count(c)>1}
Стивен Румбальский
источник
Вы можете сохранить 4 символа, если вы встраиваете их sи используете $_для второго появления (тогда место перед будет необязательным).
Говард
@ Ховард: Хороший улов. Благодарю. У меня почти нет опыта работы с Ruby.
Стивен Румбальски
2

Perl 44

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

Исполнение:

perl -lane '$l=$_;print join"",grep{$l=~/$_.*$_/}split""' <<< helloworld
llool
flodel
источник
2

К, 18

{x@&x in&~1=#:'=x}
tmartin
источник
Вы можете сохранить байт, используя 1<#вместо~1=#
J. Sendra
2

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

Я не ожидал, что это будет так коротко.

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(): сохранить ввод в виде строки ( input()= eval(raw_input()))
(Python 3.0: input()превращен в raw_input())

filter(lambda x:a.count(x)>1,a): Отфильтровать все символы внутри, aесли они встречаются aболее одного раза ( a.count(x)>1).

beary605
источник
Если вы используете вместо этого Python 3, вы можете использовать input()вместо raw_input(). Хотя вы должны добавить один символ для закрывающей скобки, так printкак это функция в Python 3.
Strigoides
@Strigoides: я добавил фрагмент кода Python 3 в свой ответ.
beary605
Фильтр Python 3 возвращает итератор ... Вам нужно будет это сделать''.join(...)
JBernardo
@JBernardo: :( Черт. Спасибо, что уведомили меня. Как видите, я не использую 3.0.
beary605
2

sed и coreutils (128)

Конечно, это не часть списка TIOBE, но это весело (-:

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

Версия для игры в гольф:

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)

объяснение

Первый sed преобразует ввод в один символ в строке. Второй sed находит персонажей, которые встречаются только один раз. Третий sed пишет скрипт sed, который удаляет уникальные символы. Последний sed выполняет сгенерированный скрипт.

Тор
источник
2

Brachylog (v2), 8 байт

⊇.oḅlⁿ1∧

Попробуйте онлайн!

Функция представления. Технически неконкурентный, потому что вопрос имеет ограничение на то, каким языкам разрешено конкурировать (однако, некоторые другие ответы уже проигнорировали это ограничение).

объяснение

⊇.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
источник
Почему вы CW все ваши решения?
Лохматый
1
@Shaggy: а) потому что я в порядке с другими людьми, редактирующими их, б) чтобы избежать завоевания репутации, если за них проголосуют. В целом, я думаю, что геймификация Stack Exchange является огромным ущербом для сайта - иногда существует отрицательная корреляция между действиями, которые вы можете предпринять, чтобы улучшить репутацию, и действиями, которые вы можете предпринять, чтобы реально улучшить сайт. Кроме того, быть в хорошей репутации - отстой; сайт постоянно требует от вас выполнения задач администратора, и все, что вы делаете, - это тупой инструмент (например, когда у вас низкая репутация, вы можете предложить редактирование, а при высокой репутации он просто проходит).
ais523
2

Japt , 6 5 байт

ÆèX É

-1 байт благодаря @Oliver

Попробуйте онлайн!

Quintec
источник
2
Добро пожаловать в Japt! На самом деле есть ярлык для o@:Æ
Оливер
@ Оливер Еще один ярлык, который я пропустил, круто, спасибо :)
Quintec
@ Оливер, лучший вопрос: как, черт возьми, я это пропустил ?! : \
Лохматый
1

Python (56)

Вот еще одна (на несколько символов длиннее) альтернатива в Python:

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

Если вы принимаете вывод в виде списка (например ['l', 'l', 'o', 'o', 'l']), то мы можем сократить его до 49 символов:

a=raw_input();print[c for c in a if a.count(c)>1]
arshajii
источник
Эй, >1это хорошая идея! Могу ли я включить это в свое решение?
beary605
@ beary605 Конечно, нет проблем - простой способ обрезать персонажа: D
arshajii
1

Mathematica 72 63

Хорошо, Mathematica не входит в число 20 лучших языков, но я все равно решил присоединиться к вечеринке.

x является входной строкой.

"" <> Select[y = Characters@x, ! MemberQ[Cases[Tally@y, {a_, 1} :> a], #] &]
DavidC
источник
1

Perl (55)

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

Читает со стандартного ввода.

QuasarDonkey
источник
1

C # - 77 символов

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

Если вы примете вывод как массив, он сводится к 65 символам:

Func<string,char[]>F=s=>s.Where(c=>s.Count(d=>c==d)>1).ToArray();
Mormegil
источник
1

Окамль, 139 133

Использует ExtLib's 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

Версия без гольфа

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

Функция gвозвращает количество вхождений c в строку s. Функция fзаменяет все символы либо пустой строкой, либо строкой, содержащей символ, в зависимости от числа вхождений. Изменить: я сократил код на 6 символов, злоупотребляя внутренним представлением bools :-)

О, и ocaml 0 в индексе TIOBE ;-)

ReyCharles
источник
f *** индекс TIOBE.
ixtmixilix
Я согласен. Также спасибо за отзыв. Теперь я могу комментировать :-)
ReyCharles
1

PHP - 70

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

с предположением $ s = 'helloworld'.

Хэнки Мулёно
источник
1

Java 8, 90 байт

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

Объяснение:

Попробуйте онлайн.

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 байт

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

Попробуйте онлайн!

Меньше гольфа:

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

Примечание: $repeatedCharsэто массив. По умолчанию Powershell объединяет элементы массива через пробел, а конвертирует массив в строку. Таким образом, регулярное выражение содержит пробелы (в этом примере [^l o]). Пробелы не влияют на результат, потому что входная строка содержит только буквы.

Mazzy
источник
1

APL (Dyalog Extended) , 8 байтов SBCS

Функция анонимного молчаливого префикса.

∊⊢⊆⍨1<⍧⍨

Попробуйте онлайн!

⍧⍨ подсчет количества селфи (подсчет вхождений элементов аргумента в самом аргументе)

1< Булева маска, где один меньше этого

⊢⊆⍨ разделить аргумент по этой маске (начать новый раздел на 1 с и удалить на 0)

ε NLIST (Flatten)

Адам
источник
1

JavaScript, 45 байт

s=>[...s].filter(c=>s.match(c+'.*'+c)).join``
kamoroso94
источник
1

R 70 байт

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

Попробуйте онлайн!

Плохая попытка, даже из топ-20 языка TIOBE. Я знаю, что со второй половиной можно что-то сделать, но на данный момент любые гольфы избегают меня.

Sumner18
источник
0

PHP - 137

Код

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

Нормальный код

$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

Улучшенная версия:

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

Конечно, для этого нужно отключить уведомления

Изменить: улучшение, вдохновленное @hengky mulyono

Я так плох в Codegolf :)

milo5b
источник
0

C ++, 139 байт

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
источник