将单数转换为复数


27

名词有两种形式,单数和复数。两者之间的转换非常容易。

  1. 通常,您以结尾s。例如 car=> cars

  2. 如果结尾sxzchsh与结束它es。例如 bus=> buses

  3. 如果它y以一个辅音结尾,则将更改yies。例如 penny=> pennies

  4. 如果以f或结尾fe,请将其更改为ves。例如 knife=> knives

  5. 如果它o以一个辅音结尾,则将其更改为oes。例如 potato=> potatoes


任务

您将被赋予一个单数名词。您必须将给定的名词转换为复数并将其输出。


规则

  • 您将不会获得诸如mouse和的不规则名词moose

  • 不会给您例外,例如safesafes;违反#4),pianopianos;违反#5)和ooes,违反#5)。

  • 系统不会为您提供具有两种或多种可能的复数形式的单词,例如mosquitomosquitosmosquitoes)和roofroofsrooves)。

  • 您将不会得到不可数的名词。

  • y 不算元音。


例子

car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios

为清楚起见,已编辑问题。随时回滚。
JungHwan Min

11
啊,英语-大量的任意规则和特殊情况:)
硕果累累

38
@ Challenger5是的,但是您可以通过艰难的透彻思考来理解它。;)
JungHwan Min

@MatthewRoh我已经编辑了前置规则中的辅音,以使其更清晰。同样也添加了一些测试用例。如果我误解了,请对其进行修改以弄清楚。
ghosts_in_the_code

2
@ Challenger5如果将英语与荷兰语进行比较,则几乎没有任何规则。荷兰语有规则和特殊情况,特殊情况与那些特殊情况相矛盾,在某些情况下甚至与特殊情况相矛盾的特殊情况也与那些特殊情况相矛盾。;)
Kevin Cruijssen

Answers:


46

Mathematica,9个字节

Pluralize

是的,这是内置的!

样品输出

Pluralize["car"]

cars

Pluralize /@ {"bus", "potato", "knife", "penny", "exception", "wolf", "eye"}

{"buses", "potatoes", "knives", "pennies", "exceptions", "wolves", "eyes"}


6
哇!Mathematica有没有内置的功能吗?
KeyWeeUsr

2
D:内建人也攻击了这一挑战
马修·鲁


18

Retina57 53 56 55 58 57字节

感谢MartinEnder的一些高尔夫建议

感谢BusinessCat打高尔夫球1个字节

([^aeiou]o|sh?|ch|z|x)$
$1e
fe?$
ve
([^aeiou])y$
$1ie
$
s

在线尝试!

说明(过时)

([^aeiou])y$
$1ie

更改{consonant}y{consonant}ie

([^aeiou]o|[fxzs]|[sc]h)$
$&e

一个附加e到当与字两端{consonant}ofxzsshch

fe$
ve

将结尾更改feve

$
s

最后s在这个词后面加上一个。

编辑

  • 添加字节,因为我忘记了第二条规则
  • 以添加字节eye为例进行更新

1
抱歉,如果这是一个愚蠢的问题,我没有使用Retina。为什么第一行需要圆括号?
user2390246'3

没关系,我想我已经回答了我自己的问题。这是由于下一行中的回溯引用。
user2390246'3

是的,这是因为我们要在y使用之前捕获角色$1
Kritixi Lithos

我认为我有57个字节:在线试用
Business Cat

16

JavaScript(ES6), 109  97字节

s=>s[R='replace'](/([^aeiou])y$/,'$1ie')[R](/fe?$/,'ve')[R](/([^aeiou]o|[sxz]|[cs]h)$/,'$1e')+'s'

在线尝试!


你为什么()在前面fe
Kodos Johnson

1
@KodosJohnson所有replace()迭代都包含对第一个匹配组(带有$1)的引用。这就是为什么我在这里需要一个空的匹配组。
Arnauld

你试过了(?<![aeiou])y吗?
泰特斯

@Titus不幸的是,JS没有实现后向断言。
Arnauld

11

批处理,325字节

@set/ps=
@for %%v in (a e i o u)do @(
for %%e in (o y)do @if %s:~-2%==%%v%%e goto s
if %s:~-2%==%%vf set s=%s:~,-1%ve&goto s
if %s:~-3%==%%vfe set s=%s:~,-2%ve&goto s
)
@if %s:~-1%==y set s=%s:~,-1%ie
@for %%e in (o s x z)do @if %s:~-1%==%%e set s=%s%e
@for %%e in (c s)do @if %s:~-2%==%%eh set s=%s%e
:s
@echo %s%s

怎么样@echo off开头,而不是@到处?此外,@set/ps=手机似乎有些生锈。不会对s变量接受切片值呢?
KeyWeeUsr

@KeyWeeUsr @echo off已经是9个字节,没有换行符,因此它不会为我节省任何费用。另外,@set/ps=首先需要输入值。
尼尔

7

Haskell中,216个 207 205字节

感谢@ Lynn,@ user1472751和@Laikoni的帮助!

import Data.List
(!)s=or.map(\x->x`isSuffixOf`s)
c=['b'..'z']\\"eiou"
p s|s!(words"s x z ch sh"++map(:"o")c)=s++"es"|s!map(:"y")c=init s++"ies"|s!["f"]=init s++"ves"|s!["fe"]=(init.init)s++"ves"|0<1=s++"s"

可读的

import Data.List;

endsWithOneOf :: String -> [String] -> Bool
endsWithOneOf str ends = (or . map (\end -> end `isSuffixOf` str)) ends 

consonants :: [Char]
consonants = ['a'..'z'] \\ "aeiou"

pluralize :: String -> String
pluralize str
    | str `endsWithOneOf` (words "s x z ch sh" ++ (map (:"o") consonants)) = str ++ "es"
    | str `endsWithOneOf` (map (:"y") consonants) = init str ++ "ies"
    | str `endsWithOneOf` ["f"] = init str ++ "ves"
    | str `endsWithOneOf` ["fe"] = (init.init) str ++ "ves"
    | otherwise = str ++ "s"

说明

import Data.List为功能isSuffixOfendsWithOneOf在高尔夫球版本中)返回列表元素之一是否为字符串的结尾。 consonants(c)只是所有辅音的列表。

最后,pluralize(p)检查结尾并返回正确的复数形式。

例:

p "potato" == "potatoes"

1
不错的解决方案!这是216个字符,但长度为多个字节,因此您的解决方案为226个字节。(代码高尔夫挑战赛以字节为单位明确得分,因为计数字符有时会让您作弊。)不过,您可以将其重命名为!!另外,words"s x z ch sh"保存5个字节。删除周围的括号,(map(:"o")c))(map(:"y")c))节省4个以上。
林恩

感谢您的帮助,@ Lynn!我执行了您的建议。
Eisfunke

2
您可以使用来保存一个字节,c=['b'..'z']\\"eiou"因为'a'总是会删除它。
user1472751 2017年

1
0<1True。短一字节。换行符的字节数也;与之相同,但是使高尔夫球代码的可读性更高。
Laikoni


5

Röda,80个字节

f&s{s~="([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve"s.="s"}

该函数修改其参数。用法:main word { f word; print word }这是使用返回值(83字节)的版本:

f s{s~="([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve";[s.."s"]}

下面是一个函数,该函数从输入流中读取无限多个值,并将多种形式压入输出流(87 83个字节):

{replace"([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve","$","s"}

这是一个匿名函数,因为它比创建命名函数要短。


如何显示第一个函数的结果(以开头的函数f&s)?只是f("word")似乎没有显示任何东西
Kritixi LITHOS

@KritixiLithos参数是引用,因此参数必须是变量。
fergusq

5

PHP,103100字节

<?=preg_replace(['/([^aeiou]o|sh?|x|z|ch)$/','/(?<![aeiou])y$/','/fe?$/'],['\1e',ie,ve],$argv[1]).s;

在线尝试!

preg_replace函数接受一系列模式和替换。

  • 感谢Titus,节省了2个字节。
  • 感谢Dewi Morgan,节省了1个字节。

2
我认为您可以使用-R和保存一个字节$argn。使用断言可y节省两个:(?<![aeiou])y$允许ie替换:no \1,无引号。
泰特斯(Titus)

1
另一个字节来自([^aeiou]o|sh?|x|z|ch)$
Dewi Morgan'3

@Titus实际上,看起来使用)-R-r1个字节的罚款,不幸的是,它不会改变字节数。但后视建议很有效。谢谢。
科多斯·约翰逊,

4

Python 3中,271 239 199字节

感谢@ovs将其减少了72个字节!

lambda s,v="aeiou":(s[-2:]=="fe"and s[:-2]+"ve"or s[:-1]+((s[-1]=="y"and s[-2]not in v)*"ie"or s[-1]=="f"and"ve"or s[-1]+((s[-1]in"sxz"or s[-2:]in["ch","sh"])+(s[-1]=="o"and s[-2]not in v))*"e"))+"s"

在线尝试!


1
您可以删除一些不必要的空格,并将first和last组合在一起elif。单个字符列表可以用字符串替换。切换到python可节省额外的3个字节。tio
ovs'Mar

@ovs完成,谢谢!我没有结合elif然而S,因为这意味着potatopotaties
numbermaniac

1
我看错了方向;)。您可以将if与最后一个elif结合使用。要节省更多字节,请用替换最后一行,print(s+"s")并删除else大小写以及您要附加到单词后面的每个s。蒂奥
ovs'Mar

1
当您用and/*和替换if / elif逻辑or/+并创建一个未命名的lambda函数时,可以得到200个字节以下的字节(我将情况换了一下)
ovs

@ovs哦,这print(s+"s")很聪明。都变了;您几乎重写了整个事情,哈哈。谢谢!(我什至不知道您可以那样做True and "string"
numbermaniac

2

sed,70 79字节

(BSD)/ (GNU)标志的69 78 +1-E-r

s/([^aeiou])y$/\1ie/
s/([^aeiou]o|[fxzs]|[sc]h)$/&e/
s/fe/ve/
s/$/s/

视网膜直接口


2

63 61字节

Y`[^aeiou]`OaR[C`sh?|x|z|ch`Cy.'y`fe?`y.'o].'$[_B.'i'v_].'e's

如此接近视网膜!但这可能不会发生。:(

在线尝试!

说明

基本策略:R当给定模式和替换列表时,eplace依次执行多次替换。我们要进行以下替换:

  • (sh?|x|z|ch)$ ->添加一个 e
  • [^aeiou]y->更改yi并添加一个e
  • fe?->更改为v并添加一个e
  • [^aeiou]o ->添加一个 e

然后我们想s不管。

技巧:

  • C给定正则表达式的运算符将其包装在捕获组中;C`xyz``(xyz)`。短一字节。
  • 通过将字符连接到列表而不是将其包括在所有项目中,可以创建全部以相同字符结尾的正则表达式或替换列表。将标量(字符串)连接到模式(正则表达式/替换)强制转换为模式。
  • 相反串接的s(和必须处理的优先排序R.),我们可以简单的O本安输出字的主要部分,然后打印s分开。

空格和注释代码:

                  a is 1st cmdline input (implicit)
Y`[^aeiou]`       Yank the consonant regex into the y variable
O a R             Output (without newline): a, with the following replacements:
 [                List of regexes to replace:
  C `sh?|x|z|ch`    (sh?|x|z|ch)
  Cy . 'y           ([^aeiou])y
  `fe?`             fe?
  y . 'o            [^aeiou]o
 ] . '$           End of list; concatenate $ to each item
 [                List of replacements:
  _                 Identity function (replace with whole match)
  B                 B is short for {b}, a function returning its second argument; as a
                    callback function for regex replacement, the second argument is
                    the value of capturing group 1 (the consonant before y)
    . 'i            To that, concatenate i
  'v                Scalar literal v
  _                 Identity function
 ] . 'e           End of list; concatenate e to each item
's                Return Scalar literal s, which is autoprinted

2

C#,73个 163字节:

Func<string,string>p=System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(System.Globalization.CultureInfo.CurrentCulture).Pluralize

是的,内置了另一种语言(尽管您需要添加对的引用System.Data.Entity.Design.dll

使用方法:

var words = new[] { "car", "bus", "potato", "knife", "penny", "exception", "wolf", "eye", "decoy", "radio" };
foreach (var word in words)
{
    var plural = p(word);
    Console.Out.WriteLine($"{word} => {plural}");
}

输出:

car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios

欢迎来到该网站。如何运行此代码?
小麦巫师

@WheatWizard已更新。我是否应该在字节数中包含更多详细信息(使用语句等)?
RoadieRich

琐事的有趣点,与此相反(单数化)的失败了很多简单的测试用例。例如,它确信“课程”的单数是“ cours”。
Morgan Thrapp

我认为名称空间需要包含在该字节数中,特别是考虑到它不是“正常”的名称空间之一。但是我认为您也至少需要将其包装在lambda中,并将参数传递给方法。因为这只是一个方法组
pinkfloydx33'3

@ pinkfloydx33现在更好了吗?
RoadieRich

2

Python的199 187个 176字节

lambda s:s+'\bve'*(s[-1]=='f')+'\b\bve'*(s[-2:]=='fe')+'e'*(s[-1]in'sxz'or s[-2:]in('ch','sh')or s[-1]=='o'and s[-2]not in'aiueo')+'\bie'*(s[-1]=='y'and s[-2]not in'aiueo')+'s'

2

Rails运行程序,18字节

$><<gets.pluralize

例:

$ echo knife | rails r filename.rb
knives

现在,这是一种深奥的语言。
2015年

2

Python, 296 字节

z = input()
if z[-1]in['s','x','z','ch','sh']:print(z+'es')
elif z[-1]=='y'and z[-2]not in['a','e','i','o','u']:print(z[:-1]+'ies')
elif z[-2:]=='fe':print(z[:-2]+'ves')
elif z[-1]=='f':print(z[:-1]+'ves')
elif z[-1]=='o'and z[-2]not in['a','e','i','o','u']:print(z[:-1]+'oes')
else:print(z+'s')

0

视网膜直接端口:

红宝石,111字节

'sub(/([^aeiou])y/){"#{$1}ie"};sub(/(.*)([^aeiou]o|[fxzs]|[sc]h)$/){"#{$1}#{$2}e"};sub(/fe/,"ve");sub(/$/,"s")'

在线尝试!

通过调用ruby -lpe并提供一个文件作为input.txt第一个CLI参数。


可能更“贴切”。顺便说一句:可以将文件添加到TIO吗?
stephanmg

0

C,321字节

#define E else if(
#define C unsigned char
C*p(C*b){static C r[999],i,w,n,m;for(n=w=i=0;r[i]=b[i];n=w,w=b[i++]);m=!strchr("aeiou",n);if(strchr("sxz",w)||(w=='h'&&strchr("cs",n))||(w=='o'&&m))r[i++]='e';E'y'==w&&m)r[i-1]='i',r[i++]='e';E'f'==w)r[i-1]='v',r[i++]='e';E'f'==n&&w=='e')r[i-2]='v';r[i++]='s';r[i]=0;return r;}

测试:

C*mx[]={"car","bus","potato","knife","penny","exception","wolf","eye","decoy","radio",0};

main()
{unsigned i;
 for(i=0;mx[i];++i)
    printf("[%s] [%s]\n", mx[i], p(mx[i]));
 return 0;
}

结果:

[car] [cars]
[bus] [buses]
[potato] [potatoes]
[knife] [knives]
[penny] [pennies]
[exception] [exceptions]
[wolf] [wolves]
[eye] [eyes]
[decoy] [decoys]
[radio] [radios]
[radio] [radios]

应该wolves不会wolfves
mbomb007 '04

@ceilingcat“静态C r [256],/ * Z =“ aeiou”,i = 0,w,n;“怎么办?代替“静态C r [256]; C / * Z =“ aeiou”,i = 0,w,n;“?
RosLuP


-1

Java 7,408字节

打高尔夫球:

boolean b="bcdfghjklmnpqrstvwxyzs".contains(String.valueOf(s.charAt(s.length()-2))); String x=s.substring(0,s.length()-1);if(s.endsWith("s")||s.endsWith("x")||s.endsWith("z")||s.endsWith("ch")||s.endsWith("sh"))return s+"es";if(s.endsWith("y")&&b)return x+"ies";if(s.endsWith("f")) return x+"ves";if(s.endsWith("fe"))return s.substring(0,s.length()-2)+"ves";if(s.endsWith("o")&&b)return s+"es";return s+="s";

基本上测试String的末尾,并根据大小写情况添加/替换字母。开头的boolean和String只是为了消除测试用例中的重复并使代码更小。

可读版本:

public static String pluralize(String s){

// Consonant at the 2nd last position?
boolean b = "bcdfghjklmnpqrstvwxyzs".contains(String.valueOf(s.charAt(s.length()-2))); 

// Substring for cases where last letter needs to be replaced
String x = s.substring(0,s.length()-1);

if(s.endsWith("s") || s.endsWith("x") || s.endsWith("z") || s.endsWith("ch") || s.endsWith("sh"))
    return s + "es";
if(s.endsWith("y") && b)
    return x + "ies";
if(s.endsWith("f")) 
    return x + "ves";
if(s.endsWith("fe"))
    return s.substring(0,s.length()-2) + "ves";
if(s.endsWith("o") && b)
    return s + "es";

return s += "s";
}

6
您不能使用摘要。
Okx
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.