การลบองค์ประกอบที่ไม่ซ้ำกันจากสตริง


12

ฉันมากับคำถามนี้เพราะมันดูเหมือนจะเป็นกรณีที่ใช้กันทั่วไปเพื่อค้นหาตัวละครที่ไม่ซ้ำกันในสตริง แต่ถ้าเราต้องการกำจัดพวกมันล่ะ?

อินพุตมีตัวอักษรตัวพิมพ์เล็กเท่านั้น ใช้เฉพาะตัวอักษรจาก a ถึง z ความยาวของอินพุตอาจมีตั้งแต่ 1 ถึง 1,000 ตัวอักษร

ตัวอย่าง:
อินพุต:
เอาต์พุตhelloworld : llool

วัตถุประสงค์: รหัสที่สั้นที่สุดชนะ
ภาษา: ภาษาใด ๆ ใน20 อันดับแรกของภาษา TIOBE

คำตอบ:


7

Perl, 28 24 ตัวอักษร (รวม 1 สำหรับตัวเลือก 'p')

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

การใช้งาน:

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

ตอนแรกฉันคิดว่าฉันสามารถทำสิ่งนี้ได้ด้วยการมองไปข้างหน้าในเชิงลบและการมองด้านลบ แต่กลับกลายเป็นว่าการมองด้านลบนั้นต้องมีความยาวคงที่ ดังนั้นฉันจึงไปหา regexes ที่ซ้อนกันแทน ด้วยการขอบคุณม็อบสำหรับคำ$&แนะนำ


+1 ฉันคิดอย่างไร้เดียงสาว่าฉันสามารถรับสิ่งนี้ได้ด้วยคำตอบ Ruby ของฉัน
Steven Rumbalski

ฉันลองสิ่งนี้กับข้อความภาษาจีนและไม่ได้ทำเคล็ดลับ = (
ixtmixilix

@ixtmixilix - จากนั้นเรียกใช้ Perl พร้อม-CDSตัวเลือก
mob

@ixtmixilix ฉันไม่รู้มากพอเกี่ยวกับการสนับสนุน unicode และ Perl ของมันเพื่อแนะนำวิธีที่จะทำให้มันทำงานกับข้อความภาษาจีนที่ฉันกลัว โชคดีสำหรับฉันคำถามที่บอกว่าตัวพิมพ์เล็ก a ถึง z
Gareth

1
แทนที่ทั้งหมด$1ด้วย$&และคุณสามารถสูญเสียคู่คู่ของวงเล็บ
ม็อบ

12

(GolfScript, 15 13 ตัวอักษร)

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

GolfScript ไม่ใช่หนึ่งใน 20 อันดับแรก แต่เป็น codegolf ที่ไม่มี GolfScript ... ( เรียกใช้ด้วยตนเอง )

รุ่นก่อนหน้า: ( เรียกใช้สคริปต์ )

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

1
:;? คุณจงใจสร้างความสับสนให้กับมือใหม่ใช่ไหม? ;)
Peter Taylor

@PeterTaylor คุณพูดถูก ฉันควรจะได้รับการแต่งตั้ง)- :)มันจะทำให้มันเป็นรอยยิ้มแล้ว น่าเสียดายที่ฉันไม่พบวิธีที่จะกำจัดเลข 1 (หมายเหตุสำหรับมือใหม่ GolfScript: คุณสามารถแทนที่;ด้วยรหัสด้วยx(หรือตัวอักษรหรือตัวเลขอื่น - หรืออักขระใด ๆ ที่ไม่ได้ใช้ในสคริปต์) ในกรณีพิเศษนี้;เป็นเพียงชื่อตัวแปร - และไม่มีความหมาย "ป๊อปและทิ้ง" ใน GolfScript โทเค็นเกือบทั้งหมดเป็นตัวแปรอย่างไรก็ตามและการใช้สัญลักษณ์ที่กำหนดไว้ล่วงหน้าเป็นวิธีที่ดีในการทำให้สคริปต์ไม่สามารถอ่านได้มากขึ้นสำหรับบุคคลภายนอก ;-))
Howard

วิธีแก้ปัญหาอื่นอีก 13 ตัว::a{]a.@--,(},
Ilmari Karonen

7

J, 12 ตัวอักษร

หลังจากป้อนคำตอบ Perl ที่ถูกต้องต่อไปนี้เป็นคำตอบที่ไม่ถูกต้อง

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

การใช้งาน:

   a 'helloworld'
llool

ประกาศคำกริยาaที่แสดงเฉพาะรายการที่ไม่ซ้ำกัน



4

ทับทิม46 40 36

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

คุณสามารถบันทึก 4 ตัวอักษรหากคุณอินไลน์sและใช้$_สำหรับการปรากฏตัวครั้งที่สอง (พื้นที่ก่อนที่จะสามารถแจกจ่ายได้)
Howard

@ วิธี: จับที่ดี ขอบคุณ ฉันไม่มีประสบการณ์เกี่ยวกับทับทิมเลย
Steven Rumbalski

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)


ถ้าคุณใช้หลาม 3 แทนคุณสามารถใช้มากกว่าinput() raw_input()แม้ว่าคุณจะต้องเพิ่มตัวละครหนึ่งตัวสำหรับวงเล็บปิดเนื่องจากprintมันเป็นฟังก์ชั่นในหลาม 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∧

ลองออนไลน์!

ฟังก์ชั่นการส่ง ในทางเทคนิคไม่ใช่การแข่งขันเพราะคำถามมีข้อ จำกัด เกี่ยวกับสิ่งที่ langauges ได้รับอนุญาตให้แข่งขัน

คำอธิบาย

⊇.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) เพื่อหลีกเลี่ยงการได้รับชื่อเสียงถ้าพวกเขา upvoted โดยทั่วไปฉันคิดว่า gamififcation ของ Stack Exchange เป็นความเสียหายอย่างใหญ่หลวงต่อไซต์ - บางครั้งก็มีความสัมพันธ์เชิงลบระหว่างการกระทำที่คุณสามารถใช้เพื่อปรับปรุงตัวแทนและการกระทำที่คุณสามารถทำได้เพื่อปรับปรุงเว็บไซต์จริง นอกจากนี้การมีชื่อเสียงเป็นที่น่าประทับใจ ไซต์ยังคงจู้จี้ให้คุณทำงานผู้ดูแลระบบและทุกสิ่งที่คุณทำคือเครื่องมือทื่อ (เช่นเมื่อคุณอยู่ในระดับต่ำตัวแทนคุณสามารถแนะนำการแก้ไขได้ที่ตัวแทนระดับสูงที่เพิ่งถูกบังคับผ่าน)
ais523

2

Japtap , 6 5 ไบต์

ÆèX É

-1 ไบต์ขอบคุณ @Oliver

ลองออนไลน์!


2
ยินดีต้อนรับสู่ Japt! มีจริงทางลัดสำหรับo@:Æ
โอลิเวอร์

@Oliver อีกทางลัดที่ฉันพลาดไปเจ๋งขอบคุณ :)
Quintec

@Oliver คำถามที่ดีกว่าคือวิธีที่ฉันไม่ได้คิดถึงเรื่องนี้เหรอ?! : \
ปุย

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]

เฮ้>1เป็นความคิดที่ดี! ฉันขอรวมมันไว้ในทางออกของฉันได้ไหม
beary605

@ beary605 ไม่มีปัญหาแน่นอน - วิธีง่ายๆในการตัดอักขระ: D
arshajii

1

Mathematica 72 63

โอเค Mathematica ไม่ได้อยู่ใน 20 อันดับแรกของภาษา แต่ฉันตัดสินใจเข้าร่วมปาร์ตี้

x คือสตริงอินพุต

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


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

ใช้ ExtStib ของ 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 ;-)


f *** ดัชนี TIOBE
ixtmixilix

ฉันเห็นด้วย. นอกจากนี้ขอขอบคุณสำหรับการโหวต ตอนนี้ฉันสามารถแสดงความคิดเห็น :-)
ReyCharles


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 จะรวมองค์ประกอบของอาร์เรย์โดย space char ในขณะที่แปลงอาร์เรย์เป็นสตริง ดังนั้น regexp มีช่องว่าง (ในตัวอย่างนี้[^l o]) ช่องว่างไม่ส่งผลกระทบต่อผลเนื่องจากสตริงอินพุตมีตัวอักษรเท่านั้น


1

APL (Dyalog Extended) , 8 ไบต์SBCS

ฟังก์ชันนำหน้าเงียบโดยไม่ระบุชื่อ

∊⊢⊆⍨1<⍧⍨

ลองออนไลน์!

⍧⍨ การนับเซลฟี (การนับจำนวนองค์ประกอบการโต้แย้งในการโต้แย้ง)

1< บูลีนมาส์กหน้าเดียวที่น้อยกว่านั้น

⊢⊆⍨ แบ่งพาร์ติชั่นโดยหน้ากากนั้น (เริ่มพาร์ติชั่นใหม่ใน 1 วินาทีและลบออกเป็น 0 วินาที)

ε nlist (เรียบ)



1

R , 70 ไบต์

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

ลองออนไลน์!

ความพยายามที่ไม่ดีแม้จากภาษายอดนิยมของ TIOBE 20 ฉันรู้ว่าบางสิ่งสามารถทำได้ในช่วงครึ่งหลัง แต่ในขณะนี้มีสนามกอล์ฟใดบ้างที่หลบหนีฉัน


1

JavaScript ขนาด 34 ไบต์

อินพุตเป็นสตริงเอาต์พุตเป็นอาร์เรย์อักขระ

s=>[...s].filter(x=>s.split(x)[2])

ลองออนไลน์!


ดี นี่คือทางเลือก 34 ไบต์โดยใช้map: tio.run/##BcExDoAgDADAvzgYOtjBHT9CTCSICqmUWKL8vt5l/ …
โอลิเวอร์

@Oliver, ไม่มาก
Shaggy


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;

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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.