เขียนโปรแกรมที่ค้นหาตัวอักษรที่จับคู่ที่เกิดขึ้นมากที่สุดในสตริง


20

โปรแกรมจะต้องส่งออกตัวอักษรที่จับคู่มากที่สุด ตัวอย่างเช่นหากโปรแกรมของคุณได้รับสตริงต่อไปนี้:

"Sally's friend Bobby searched for seashells."

มันจะต้องส่งออกLเพราะเกิดขึ้นเป็นครั้งที่สองซึ่งเป็นบ่อยมากขึ้นกว่าคู่อื่น"ll""bb"

กฎ:

  • หากมีจดหมายมากกว่าหนึ่งฉบับที่เกิดขึ้นอันดับหนึ่งให้ส่งออกทั้งหมดตามลำดับตัวอักษร (เช่น"Sally's friends Jimmy and Bobby rummaged for seashells."ควรส่งออกทั้งสองLและM[หรือ"LM"หากคุณโปรด] เพราะพวกเขาทั้งสองเกิดขึ้นบ่อยกว่าคู่อื่น ๆ )
  • ตัวอักษรที่มีสามเท่าสี่เท่าและอื่น ๆ นับเป็นหนึ่งคู่ (เช่น"lll"ใน"willless"ถูกนับเป็นหนึ่งคู่Lเท่านั้น)
  • ตัวอักษรคู่จะต้องอยู่ในคำเดียว (เช่น"Sally's sociable friends Sammy and Bobby searched for fabulous seashells."ควรส่งออกLและไม่ใช่Sเพราะแม้จะ"ss"มีเหตุการณ์มากกว่า"ll"นั้นพวกเขาจะถูกคั่นด้วยช่องว่าง)
  • นับเฉพาะตัวอักษรจากตัวอักษรภาษาอังกฤษ
  • กรณีไม่สำคัญ (เช่น"Ss"เป็นเช่นเดียวกับ"SS"หรือ"ss"และทั้งหมดถูกนับเป็นหนึ่งคู่S)

คุณสามารถอ่านข้อมูลของคุณได้จากทุกที่ที่คุณต้องการ รหัสที่สั้นที่สุดชนะ


2
เราสามารถสมมติว่าตัวอักษรที่จะเกิดขึ้นเป็นคู่หรือสามารถป้อนข้อมูลที่มีช่องว่างคู่หรือสองเท่า'etc?
Martin Ender

1
เราสามารถสมมติได้ว่าอย่างน้อยหนึ่งตัวอักษรปรากฏขึ้นสองครั้ง?
Martin Ender

@ MartinBüttnerใช่คุณสามารถสันนิษฐานได้ว่าเกิดจดหมายอย่างน้อยหนึ่งคู่ อย่างไรก็ตามตัวละครอื่น ๆ อาจปรากฏเป็นคู่เช่นกัน นับเฉพาะตัวอักษร
ayane

แม้ว่าจะมีเพียงคู่เดียวฉันยังคงสามารถพิมพ์ในรายการที่ชอบได้['l']หรือไม่?
Maltysen

@Maltysen ใช่คุณสามารถทำได้
Ayane

คำตอบ:


6

Pyth, 26 25 24 16 15 ไบต์

.M/sfthTrrz08ZG

ลองใช้งานออนไลน์: การสาธิต

คำอธิบาย:

.M/sfthTrrz08ZG   implicit: z = input string
         rz0      convert z to lower-char
        r   8     run-length-encoding (into tuples [count, char])
    f             filter for tuples T, which satisfy:
     thT            T[0]-1 != 0 (count > 1)
   s              join to a string
.M            G   find the elements Z of "abcd...z", which produce the highest value:
  /...........Z       count of Z in ...

1
eC-> sบันทึกหนึ่งไบต์
isaacg

คุณรู้จักแหล่งข้อมูลที่ดีที่ฉันสามารถใช้เพื่อเรียนรู้ Pyth หรือไม่?
Beta Decay

@BetaDecay คุณสามารถค้นหาบทช่วยสอนเกี่ยวกับPyth ได้ที่pyth.readthedocs.orgมันไม่ได้ครอบคลุมฟังก์ชั่นและลูกเล่นทั้งหมด แต่เป็นการเริ่มต้นที่ดี และถ้าคุณมีคำถามใด ๆ เพียงแค่ถามในการแชท
Jakube

7

Bash + GNU coreutils, 133

grep -Eo '([A-Z])\1+'<<<"${1^^}"|cut -c1|sort|uniq -c|sort -rn|while read n l
do((a-n&&a-0))&&exit||echo $l&&a=$n
done|sort|tr -d \\n

Testcases:

$ for t in "Sally's friend Bobby searched for seashells." \
> "Sally's friends Jimmy and Bobby rummaged for seashells." \
> "willless" \
> "Sally's sociable friends Sammy and Bobby searched for fabulous seashells." \
> "11ss11aa"
> do
> ./mostpaired.sh "$t"
> echo
> done
L
LM
LS
L
AS
$ 

มันนับตัวอักษรเท่านั้นหรือ (testcase: 11ss11aa-> SA)
edc65

@ edc65 ฉันแก้ไขมันที่นั่น ;-) ที่จริงแล้ว11ss11aa-> AS :)
Digital Trauma

ฉันคิดว่าความsort -rต้องการของคุณคือsort -rnถ้าคุณมีตัวอักษรที่จับคู่มากกว่า 10 ตัว
Toby Speight

@TobySpeight ใช่. แก้ไขแล้ว.
Digital Trauma

สามารถทำให้ AWK สั้นลงแทนขณะที่: awk '! n {n = $ 1}; n == $ 1' | grep -o. $
Nik O'Lai

5

CJam, 29 27 ไบต์

leue`{2a>},s_el-$e`$z~\)-,>

ขอบคุณ @Optimizer สำหรับการตีกอล์ฟขนาด 2 ไบต์!

ลองใช้ออนไลน์ในล่าม CJam

มันทำงานอย่างไร

leu    e# Read a line from STDIN and covert to uppercase.
e`     e# Perform run-length encoding.
       e# Example: "AABBBC!!" -> [[2 'A] [3 'B] [1 'C] [2 '!]]
{2a>}, e# Filter out all pairs that are less of equal to [2].
s      e# Stringify.
       e# Example: [[2 'A] [3 'B] [2 '!]] -> "2A3B2!"
_el    e# Push a copy of the string and convert to lowercase.
       e# Example: "2A3B2!" -> "2a3b2!"
-      e# Remove all character from the second string from the first.
       e# Example: "2A3B2!" "2a3b2!" - -> "AB"
$e`$   e# Sort, perform run-length encoding and sort again.
       e# Example: "ABACABDBC" -> "AAABBBCCD"
       e#                      -> [[3 'A] [3 'B] [2 'C] [1 'D]]
                               -> [[1 'D] [2 'C] [3 'A] [3 'B]]
z~     e# Zip and dump.
       e# Example: [[1 'D] [2 'C] [3 'A] [3 'B]] -> [1 2 3 3] ['D 'C 'A 'B]
\)     e# Pop out the last element from the first array.
       e# Example: [1 2 3 3] -> [1 2 3] 3
-      e# Remove all occurrences of the popped element from the array.
       e# Example: [1 2 3] 3 -> [1 2]
,      e# Compute the length of the remainder.
>      e# Skip that many elements from the character array.

z~\)-,>ควรทำงานเท่าที่ฉันเห็น
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer: สั้นลงและใช้งานง่ายขึ้น ขอบคุณ!
Dennis

4

Pyth - 23 22 21 20 ไบต์

ใช้การทดแทน regexp เพื่อแทนที่ตัวอักษรสองตัวหรือมากกว่าทั้งหมดเป็นค่า temp และใช้.Maximal เพื่อให้ได้สิ่งที่เกิดขึ้นทั้งหมด ขอบคุณ @Jakube ที่ชี้ให้เห็นความซ้ำซ้อนของการเรียงลำดับและการบันทึกไบต์

.M/:rz0+Z"{2,}"KC0KG

รับอินพุตจาก stdin และเอาต์พุตเหมือนกับ['l', 'm']stdout

.M        G         Values which yield maximal amount over lowercase alphabet
 /                  Count
  :                 Regexp substitution
   rz0              Lowercased input
   +Z               String concatenate current loop var         
    "{2,}"          Regexp 2 or more of previous group
   KCZ              Inline assign null byte to K and use value
  K                 Count K which is null byte

ลองมันออนไลน์ได้ที่นี่


4

C, 155

สิ่งที่แตกต่างไม่มี regexps

m=1,i=1,n[91];
main(c,a)char**a;
{
  char*t=a[1];
  for(;c=*t++;)(c&=95)>64&&c<91&&(c-(*t&95)?i=1:(c=(n[c]+=i),i=0,m=m<c?c:m));
  for(c=0;++c<91;)n[c]-m||putchar(c);
}

3

Python 2, 132 143 ไบต์

def f(x):import re;x=re.findall(r'(.)\1+',x.upper());s={l:x.count(l)for l in x};print "".join(sorted([l for l in s if s[l]==max(s.values())]))

ตัวอย่างการเรียกใช้:

f("Sally's friends Jimmy and Bobby rummaged for seashells.")
LM

1
อาจเป็นไปไม่ได้ "จดหมายที่มีสามเท่าสี่เท่าและอื่น ๆ นับเป็นหนึ่งคู่"
Ginden

คุณถูก! ฉันพยายามแก้ไขแล้ว ขอบคุณสำหรับการชี้ว่า :)
Heo

2

CJam, 37 ไบต์

leue`{~_el-\(e&},1f=$e`$_W=0=f-{,1=},

ลองออนไลน์

หากไม่มีการสนับสนุนการแสดงออกปกติฉันกลัวว่าจะยากที่จะแข่งขันกับ Pyth นี่คือสิ่งที่ดีที่สุดที่ฉันได้พบเมื่อผ่านครั้งแรก

คำอธิบาย:

l     Get input.
eu    Convert it to upper case, since case does not matter.
e`    Run length encoding, to split into groups of same characters.
{     Start of block for filtering.
  ~     Unpack the length/letter pair.
  _     Copy the letter.
  el    Change copy to lower case.
  -     Subtract to compare. If result is non-zero, this is a letter.
  \     Swap count to top.
  (     Decrement to get truthy value for count > 1.
  e&    Logical and: It's a letter, and count is > 1.
},    End of filter.
1f=   Don't need the counts anymore, filter out the letters only from the RLE pairs.
$     Sort them, so that multiples of the same letter are sequential.
e`    RLE again, to count how many multiples of each letter we had.
$     And sort again, to get the count/letter pairs in order of incrementing count.
_     Copy list.
W=0=  Pick out count of last element, which is the highest count.
f-    Remove count from pairs that have the highest count. This leaves them
      as one member lists with letter only, while others still have count/letter.
{     Start block for filter.
  ,1=   Check for list length one.
},    End filter.


2

R, 105 ไบต์

cat(substr(names(b<-table(regmatches(s<-toupper(readline()),gregexpr("([A-Z])\\1+",s))))[b==max(b)],1,1))

สิ่งนี้จะอ่านบรรทัดข้อความจาก STDIN และพิมพ์รายการตัวคั่นที่เว้นวรรคของตัวอักษรที่จับคู่ที่พบบ่อยที่สุดไปยัง STDOUT

คำอธิบาย Ungolfed +:

# Read a string from STDIN, convert to uppercase
s <- toupper(readline())

# Get each match of the regex /([A-Z])\1+/
matches <- regmatches(s, gregexpr("([A-Z])\\1+", s))

# Compute the frequency of each match
freq <- table(matches)

# Get the matches with the highest frequency
highest <- names(freq)[freq == max(freq)]

# Each element of highest is the literal pair, so take the first character
first <- substr(highest, 1, 1)

# Print to STDOUT
cat(first)

ตัวอย่าง:

> (code)
Sally's friends Jimmy and Bobby rummaged for seashells.
L M

> (code)
Sally's friend Bobby searched for seashells.
L

> (code)
Sally's sociable friends Sammy and Bobby searched for fabulous seashells.
L

> (code)
11ss11nn
N S

คุณสามารถลองออนไลน์ได้ !


คุณอาจจะสามารถกำจัดถ้าคุณไม่สนใจกรณีและการใช้งานของคุณในtoupper Perl gregexprเช่นcat(substr(names(b<-table(regmatches(s<-readline(),gregexpr("(\\w)\\1+",s,T,T))))[b==max(b)],1,1))
MickyT

@MickyT: ฉันเคยคิดเกี่ยวกับมัน แต่ดูเหมือนว่า OP ต้องการให้ผลลัพธ์เป็นตัวพิมพ์ใหญ่ดังนั้นจึงต้องใช้toupperเพื่อให้แน่ใจว่า
Alex A.

นั่นคือขี้เถ้าฉันคิดถึงเมื่อฉันอ่านคำถาม
MickyT

ลองเล่นซอ แต่ดูเหมือนว่าจะทำงานได้ตลอดไปโดยไม่มีค่าใช้จ่ายใน firefox ทดสอบ: 11ss11nn?
edc65

@ edc65 เป็นปัญหากับ R-Fiddle; ไม่มีอะไรทำงานเลย ฉันติดต่อผู้ดูแลระบบเพื่อรายงานปัญหา แก้ไข regex ของฉันและตอนนี้การทดสอบของคุณใช้งานได้ตามที่คาดไว้ แต่มีค่าใช้จ่าย 2 ไบต์ ขอบคุณสำหรับการชี้สิ่งนี้ฉันขอขอบคุณ!
Alex A.

2

ทับทิม, 60

f=->s{(?a..?z).group_by{|l|s.scan(/#{l*2}+/i).size}.max[1]}

p f["Sally's friends Jimmy and Bobby rummaged for seashells."]

group_byสร้างโครงสร้างแฮช (พจนานุกรม) ที่คีย์เป็นผลลัพธ์ของบล็อกและค่าเป็นรายการของตัวอักษรที่ส่งผลให้แต่ละคีย์ ในกรณีนี้กุญแจจะนับจำนวนจดหมายวิ่ง 2+ ตัวพิมพ์เล็กและใหญ่ maxเปรียบเทียบ[key,value]tuple แต่ละคำในพจนานุกรมดังนั้นมันจึงค้นหาคีย์สูงสุด จากนั้น[1]ส่งคืนส่วนรายการค่าของ tuple


2

Python 2, 185 159 153

i=input().lower()
d=sorted({l:len(i.split(l+l))for l in map(chr,range(97,123))}.items(),None,lambda x:x[1],1)
print sorted(c for c,k in d if k==d[0][1])

รับอินพุตเป็นสตริงที่อยู่ในเครื่องหมายคำพูด


2

C # 160 Bytes

sอินพุตอยู่ที่ไหน:

char? d(string s){s=s.ToUpper();return s.Select((x,i)=>new{y=x,z=i==0?(char?)null:s[i-1]}).Where(x=>x.y==x.z).GroupBy(x=>x.z).OrderBy(x=>x.Count()).Last().Key;}

1

อาร์เอส, 146 ไบต์

[^A-Za-z]/
*(.)\1+/\1\1
*(.)(?!\1)/
$/#
+*(.)#(?!.*?\1)/#\1
+*(.)(.*)#(.*)\1/\2#\3\1\1
#/
*(.)(\1*)/\1(_)^^((^^\1\2))
([^_])(_+)(?!_)(?=.*\2_)/
_/

ลองมัน! โปรด! ฉันใช้เวลาตลอดไปในการสร้างปุ่มแม้จะมีช่องเอาท์พุทในหน้านั้น ...

นี่มันค่อนข้าง ... บ้าจริง ๆ ตรรกะที่นี่แปลก ๆ ฉันจะโพสต์คำอธิบายเฉพาะเมื่อมีคนถาม (แน่นอนฉันยังบอกด้วยว่าสำหรับคำตอบแบบ INTERCAL ที่ขอคำอธิบาย ... ซึ่งฉันไม่เคยอธิบาย ... ;)


ฉันชอบล่าม แต่คุณอาจต้องการวางช่องทำเครื่องหมายการแก้ปัญหาในบรรทัดเดียวกับปุ่มหรือบางสิ่ง มันดูแปลกไปตลอดทาง ยังเจ๋ง! +1
Maltysen

พยายาม (ข้อผิดพลาด ... ) i.stack.imgur.com/mTioT.png
edc65

@ Maltysen ฉันจะพิจารณาว่า ขอบคุณ!
kirbyfan64sos

@ edc65 ประณาม ... อะไรคือข้อผิดพลาดทั้งหมด? ดูเหมือนว่าอาจเป็นข้อผิดพลาดของ PyPy.js หรือความจริงที่ฉันไม่เคยทดสอบบน Firefox ...
kirbyfan64sos

1

จาวาสคริปต์156 153

var x=prompt(),f={},a=0,o
x.toUpperCase().replace(/([A-Z])\1+/g,function(m,s){m=f[s]=-~f[s]
if(a==m)o.push(s)
if(a<m)a=m,o=[s]})
alert(o.sort().join(""))


f[s]?f[s]+1:1->-~f[s]
edc65

มันล้มเหลวด้วยตัวอักษรที่ไม่ใช่:Count only letters from the English alphabet
edc65

ขอบคุณ @ edc65 ฉันได้เพิ่มทางลัดและการตรวจสอบ AZ
wolfhammer

1
รหัสที่แน่นอนของคุณสตรีมมิ่งและ ES6: f=x=>{x.toUpperCase(f={},a=0,o).replace(/([A-Z])\1+/g,(m,s)=>a<(m=f[s]=-~f[s])?(a=m,o=[s]):a>m?0:o.push(s));alert(o.sort().join'')}(2 สุดท้าย '' เป็น backticks จริงๆ & # 96
edc65

1

Bash + textutils (grep, sed), 111 chars

fold -1<<<$s|uniq -iD|sort -f|uniq -ic|sort -rn|grep -i [A-Z]|sed -n '1h;G;s/\(\s*\S\+\s\)\(.\)\n\1./\2/p'|sort

Bash + awk (แทน sed) 97 chars

fold -1<<<$s|uniq -iD|sort -f|uniq -ic|sort -rn|grep -i [A-Z]|awk '!n{n=$1};n==$1{print $2}'|sort

เพื่อทดสอบก่อนกำหนด s

s="Sally's friends Jimmy ää and Bobby rummaged ää for seashells."

0

R, 98 ไบต์

คล้ายกับโซลูชันของ Alex มาก แต่ใช้การเปลี่ยนตัวแทนที่จะจับคู่เพื่อกำหนดตัวอักษรที่ต่อเนื่องกัน การสแกนใช้ในการรับอินพุตและเพื่อแยกผลลัพธ์การแทนที่ในช่องว่าง

cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])

การทดสอบสองสามอย่าง

> cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])
1: 11 was a race horse, 22 was one too. 11 won one race and 22 one won too.
19: 
Read 18 items
Read 2 items
O
> cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])
1: Sally's friends Jimmy and Bobby rummaged for seashells.
9: 
Read 8 items
Read 5 items
L M
> cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])
1: 11ss11nn
2: 
Read 1 item
Read 2 items
N S
> 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.