从字符串中删除唯一元素


12

我遇到了这个问题,因为在字符串中查找唯一字符似乎是非常常见的用例。但是,如果我们想摆脱它们怎么办?

输入仅包含小写字母。仅使用从a到z的字母。输入长度可以是1到1000个字符。

示例:
输入:helloworld
输出:llool

目标:最短的代码胜出
语言:TIOBE语言前20名

Answers:


7

Perl,28个 24个字符(包括1个“ p”选项)

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

用法:

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

起初,我以为可以使用负前瞻性和负后瞻性来做到这一点,但事实证明,负前瞻性必须具有固定的长度。所以我改为使用嵌套的正则表达式。感谢暴民$&小费。


+1。我天真地以为我可以将这个问题与我的Ruby回答结合起来。
史蒂芬·鲁姆巴尔斯基

我在中文文本上尝试过,但没有成功。=(
ixtmixilix 2012年

@ixtmixilix-然后运行带有-CDS选项的perl
mob

@ixtmixilix我对unicode不太了解,而Perl对它的支持并不十分清楚,以至于提出一种使它与中文文本一起使用的方法。对我来说幸运的是,这个问题只说了小写a到z。
Gareth 2012年

1
将所有替换为$1$&您可能会丢失一对括号。
暴徒

12

(GolfScript,15个 13个字符)

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

GolfScript不是前20名之一,而是没有GolfScript的代码高尔夫球...(自己运行

先前版本:(运行脚本

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

1
:;?您是在故意混淆新手,不是吗?;)
Peter Taylor

@PeterTaylor你是对的。我本该选择一个)-这样会使它变得面带笑容:)。不幸的是,我什至找不到消除数字1的方法。(GolfScript新手注意:您可以用(或其他任何字母或数字-或脚本中未使用的任何字符)替换;代码中的x任何数字。在这种特殊情况下,;它只是一个变量名-并没有“弹出并丢弃”的含义。在GolfScript中,几乎所有标记都是变量,并且使用预定义符号是使脚本更不易被外人阅读的好方法;-)。
霍华德

另一个13个字符的解决方案::a{]a.@--,(},
Ilmari Karonen 2014年

7

J,12个字符

输入有效的Perl答案后,这是一个无效的(语言不在TIOBE前20名中)。

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

用法:

   a 'helloworld'
llool

声明a仅输出非唯一项的动词。




2

Perl的44

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

执行:

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


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),则过滤掉其中的所有字符。


如果您改用python 3,则可以使用input()而不是raw_input()。虽然你必须添加一个字符一个右括号,因为print在Python 3的功能
Strigoides

@Strigoides:我在答案中添加了Python 3代码段。
beary605

Python 3的过滤器返回一个迭代器...您需要做''.join(...)
JBernardo 2012年

。@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.

为什么您要对所有解决方案进行CW处理?
毛茸茸的

1
@Shaggy:a)因为我可以和其他人一起编辑它们,所以b)避免在被别人投票时获得声誉。总的来说,我认为Stack Exchange的游戏化对网站造成了极大的损害–有时,您可以采取的改善销售代表的措施与实际采取的改善场所的措施之间存在负相关关系。另外,声誉很高的人很烂;该网站一直在困扰您执行管理任务,而您所做的一切都是钝器(例如,当您的代表人数较少时,您可能会建议您进行编辑,而在代表人数较高时,它会被强制通过)。
ais523


1

巨蟒(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]

嘿,>1是个好主意!我可以将其合并到我的解决方案中吗?
beary605

@ beary605绝对没问题
剪掉

1

Mathematica 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根据出现的次数用空字符串或包含该字符的字符串替换所有字符。编辑:我通过滥用bool的内部表示将代码缩短了6个字符:-)

哦,在TIOBE索引上ocaml为0 ;-)


f *** TIOBE索引。
ixtmixilix 2012年

我同意。另外,感谢您的支持。现在我可以评论:-)
ReyCharles 2012年

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])。空格不会影响结果,因为输入字符串仅包含字母。


1

APL(Dyalog扩展),8 字节SBCS

匿名默认前缀功能。

∊⊢⊆⍨1<⍧⍨

在线尝试!

⍧⍨ 签到自拍(计算参数本身中参数元素的出现次数)

1< 小于1的布尔掩码

⊢⊆⍨ 通过该掩码对参数进行分区(在1s处开始一个新分区,在0s处开始删除)

ε NLIST(扁平化)


1

JavaScript,45个字节

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

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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.