我女儿的字母


65

前几天,我们和我的女儿用冰箱贴写了一封句子。尽管我们能够制作一些(I love cat),但I love you too由于字母数量不足o(4),我们没有足够的字母来制作其他()

然后我发现,虽然一组包含3个e字母,但只有2个o字母。可能受到http://en.wikipedia.org/wiki/Letter_frequency的启发,这仍然不能反映“冰箱上”的实际情况。

问题

给定文本文件,其中每行包含一个“样本语句”,一个人想在冰箱上书写,建议使用字母数量最少的字母集,但仍足以单独书写每个句子。

注意:忽略大小写,无论如何所有大写字母都是大写。

输入项

该文件包含换行符分隔的句子:

hello
i love cat
i love dog
i love mommy
mommy loves daddy

输出量

提供字母的倒排列表,其中每个字母仅出现多次,足以写出任何句子:

acdddeghillmmmoostvyy

(谢谢,isaacg!)

优胜者

最短的实现(代码)

更新:测试

我创建了一个额外的测试,并在这里尝试了各种答案:

https://gist.github.com/romaninsh/11159751


2
v输出中应该有一个字母;)
Antonio Ragagnin 2014年

40
我们现在可以/需要替换倒置MW,或者侧向NZ?;-)
Ilmari Karonen 2014年

4
基本上,您可以使用Is 构造任何字母。
swish 2014年

7
更严重的是,当您说“忽略大小写”时,您是说我们可以假定输入已经全部在相同的情况下,还是必须将所有输入都转换为相同的情况?另外,输出中是否可以包含一些前导空格?
Ilmari Karonen 2014年

3
@Doorknob:_\¯
Ilmari Karonen 2014年

Answers:


18

GolfScript,28/34个字符

n/:a{|}*{a{.[2$]--}%*$-1=}%$

上面的28个字符的程序假定所有输入字母都在相同的情况下。如果不一定是这样,我们可以通过{95&}%在代码之前加上大写字母来强制它们变为大写,总共34个字符:

{95&}%n/:a{|}*{a{.[2$]--}%*$-1=}%$

笔记:

  • 为了正确操作,输入必须至少包含一个换行符。对于在每行末尾都有换行符的普通文本文件,这将是正确的,但如果输入仅包含一行而没有尾随换行符,则可能不是正确的。可以通过n+在代码之前添加两个额外的字符来解决此问题。

  • 34个字符的版本中的大写字母实际上是粗略的-将小写ASCII字母映射为大写字母(并将空格映射为NULs),但是却完全弄乱了数字和大多数标点符号。我假设输入将不包含任何此类字符。

  • 28个字符的版本NUL均等地对待所有输入字符(换行符和s 除外)。特别是,如果输入包含任何空格,则某些空格也会出现在输出中;方便地,它们将在任何其他可打印ASCII字符之前排序。但是,34个字符的版本会忽略空格(因为事实证明我可以做到这一点,而不会花费我任何额外的字符)。

说明:

  • 可选的{95&}%前缀通过将每个输入字节()的ASCII码的第六位清零来使输入大写。这会将小写ASCII字母映射为大写字母,将空格映射为空字节,并使换行符保持不变。95 = 64 + 31 = 10111112

  • n/在换行符处分割输入,:a并将结果数组分配给变量a。然后{|}*计算数组中字符串的集合并集(假设数组至少包含两个元素)将产生一个包含输入中所有唯一(非换行符)字符的字符串。

  • 然后,以下{ }%循环遍历每个唯一字符。在循环体内,内部循环a{.[2$]--}%遍历数组中的字符串a,从每个字符串中删除不等于外部循环所遍历的所有字符。

    内部循环将当前字符的ASCII码保留在堆栈中的过滤数组下方。我们通过对已过滤的数组重复ASCII码(*)指示的次数,然后对其进行排序($)和获取最后一个元素(-1=)来使用此功能。实际上,这会产生过滤后的数组中最长的字符串(因为它们全部由相同字符的重复组成,字典排序只是按长度对它们进行排序),除非该字符的ASCII码为零(在这种情况下不会产生任何结果)。

  • 最后,$最后的只是按字母顺序对输出进行排序。


3
惊人。待办事项:学习GolfScript!
DLosc

1
您甚至可以将其减少到26 :n/:a{|}*{{{=}+,}+a%$-1=}%$
霍华德

13

J-37个字符

从stdin读取,输出到控制台。

dlb#&a.>./+/"2=/&a.tolower;._2[1!:1]3

1!:1]3是对stdin的调用。tolower;._2通过分割线并使它们同时小写来执行双重任务。然后,我们计算一个字符在每一行中出现多少次+/"2=/&a.,并使用取所有行上的逐点最大值>./

最后,我们使用来将每个字符中的许多个从字母表中拉出#&a.。这包括空格-由于它们的ASCII值较低,所以都在前面找到所有空格-因此,我们只需使用删除前导空格即可dlb


12

的JavaScript(ECMAScript的6) - 148个 139 135特性

版本2:

更新为使用数组理解:

[a[i][0]for(i in a=[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort())if(a[i-1]<a[i])]

版本1:

[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort().filter((x,i,a)=>a[i-1]!=x).map(x=>x[0])

假设:

  • 输入字符串在变量中s;
  • 我们可以忽略输入的大小写(由问题指定-即全部为大写或小写);
  • 输出是一个字符数组(大约与JavaScript可以达到OP对字符列表的要求一样);和
  • 输出将显示在控制台上。

有评论:

var l = s.split('\n')             // split the input up into sentences
         .map(x=>x.split(/ */)   // split each sentence up into letters ignoring any
                                  // whitespace
                  .sort()         // sort the letters in each sentence alphabetically
                  .map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))
                                  // append the frequency of previously occurring identical
                                  // letters in the same sentence to each letter.
                                  // I.e. "HELLO WORLD" =>
                                  // ["D0","E0","H0","L0","L1","L2","O0","O1","R0","W0"]
[].concat(...l)                   // Flatten the array of arrays of letters+frequencies
                                  // into a single array.
  .sort()                         // Sort all the letters and appended frequencies
                                  // alphabetically.
  .filter((x,i,a)=>a[i-1]!=x)     // Remove duplicates and return the sorted
  .map(x=>x[0])                   // Get the first letter of each entry (removing the
                                  // frequencies) and return the array.

如果你想:

  • 以字符串形式返回,然后.join('')在末尾添加;
  • 接受用户输入,然后将s变量替换为prompt(); 要么
  • 将其编写为函数,f然后添加f=s=>到开头。

正在运行:

s="HELLO\nI LOVE CAT\nI LOVE DOG\nI LOVE MOMMY\nMOMMY LOVE DADDY";
[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort().filter((x,i,a)=>a[i-1]!=x).map(x=>x[0])

给出输出:

["A","C","D","D","D","E","G","H","I","L","L","M","M","M","O","O","T","V","Y","Y"]

1
真好!您可以减少/\s*// */并删除括号来节省3个字节j=0
nderscore 2014年

1
您不能使用...代替apply吗?
2014年

都感谢您-节省了9个字符-Spread...)运算符是我以前从未遇到过的运算符。
MT0

[].concat(...s.split`N`.map(x=>x.split(/ */).map((x,i,a)=>x+(a[x]=a[x]?++j:j=1)))).sort().map((x,i,a)=>a[i-1]<x?x[0]:'').join``;
l4m2 '18年

11

Perl-46个字节

#!perl -p
$s=~s/$_//ifor/./g;$s.=uc}for(sort$s=~/\w/g){

将shebang计为1。这是下面Ruby解决方案的宽松翻译。


Ruby 1.8-72字节

s='';s+=$_.upcase.scan(/./){s.sub!$&,''}while gets;$><<s.scan(/\w/).sort

输入来自stdin

用法示例:

$ more in.dat
Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

$ ruby fridge-letters.rb < in.dat
ACDDDEGHILLMMMOOSTVYY

输出需要排序。
马特

@Matt现在固定。
primo

真好 如果您的Perl依旧模糊不清,则需要在/i和之间添加一个空格for
tobyink 2014年

8

蟒- 206 204 199 177 145 129 117 94 88个字符

print(''.join(c*max(l.lower().count(c)for l in open(f))for c in map(chr,range(97,123))))

我不确定如何获取文件名,因此目前代码假定该文件包含在名为的变量中f。请让我知道是否需要更改。


8
本着Unix的精神-您可以从stdin中阅读。
romaninsh 2014年

5
始终使文件名一个字符长...

3
@Tal我也是新手,但是如果它保存字符,为什么不呢?

1
通过假定f输入文件名并使用大写字母(无论如何,所有磁铁字母都是大写字母),您可以将其降至91:print(''.join([chr(i)*max(l.upper().count(chr(i))for l in open(f))for i in range(65,91)]))
Gabe 2014年

1
@ njzk2好吧,如果我们在控制台中运行它,从理论上讲,它只会自行打印结果……
Tal 2014年

6

Ruby 1.9 +,51(或58或60)

a=*$<
?a.upto(?z){|c|$><<c*a.map{|l|l.count c}.max}

假定所有内容都小写。不区分大小写的成本为7个字符.upcase,而不区分大小写和小写的输出成本为9个字符.downcase


4

R(156,包括已读取的文件)

使用表,我为每个句子构造了字母频率表。然后,我最后为每个字母取最大值。

a=c();for(w in tolower(read.csv(fn,h=F)$V1))a=c(a,table(strsplit(w,"")[[1]]));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")

取消高尔夫:

a=c()
words = read.csv(fn,h=F)$V1
for(w in tolower(words))
  a=c(a, table(strsplit(w, "")[[1]]))
a = tapply(seq(a), names(a), function(i) max(a[i]))[-1] ## The -1 excludes the space count.
cat(rep(names(a), a), sep="")

解:

acdddeghillmmmoooooostuvyy

@lambruscoAcido,您可以向量化(取消高尔夫代码的)前三行,这将给您带来好处a=unlist(lapply(readLines(fn),function(x)table(strsplit(tolower(x),""))));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep=""),但是它只短了3个字符
jkd

cat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")假设只有112个字符的另一种方法f是文件名
jkd

4

哈斯克尔, 109 108

import Data.List
import Data.Char
main=interact$sort.filter(/=' ').foldl1(\x y->x++(y\\x)).lines.map toLower

该程序从stdin读取并写入sdtout。

这非常简单:将字符串分成行列表,并通过在列表上进行迭代并添加每行中包含的新字母来重建字符串。


噢,为什么我以前从未听说过(\\)?
Flonk


4

Perl 6:56 53个字符;58 55字节

say |sort
([∪] lines.map:{bag comb /\S/,.lc}).pick(*)

对于每一行,它会针对小写字符串(comb /\S/,.lc)的非空格字符进行梳理,并Bag为每个字符以及每个字符及其出现的次数进行集合。在所有行[∪]上采用Bags 的并集,从而获得字符出现的最大次数。.pick(*)在这里很糟糕,但这是从Bag复制品中获得所有字符的最短方法,即复制的次数。

编辑:看是否会更短,我尝试翻译histocrat的Ruby answer。它是63个字符,但我仍然非常喜欢这种方法:

$!=lines».lc;->$c{print $c x max $!.map:{+m:g/$c/}} for"a".."z"

3

Haskell中,183 162 159

假设文件在file.txt

import Data.Char
import Data.List
main=readFile"file.txt">>=putStr.concat.tail.map(tail.maximum).transpose.map(group.sort.(++' ':['a'..'z'])).lines.map toLower

例如,如果file.txt包含

abcde
abcdef
aaf

脚本将输出

aabcdef

基本上,我会将整个字母附加到每一行,以便在进行分组和排序时,我确定最终会得到一个包含27个元素的列表。接下来,我转置“频率表”,以便此数组中的每一行都由每行中单个字母的频率组成,例如["a","","aaa","aa","aaaa"]。然后,我选择每个数组的最大值(由于OrdString 的-instance的工作原理,因此可以像我想要的那样工作),然后删除开头添加的字母,去除空格,然后输出结果。


1
取而代之的是drop 1,只需使用tail
Bergi 2014年

@Bergi Haha derp,谢谢!我在帖子中进行了更改。
Flonk

3

C,99个字符

t[256];main(c){for(--*t;++t[1+tolower(getchar())];);for(c=97;c<123;c++)while(t[c]--)putchar(c-1);}

如果提供少于一个换行符,它将崩溃。我认为可以很容易地解决它。


我尝试过,但是没有产生正确的结果。gist.github.com/romaninsh/11159751
romaninsh

3

kdb(q / k):59个字符:

d:.Q.a! 26#0
.z.pi:{d|:.Q.a##:'=_y}.z.exit:{-1@,/.:[d]#'!:d}
  • 从字母.qa生成预排序的种子字典
  • 处理输入的每一行,转换为小写字母,分组为字典,计数每个元素,从结果中获取字母字符(例如,在此阶段修剪空格,换行符等),并使用max-assign到global d来保持运行总数。
  • 定义退出处理程序,该处理程序将传入.z.pi以保存定界符,但在此未使用。从每个键值中生成字符列表,展平并最终打印到stdout。

-1添加一个换行符,使用1将保存一个字符,但不生成指定的输出。希望我能摆脱.z.pi / .z.exit样板,它将删除14个字符。

编辑:通过使用种子字典避免使用inter / asc。


3

Perl,46岁

for$:(a..z){$a[ord$:]|=$:x s/$://gi}}{print@a

这是从STDIN读取的另一种Perl解决方案,需要-n切换(+1计数),与primo的得分保持联系,但运行时不会有任何抱怨:-)。它利用了一个事实,即逐位or的结果具有更长的字符串参数的长度。


1
尝试了我的测试,效果很好。
romaninsh 2014年

3

我要添加自己的解决方案:

重击-72

假设输入在文件“ i”中

for x in {A..Z};do echo -n `cat i|sed "s/[^$x]//g"|sort -r|head -1`;done

说明

对于每个可能的字母,仅将其从输入文件中过滤掉,结果如下:

AAA
A
A

AAAA

A
AAAAAAAAAAAAAAAA

然后对结果进行排序并选择最长的行。echo -n是否有删除换行符。


3

巴什171 159 158、138带垃圾输出

需要仅小写的输入。假定该文件被调用_(下划线)。由于split创建了令人讨厌的文件名(xaa,xab ... xaz,???),输入文件中最多26行。

bash{a..z}输出a b c d e f ...

touch {a..z}
split _ -1
for l in {a..z}
do for s in {a..z}
do grep -so $l xa$s>b$l
if [ `wc -l<b$l` -ge `wc -l<$l` ]
then mv b$l $l
fi
done
tr -d '\n'<$l
done

样品输出

acdddeghillmmmoostvyy

说明

touch {a..z}

创建我们稍后将要阅读的文件,以便bash不会抱怨它们不存在。如果删除此行,将节省13个字符,但会得到很多垃圾输出。

split _ -1

将输入文件拆分为多个部分,每个部分存储1行。该命令创建的文件名为xaa,xab,xac等,我不知道为什么。

for l in {a..z}
do for s in {a..z}

对于每个字母,请$l阅读存储在文件中的所有行xa$s

do grep -so $l xa$s>b$l

删除-s开关以节省1个字符,并获得大量垃圾输出。它可以防止grep抱怨文件不存在(除非您输入26行,否则将发生)。这将处理文件xa$s,除去出现的所有内容$l,然后将输出发送到文件b$l。因此,当我$l是m 时,每个字母后的“我爱妈妈”都将用新行变成“ mmm” 。

if [ `wc -l<b$l` -ge `wc -l<$l` ]

如果我们刚创建的文件中的行数大于或等于(即,由于每行有一个字母,则为更多字母),这是我们迄今为止最高结果(存储在中$l)的行数。

then mv b$l $l

...将我们的新记录存储在文件中$l。在循环结束时,当我们遍历所有行时,文件$l将存储x行,每行包含字母$l,其中x是该行在同一行中出现的最高次数。

fi
done
tr -d '\n'<$l

输出该特定字母的文件内容,删除新行。如果您不想删除新行,请将更改为,trecho $l节省6个字符。

done

与GNU bash中,版本51年2月3日(苹果),但文件“-l1aa”在包含输入数据的当前文件夹试图..
romaninsh

@romaninsh可能是您split(与coreutils)的版本不同。我目前在Ubuntu 14.04上运行GNU bash 4.3.8和GNU coreutils 8.21,并且运行良好(在升级之前,它也可以在Ubuntu 13.10上运行)。但是,我确实必须将程序和输入文件放置在单独的目录中才能正常工作-我怀疑这仅仅是由于home文件夹中有数百万个垃圾文件

@romaninsh实际上,如果您查看脚本中的确切命令:split _ -l1并且您注意到您的输入已保存到-l1aa,我认为您的版本split 不会被识别-l1为选项,而是将其作为输出的前缀。尝试在-l和之间放置一个空格1,或者在--lines=1或之间放置一个空格-1(这似乎是一种过时的,更具讽刺意味的语法,我现在将使用该语法更新帖子)。

3

C#,172个字节

var x="";foreach(var i in File.ReadAllText(t).ToLower().Split('\r','\n'))foreach(var j in i)if(x.Count(c=>c==j)<i.Count(c=>c==j))x+=j;string.Concat(x.OrderBy(o=>o)).Trim();

聪明的……聪明的……我曾考虑过与linq一起玩,但是怀疑它会像这些扭曲的foreachs一样短:)
Noctis

2

Python 2-129

@Tal的想法

a,r=[0]*26,range(26)
for l in open('f'):a=[max(a[i],l.lower().count(chr(i+97)))for i in r]
print''.join(chr(i+97)*a[i]for i in r)

在相同数量的字符中执行相同操作的其他几种方法:

a=[0]*26
b='(chr(i+97)))for i in range(26)'
exec'for l in open("f"):a=[max(a[i],l.lower().count'+b+']\nprint"".join(a[i]*('+b+')'

a=[0]*26
b='(chr(i+97)))for i in range(26))'
exec'for l in open("f"):a=list(max(a[i],l.lower().count'+b+'\nprint"".join(a[i]*('+b

假定该文件另存为f在可访问目录中。该程序可直接运行,无需额外输入。


为什么要投反对票?对不起,我做错了什么。
isaacg 2014年

2

Mathematica v10-110

还没有出来,但是要非常仔细地阅读新文档,我认为这应该可行:

StringJoin@MapIndexed[#2~Table~{#1}&,Rest@Merge[Counts/@Characters@StringSplit[ToLowerCase@Input[],"\n"],Max]]

2

Scala,125个字符

val i=""::io.Source.stdin.getLines.toList.map(_.toLowerCase);println('a'to'z'map(c=>(""+c)*i.map(_.count(_==c)).max)mkString)

首先,我读取输入,将其转换为小写并添加一个空行。

然后,对于从a到的每个字母,z我重复该字母在任何行中出现的最大次数(这就是为什么我需要空行:max不能在空输入中调用)。然后,我只加入结果并打印到输出。

要读取文件,请替换stdinfromFile("FILENAME"),将代码的大小增加到132个字符+文件名长度。


2

Javascript,261个字符

eval('s=prompt().toUpperCase().split("\\n");Z=[########0,0];H=Z.slice();s@r){h=Z.slice();r.split("")@c){if(c.match(/\\w/))h[c.charCodeAt(0)-65]++});H=H@V,i){return V>h[i]?V:h[i]})});s="";H@n,i){s+=Array(n+1).join(String.fromCharCode(i+97))});s'.replace(/@/g,".map(function(").replace(/#/g,"0,0,0,"))

删除eval(...)并执行以获取真实代码;这是(稍微)压缩。

s作为行数组和输出字符串的多功能控件,h包含每行字母的直方图,并H包含迄今为止的最大值的直方图。它不区分大小写,只忽略az和AZ(我认为... JS数组有时很奇怪)。

现在正确:)


这只是字符的总数,并不完全是问题要问的内容。字母应合计为构成输入中任何单个句子(而不是全部)的最小集。我非常喜欢您的方法来避免需要对输出进行排序。
马特

@Matt哦,是的...我稍后再修复。现在还没有时间。
tomsmeding 2014年

1
不知道到底发生了什么,@直到我结束。我喜欢:)
Matt

2

JavaScript(ES5)141字节

假设变量s是没有大小写检查要求和数组输出的输入字符串:

for(a in s=s[o=_='',y='split']('\n'))for(i=0;x=s[a][i++];)o+=x!=0&&(l=s[a][y](x).length-~-o[y](x).length)>0?Array(l).join(x):_;o[y](_).sort()

我测试了您的解决方案,并在“ o”内部寻找输出,但似乎未正确排序。(见gist.github.com/romaninsh/11159751
romaninsh

@romaninsh我在要点中看到的输出看起来已正确排序
nderscore 2014年

是的,这是参考/正确的输出。当我尝试您的代码时,我得到了:gist.github.com/romaninsh/11161018
romaninsh 2014年

抱歉,如果我错误地执行了您的示例。
romaninsh 2014年

@romaninsh啊,我原本打算在浏览器的控制台中运行它。这是经过重新格式化的版本,可以在节点上使用:gist.github.com/nderscore/96aa888c77d275c26c15
nderscore 2014年

2

PowerShell的-141

从名为“ a”的文件中读取文本。

$x=@{}
gc a|%{[char[]]$_|group|%{$c=$_.name.tolower().trim()
$n=$_.count;$x[$c]=($n,$x[$c])[$n-lt$x[$c]]}}
($x.Keys|sort|%{$_*$x[$_]})-join""

2

Groovy,113/ 127 102/116个字符

假设文件全部为一种情况(102个字符):

t=new File('f').text;t.findAll('[A-Z]').unique().sort().each{c->print c*t.readLines()*.count(c).max()}

假设文件大小写混合(116个字符):

t=new File('f').text.toUpperCase();t.findAll('[A-Z]').unique().sort().each{c->print c*t.readLines()*.count(c).max()}

基本上:

  • t=new File('f').text 获取文件的文本。
  • t.findAll('[A-Z]').unique().sort().each{c-> 要获取唯一字符,请对其进行排序并进行迭代。
  • print c*t.readLines()*.count(c).max() 单行获取最大出现次数,并多次打印字符。

2

重击(主要是awk)- 172 163 157

awk -v FS="" '{delete l;for(i=1;i<=NF;i++)l[toupper($i)]++;for(i in l)o[i]=(o[i]>l[i]?o[i]:l[i])}END{for(i in o)for(j=0;j<o[i];j++)print i}'|sort|tr -d ' \n'

文本需要通过管道传输到awk(或指定为文件)。

输入示例

Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

示例输出

ACDDDEGHILLMMMOOSTVYY

PHP(可能会更好)- 174 210

$o=array();foreach(explode("\n",$s) as $a){$l=array();$i=0;while($i<strlen($a)){$k=ucfirst($a[$i++]);if($k==' ')continue;$o[$k]=max($o[$k],++$l[$k]);}}ksort($o);foreach($o as $k=>$v)for($i=0;$i<$v;$i++)echo $k;

假定字符串包含在变量$ s中

输入示例

Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

示例输出

ACDDDEGHILLMMMOOSTVYY

2

我意识到这可能不是最有效的答案,但是我还是想尝试解决问题。这是我的ObjC版本:

- (NSArray *) lettersNeededForString:(NSString *)sourceString {
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@" " withString:@""];
    const char * sourceChars = sourceString.UTF8String;
    NSMutableArray * arr = [NSMutableArray new];
    for (int i = 0; i < sourceString.length; i++) {
        [arr addObject:[NSString stringWithFormat:@"%c", sourceChars[i]]];
    }
    return [arr sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}    

然后,您可以为任何字符串调用它:

NSArray * letters = [self lettersNeededForString:@"Hello\nI love cat\nI love dog\nI love mommy\nMommy loves daddy"];
NSLog(@"%@",letters);

我当时正在考虑使用大量文本的应用程序,而我宁愿不必计算我的数组。为此,我将方法添加到此方法中:

- (NSDictionary *) numberOfLettersNeededFromString:(NSString *)sourceString {

    sourceString = [sourceString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@" " withString:@""];
    const char * sourceChars = sourceString.UTF8String;
    NSMutableArray * arr = [NSMutableArray new];
    for (int i = 0; i < sourceString.length; i++) {
        [arr addObject:[NSString stringWithFormat:@"%c", sourceChars[i]]];
    }

    static NSString * alphabet = @"abcdefghijklmnopqrstuvwxyz";
    NSMutableDictionary * masterDictionary = [NSMutableDictionary new];
    for (int i = 0; i < alphabet.length; i++) {
        NSString * alphabetLetter = [alphabet substringWithRange:NSMakeRange(i, 1)];
        NSIndexSet * indexes = [arr indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
            if ([[(NSString *)obj lowercaseString] isEqualToString:alphabetLetter]) {
                return YES;
            }
            else {
                return NO;
            }
        }];

        masterDictionary[alphabetLetter] = @(indexes.count);
    }

    return masterDictionary;
}

运行像:

NSDictionary * lettersNeeded = [self numberOfLettersNeededFromString:@"Hello\nI love cat\nI love dog\nI love mommy\nMommy loves daddy"];
NSLog(@"%@", lettersNeeded);

会给你:

{a = 2; b = 0; c = 1;d = 4;e = 5;f = 0; g = 1;h = 1;我= 3; j = 0; k = 0; l = 6;m = 6;n = 0; o = 8;p = 0; q = 0; r = 0; s = 1; t = 1;u = 0; v = 4;w = 0; x = 0; y = 3;z = 0; }

如果我有大量文本,并且只需要知道每个字母需要多少个字母,我认为这会更好。



2

Python 2,154字节

import collections
c = collections.Counter()
for line in open("input.txt"):
    c |= collections.Counter(line.upper())
print "".join(sorted(c.elements()))

欢迎来到PCG!该站点支持Markdown语法,您可以使用该语法来格式化代码,从而使其看起来不错:只需将代码的每一行缩进4个空格。
algorithmhark

您需要添加导入集合所需的字符。
isaacg 2014年

1
不能回答问题,因为您需要最少的字母数量才能单独写每个句子。在您的代码中,输出同时写所有句子所需的字母数。
njzk2 2014年

您在语句s末尾缺少,import并且该with块缺少缩进。并且由于这是代码高尔夫,因此在可能的情况下删除不必要的空白将使您受益匪浅。
Fraxtil 2014年

由于这是代码高尔夫球,因此删除with语句(只需在调用open上循环),我认为这些元素不需要排序。
RemcoGerlich 2014年

2

C,298字节

char c;
int j,n;
char C[26];
char D[26];
int main()
{
char a='a';
while((c=getchar())>=0)
{
c=tolower(c);
if(c>=a&&c<='z'){j=c-a;D[j]++;}
if(c=='\n'){
for(j=0;j<26;j++){
if(D[j]>C[j])
{C[j]=D[j];}
D[j]=0;
}
}
}
for(j=0;j<26;j++)
{
n=C[j];
while(n--)
{
putchar(a+j);
}
}
}

数组D保持每一行的字母计数,然后将最大计数复制到C。

注意:我昨天放了答案,但现在未列出,也许我按了Delete键而不是错误编辑?


只有271个字节。您也有很多无关的换行符。另外,您可以省略intfrom int main()int j,n;
nyuszika7h 2014年

另外,您先前的答案仍然存在。
nyuszika7h 2014年

2

PHP,143字节

假设输入是通过变量传递的$s

$i=explode("\n",$s);foreach(range('a','z')as$c){$x=array_map(function($l)use($c){return substr_count($l,$c);},$i);echo str_repeat($c,max($x));}

说明

对于每个可能的字母,我正在通过用户定义的函数映射包含字符串列表的数组,该函数使用每行使用的字符数替换每行。对于字母“ d”,“妈妈爱爸爸”行将被映射为3。

之后,我多次在数组中找到最大值并输出字母。这是多行版本:

$i=explode("\n",$s);
foreach(range('A','Z')as $c){
    $x=array_map(function($l)use($c){
        return substr_count($l,$c);
    },$i);
    echo str_repeat($c,max($x));
}

1

Python(209,附带示例,不包括136):

from collections import*;c=Counter()
for i in ["Hello","I love cat", "I love Dog", "I love mommy", "Mommy loves daddy"]:
 for j in i.lower(): c[j]=max(c[j],list(i).count(j))
print "".join(sorted(c.elements()))

我今天下午发布一个PYG示例。


我不知道Python字符串有一个count方法...我不认为改变我对问题的答案以使用这种新发现的知识被认为是合法的吗?:p
Tal 2014年

@tal他们没有。这是一个列表的方法,如果你仔细看
ɐɔıʇǝɥʇuʎs

1
哦,我知道了……但在意外的转折中,结果证明字符串显然也具有此方法(无论如何在3.x中)
Tal 2014年
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.