문자열에서 고유 한 요소 제거


12

문자열에서 고유 한 문자를 찾는 것이 매우 일반적인 유스 케이스 인 것처럼 보이기 때문에이 질문에 왔습니다. 그러나 우리가 그들을 제거하려면 어떻게해야합니까?

입력은 소문자 알파벳 만 포함합니다. a에서 z까지의 문자 만 사용됩니다. 입력 길이는 1-1000 자입니다.

예 :
입력 : helloworld
출력 : llool

목표 : 코드가 가장 짧은
언어입니다. 언어 : TIOBE 언어 중 상위 20 개 언어

답변:


7

Perl, 28 24 자 ( 'p'옵션에 1 포함)

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

용법:

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

처음에 나는 부정적인 미리보기와 부정적인 표정으로 이것을 할 수 있다고 생각했지만, 부정적인 표정은 고정 길이를 가져야한다는 것이 밝혀졌습니다. 그래서 대신 중첩 정규 표현식을 사용했습니다. 팁에 대한 폭도 덕분 $&입니다.


+1. 나는 루비 답변 으로이 일을 취할 수 있다고 순진하게 생각했습니다.
Steven Rumbalski

나는 이것을 중국어 텍스트로 시도했지만 트릭을하지 않았다. = (
ixtmixilix

@ixtmixilix- -CDS옵션으로 perl을 실행하십시오
mob

@ixtmixilix 나는 유니 코드와 Perl의 지원에 대해 충분하지 않아서 중국어 텍스트로 작동하게하는 방법을 제안합니다. 운 좋게도 문제는 소문자 a ~ z 만 나타냅니다.
Gareth

1
모든 교체 $1와 함께 $&당신은 괄호 몇 쌍을 잃을 수 있습니다.
mob

12

(GolfScript, 15 13 자)

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

GolfScript은 상위 20 중 하나지만, GolfScript없이 codegolf (없는 자신을 실행 )

이전 버전 : ( 스크립트 실행 )

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

1
:;? 당신은 일부러 초보자를 혼동 시키려고 노력하고 있습니까? ;)
Peter Taylor

@PeterTaylor 당신이 맞아요. 나는 )그것을 선택 했어야했다 – 그것은 그것을 웃는 것으로 만들 것이다 :). 불행히도, 나는 숫자 1을 제거하는 방법을 찾지 못했습니다. (GolfScript 초보자를위한 참고 사항 : ;코드의 x어떤 문자도 (또는 다른 문자 또는 숫자-그렇지 않으면 스크립트에서 사용되지 않는 문자)로 바꿀 수 있습니다 .) 이 특수한 경우 ;에는 변수 이름 일 뿐이며 "pop and waste"라는 의미가 없습니다. GolfScript에서는 거의 모든 토큰이 변수이므로 미리 정의 된 기호를 사용하면 외부인이 스크립트를 읽을 수 없도록 만드는 좋은 방법입니다.
Howard

또 다른 13 문자 솔루션 ::a{]a.@--,(},
Ilmari Karonen

7

J, 12 자

유효한 Perl 답변을 입력 한 후 잘못된 답변 (TIOBE 상위 20에없는 언어)이 있습니다.

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

용법:

   a 'helloworld'
llool

a고유하지 않은 항목 만 출력 하는 동사 를 선언 합니다.



4

루비 46 40 36

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

인라인 s을 사용 $_하고 두 번째 모양 (이전의 공간이 없어야 할 공간)에 사용할 경우 4 개의 문자를 저장할 수 있습니다 .
Howard

@Howard : 좋은 캐치. 감사. Ruby에 대한 경험이 거의 없습니다.
Steven Rumbalski

2

펄 44

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

실행:

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


2

파이썬 2.7 ( 52 51), 파이썬 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).


대신 파이썬 3를 사용하는 경우 사용할 수 있습니다 input()보다는 raw_input(). 닫는 대괄호에 문자 하나를 추가해야하지만 print파이썬 3의 함수 이므로
Strigoides

@Strigoides : 내 답변에 Python 3 코드 스 니펫을 추가했습니다.
beary605

파이썬 3의 필터는 반복자를 반환합니다 ... 당신이해야 할''.join(...)
JBernardo

@JBernardo : : (Dang. 알려 주셔서 감사합니다. 보시다시피, 나는 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.

왜 모든 솔루션을 CW합니까?
얽히고 설킨

1
@Shaggy : a) 다른 사람들이 편집하고 있기 때문에 괜찮습니다. b) 반대되는 평판을 피하기 위해. 일반적으로 Stack Exchange의 gamififcation은 사이트에 큰 해를 끼친다 고 생각합니다. 때로는 담당자를 개선하기 위해 취할 수있는 조치와 실제로 사이트를 개선하기 위해 취할 수있는 조치간에 부정적인 상관 관계가 있습니다. 또한 높은 평판을 얻는 것은 짜증납니다. 이 사이트는 관리자 작업을 계속하도록 잔소리하고, 수행하는 모든 작업은 무뚝뚝한 도구입니다 (예 : 담당자가 낮 으면 편집을 제안 할 수 있으며 담당자가 높으면 강제로 적용됨).
ais523 2019

2

Japt , 6 5 바이트

ÆèX É

@Oliver 덕분에 -1 바이트

온라인으로 사용해보십시오!


2
Japt에 오신 것을 환영합니다! 실제로 다음과 같은 바로 가기가 있습니다 o@.Æ
Oliver

@Oliver 내가 놓친 또 다른 지름길, 멋진, 감사합니다 :)
Quintec

@Oliver, 더 나은 질문은 집어는 않았다 어떻게 내가 그것을 놓치지! : \
Shaggy

1

파이썬 (56)

파이썬의 또 다른 대안은 다음과 같습니다.

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]

이봐, >1좋은 생각이야! 이를 솔루션에 통합 할 수 있습니까?
beary605

@ beary605 물론 전혀 문제 - 쉬운 방법은 문자 잘라내 없습니다 : D
arshajii

1

매스 매 티카 72 63

Mathematica는 상위 20 개 언어 중 하나가 아니지만 어쨌든 파티에 참여하기로 결정했습니다.

x 입력 문자열입니다.

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

1

펄 (55)

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

stdin에서 읽습니다.


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();

1

OCaml의, (139) (133)

ExtLib의 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는 문자열 s에서 c의 발생 횟수를 리턴합니다. 이 함수 f는 모든 문자를 빈 문자열 또는 발생 횟수에 따라 문자를 포함하는 문자열로 바꿉니다. 편집 : bools의 내부 표현을 남용하여 코드를 6 자 단축했습니다 :-)

아, ocaml은 TIOBE 인덱스에서 0입니다. ;-)


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

자바 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]). 입력 문자열에 문자 만 포함되므로 공백은 결과에 영향을 미치지 않습니다.




1

R , 70 바이트

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

온라인으로 사용해보십시오!

TIOBE 상위 20 개 언어에서도 시도가 잘못되었습니다. 나는 하반기에 무언가를 할 수 있다는 것을 알고 있지만, 현재 어떤 골프도 나를 피할 수 있습니다.




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에 너무 나쁘다 :)


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;

언 골프 :

#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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.