Nguyên tắc chung cho viết hoa tiêu đề


30

Theo trang web này, một quy tắc chung được khuyến nghị bởi Hướng dẫn về Phong cách Văn phòng In ấn của Chính phủ Hoa Kỳ

Viết hoa tất cả các từ trong tiêu đề của các ấn phẩm và tài liệu, ngoại trừ a, an, tại, bởi, cho, trong, trên, trên, lên, và, như, nhưng, hoặc, và cũng không.

Điều này có thể không đúng vì tôi không thể tìm thấy đề xuất như vậy trong Sổ tay Phong cách , nhưng dù sao chúng ta hãy sử dụng quy tắc này.


Các thách thức

Đưa ra một chuỗi đầu vào bao gồm các từ viết thường được phân cách bằng dấu cách, xuất viết hoa của chuỗi theo các quy tắc sau

  • Từ đầu tiên và cuối cùng được viết hoa.
  • Tất cả các từ khác được viết hoa, ngoại trừ a , an , the , at , by , for , in , of , on , to , up , , as , but , or , and nor .

Chuỗi đầu vào sẽ chứa ít nhất một từ và mỗi từ chứa ít nhất một chữ cái và chỉ các ký tự từ ađến z.

Đây là một thử thách golf mã, vì vậy hãy cố gắng sử dụng càng ít byte càng tốt trong ngôn ngữ bạn chọn. Bạn có thể viết một chương trình đầy đủ hoặc một chức năng để hoàn thành nhiệm vụ.

Tủ thử

"the rule of thumb for title capitalization" -> "The Rule of Thumb for Title Capitalization"
"programming puzzles and code golf" -> "Programming Puzzles and Code Golf"
"the many uses of the letter a" -> "The Many Uses of the Letter A"
"title" -> "Title"
"and and and" -> "And and And"
"a an and as at but by for in nor of on or the to up" -> "A an and as at but by for in nor of on or the to Up"
"on computable numbers with an application to the entscheidungsproblem" -> "On Computable Numbers With an Application to the Entscheidungsproblem"

1
Các từ bắt đầu / kết thúc có nên được viết hoa ngay cả khi chúng nằm trong danh sách loại trừ không? Các ví dụ của bạn nói có, nhưng thông số kỹ thuật chỉ nói các từ viết hoa trừ khi chúng nằm trong danh sách và không có gì về từ đầu tiên / từ cuối cùng. Lưu ý rằng hai khả năng khác nhau rõ rệt, một là bộ lọc đơn giản và thứ hai yêu cầu hành vi đặc biệt trong các trường hợp cạnh (theo nghĩa đen).
CAD97

3
@ CAD97 Các quy tắc viết hoa là hai gạch đầu dòng, không phải là Trích dẫn. Và gạch đầu dòng cho biết "Từ đầu tiên và từ cuối cùng được viết hoa." và từ thứ hai nói "Tất cả các từ khác đều được viết hoa, ngoại trừ ..." có nghĩa là các từ đầu tiên và cuối cùng luôn được viết hoa.
Laikoni

Tôi đã bỏ lỡ điều đó, bằng cách nào đó. Tuy nhiên, cảm ơn đã làm rõ.
CAD97

Tôi không chắc chắn thực sự cần thiết phải xác định rằng mỗi từ có ít nhất một chữ cái. :)
David Conrad

Câu trả lời:


11

Python 2, 118 byte

Nhìn ma, không có regex!

for w in`input()`.split():print[w.title(),w][`w`in"'a'an'and'as'at'the'by'but'for'nor'in'of'on'or'to'up'"].strip("'"),

Đầu vào phải được bọc trong dấu ngoặc kép. Đầu ra có một không gian kéo dài và không có dòng mới (tôi cho rằng điều đó ổn). Xác minh tất cả các trường hợp thử nghiệm trên Ideone .

Giải trình

Hãy lấy đầu vào a or anlàm ví dụ của chúng tôi.

Sử dụng `x`phím tắt của Python 2 cho repr, chúng tôi gói đầu vào trong dấu ngoặc đơn : 'a or an'. Sau đó, chúng tôi phân chia trên khoảng trắng và lặp lại qua các từ.

Trong vòng lặp, chúng tôi lấy repr lại . Đối với các từ đầu tiên và cuối cùng, điều này cho "'a""an'". Đối với những từ khác, nó cho 'or'. Chúng tôi muốn tránh viết hoa nếu chúng phù hợp với mẫu sau và nằm trong danh sách từ ngắn. Vì vậy, chúng ta có thể biểu diễn danh sách từ dưới dạng chuỗi"'a'an'...'up'" và biết rằng reprbất kỳ từ ngắn nào cũng sẽ là một chuỗi con.

`w` in "..."đưa ra một giá trị boolean, mà chúng ta có thể coi là 0hoặc 1cho các mục đích lập chỉ mục vào danh sách [w.title(), w]. Nói tóm lại, chúng tôi đặt tiêu đề cho trường hợp từ nếu nó ở đầu, cuối hoặc không có trong danh sách các từ ngắn. Nếu không, chúng tôi để nó một mình. May mắn thaytitle() vẫn hoạt động như mong đợi với đầu vào như thế nào 'a.

Cuối cùng, chúng tôi loại bỏ bất kỳ trích dẫn nào từ từ và in nó với một khoảng trắng ở cuối.


8

05AB1E , 68 61 byte

Đã lưu 7 byte nhờ Adnan

™ð¡Dg<UvyN__NXQ_“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“#™yå&&il})ðý

Hãy thử trực tuyến!

Giải trình

“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“là một chuỗi từ điển được dịch là a an the at by for in of on to up and as but or nor.

™                          # title case input string
ð¡                         # split on spaces
Dg<U                       # store index of last word in X

vy                         # for each word
  N__                      # is it not first index?
     NXQ_                  # is it not last index
         “...“             # the compressed string 
              #            # split on spaces
               ™           # convert to title case
                yå         # is current word in this list?
                  &&       # and the 3 previous conditions together
                    il     # if all are true, convert to lower case
                      }    # end loop
)ðý                        # wrap stack in list and join by spaces

2
Nó không bao giờ làm tôi ngạc nhiên về những gì bạn quản lý để đạt được với một chuỗi ngắn các nhân vật hoàn toàn không thể nhận ra. Có vẻ như nó hoạt động rồi :) +1
ElPedro

Bah! Tôi rất gần và tôi không thể tìm cách cạo sạch một nhân vật.
mbomb007

@ mbomb007: Tốt hơn nhanh lên trước khi Jelly, MATL hoặc một số ngôn ngữ khác có thể áp dụng các chức năng cho các chỉ số đến và đánh bại điều này :) Tôi dường như cũng nhớ một ngôn ngữ với regex nén, nhưng không thể nhớ nó được gọi là gì. Điều này đủ dài để nó vẫn có thể chơi được.
Emigna

1
Đối với 62 byte :)
Adnan

@Adnan: Tôi đã bắt đầu như vậy nhưng chỉ với các từ 3 char (kết thúc lâu hơn), nhưng tôi cũng không xem xét việc sử dụng các từ 2 char nữa ... athay vì cũng €…tiết kiệm thêm một byte nếu dẫn với nó :) Cảm ơn!
Emigna

7

GNU sed 81 74 73 byte

Bao gồm +1 cho -r

s/\b./\u&/g
:;s/.(And?|A[st]?|The|By|But|[FN]or|In|O[fnr]|To|Up) /\L&/;t

Dòng đầu tiên viết hoa chữ cái đầu tiên của mỗi từ. Thứ hai chuyển tất cả các từ cần thiết trở lại chữ thường.

Hãy thử trực tuyến!


6

Võng mạc, 69 66 byte

Viết hoa chữ cái đầu tiên của mỗi từ, sau đó thay đổi các từ đã chọn thành chữ thường nếu chúng không phải là từ đầu tiên hoặc từ cuối cùng. Có một khoảng trống ở cuối dòng cuối cùng.

T`l`L`\b.
+T`L`l` (And?|A[st]?|The|By|But|[FN]or|In|O[fnr]|To|Up) 

Dùng thử trực tuyến

Điều này cũng hoạt động với một .thay vì không gian đầu tiên.

Có rất nhiều regex có cùng độ dài, nhưng tôi không thể tìm cách cắt nó nữa ...


(Cách tiếp cận này cũng là 69 byte trong Pip, nhưng tôi không thể sử dụng +thủ thuật để rút ngắn nó.)
DLosc

@DLosc Cảm ơn. Idk tại sao tôi đã không nhìn thấy điều đó. Tôi đã gần gũi.
mbomb007

3

JavaScript (ES6), 141 138 135 133 byte

Đã lưu 3 byte nhờ mbomb007

s=>s.replace(/(\w+)( ?)/g,(a,w,n,i)=>i&&n&&/^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$/.exec(w)?a:a[0].toUpperCase()+a.slice(1))

Các trường hợp thử nghiệm


3

Thạch , 58 byte

“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’b26ịØaṣ”z
e€¢¬T;2Ḷ¤
ḲŒtǦK

Dùng thử trực tuyến! hoặc là chạy tất cả các bài kiểm tra

Làm sao?

Một chuỗi được nén với khoảng trắng phân tách các từ sẽ là 47byte, tách nó có giá 1byte, cho 48byte.

Hai chuỗi nén không tách rời của các từ có độ dài 23(với 'a' ở cuối một) tương ứng sẽ là các 40byte cộng với 2để phân tách từng từ và 1nối chúng với nhau, cho các 45byte.

Một số 250 cơ sở như được mô tả dưới đây là 32byte, sau đó 3chuyển đổi sang cơ sở 26, 3để lập chỉ mục vào bảng chữ cái chữ thường và 3để phân chia nó trên ký tự không sử dụng 'z', cho các 41byte.

Vì vậy, việc tìm kiếm các từ không viết hoa:
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’
được hình thành như vậy:

Lấy những từ đó và nối chúng với một dấu phân cách:
s="a an the at by for in of on to up and as but or nor"

Nhãn tiếp theo 'a'1, 'b'như 2với các dấu phân cách như 0:

alpha = ' abcdefghijklmnopqrstuvwxyz'
x = [alpha.index(v) for v in s]
x
[1,0,1,14,0,20,8,5,0,1,20,0,2,25,0,6,15,18,0,9,14,0,15,6,0,15,14,0,20,15,0,21,16,0,1,14,4,0,1,19,0,2,21,20,0,15,18,0,14,15,18]

Chuyển đổi số này thành 26số cơ sở (chữ cái cuối cùng được sử dụng 'y'cộng với một chữ số cho dấu phân cách, mã Python cho điều này là:
n=sum(v*26**i for i,v in enumerate(x[::-1]))

Chuyển đổi số đó thành 250số cơ sở (sử dụng danh sách các chữ số):

b=[]
while n:
    n,d = divmod(n,250)
    b=[d]+b
b
[16,48,220,145,8,32,202,209,162,13,45,142,244,153,9,80,207,75,35,161,52,18,108,103,52,205,24,38,237,118]

Tra cứu các ký tự tại các chỉ mục đó trong bảng mã của thạch:

codepage = '''¡¢£¤¥¦©¬®µ½¿€ÆÇÐÑ×ØŒÞßæçðıȷñ÷øœþ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR TUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¶°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ƁƇƊƑƓƘⱮƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏż«»‘’“”'''
r=''.join(codepage[i-1] for i in b)
r
'Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu'

(lưu ý: vì việc triển khai thực tế là phỏng đoán, nếu b0 chữ số người ta sẽ cần phải thực hiện trước)

Phần còn lại:

ḲŒtǦK - Main link: title string
Ḳ      - split on spaces
    ¦  - apply to indexes
   Ç   -     given by calling the last link (1) as a monad (with the split title string)
 Œt    -     title case (first letter of each (only) word to upper case)
     K - join on spaces

e€¢¬T;2Ḷ¤ - Link 1, find indexes to capitalise: split title string
e€        - is an element of, for €ach
  ¢       - the result of calling the last link (2) as a nilad
   ¬      - logical not
    T     - get the truthy indexes (indexes of words that are not in the list)
     ;    - concatenate with
        ¤ - nilad followed by link(s) as a nilad
      2Ḷ  - range(2) -> [0,1]
                (we always want to capitalise the first index, 1, and the last index, 0)

“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’b26ịØaṣ”z - Link 2, make the word list: no arguments
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’          - the base 250 number
                                b26       - convert to base 26
                                   ị      - index into
                                    Øa    - lowercase alphabet
                                      ṣ   - split on
                                       ”z - literal 'z' (the separator 0 indexes into `z`)

2

PHP, 158 byte

10 byte được lưu bởi @Titus

foreach($w=explode(" ",$argv[1])as$k=>$v)echo" "[!$k],$k&&$k+1<count($w)&&preg_match("#^(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf])$#",$v)?$v:ucfirst($v);

Phiên bản trước PHP, 174 byte

foreach($w=explode(" ",$argv[1])as$k=>$v)$k&&$k+1<count($w)&&in_array($v,[a,an,the,at,by,"for",in,of,on,to,up,"and","as",but,"or",nor])?:$w[$k]=ucfirst($v);echo join(" ",$w);

Echoing trong vòng lặp tiết kiệm 10 byte:foreach(...)echo" "[!$k],(condition)?$v:ucfirst($v);
Tít

2

TI-Basic, 295 + 59 + 148 = 502 byte

Bây giờ bạn có thể tận dụng máy tính của bạn. Tuyệt vời cho trường học :)

Chương trình chính, 295 byte

Về cơ bản, mẹo để ghép các từ sao cho tất cả Akhông trở thành alà kèm theo dấu cách, chẳng hạn như thay thế " A "bằng " a ". Điều này cũng tự động làm cho nó để các từ đầu tiên và cuối cùng được viết hoa, bởi vì chúng không có khoảng trắng ở cả hai bên và do đó sẽ không khớp với bất kỳ từ nào. (Thiên tài, phải không? Và siêu dài vì các chữ cái viết thường là hai byte mỗi ...)

"("+Ans+")→Str1
"@A ~ a@An ~ an@The ~ the@At ~ at@By ~ by@For ~ for@In ~ in@Of ~ of@On ~ on@To ~ to@Up ~ up@And ~ and@As ~ as@But ~ but@Or ~ or@Nor ~ nor@→Str2
For(I,2,length(Ans
If "@"=sub(Str2,I-1,1
Then
" "+Str1+"~"+sub(Str2,I,inString(Str2,"@",I)-I)+" "
prgmQ
Ans→Str1
End
End

Chương trình con ( prgmQ), 59 byte:

Ans→Str9
inString(Ans,"~
sub(Str9,Ans,length(Str9)-Ans+1→Str8
Str9
prgmR
Repeat Str9=Ans+Str8
Ans+Str8→Str9
prgmR
End

Chương trình con ( prgmR), 148 byte:

Ans→Str0
inString(Ans,"~→Z
inString(Str0,"~",Ans+1→Y
inString(sub(Str0,1,Z-1),sub(Str0,Z+1,Ans-Z-1→X
sub(Str0,1,-1+inString(Str0,"~
If X
sub(Str0,1,X-1)+sub(Str0,Y+1,length(Str0)-Y)+sub(Str0,X+length(sub(Str0,Z+1,Y-Z-1)),Z-X-length(sub(Str0,Z+1,Y-Z-1

PS ~đại diện cho mã thông báo 0x81@đại diện cho mã thông báo 0x7F, tìm hiểu thêm tại đây .


2

Java 7, 271 259 258 byte

String c(String x){String a[]=x.split(" "),s=" ",r=w(a[0])+s;for(int i=0,l=a.length-1;i<l;r+=(!s.matches("^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$")|i==l?w(s):s)+" ")s=a[++i];return r;}String w(String w){return(char)(w.charAt(0)-32)+w.substring(1);}

Mã thử nghiệm & mã hóa:

Hãy thử nó ở đây.

class M{
  static String c(String x){
    String a[] = x.split(" "),
           s = " ",
           r = w(a[0]) + s;
    for(int i = 0, l = a.length-1; i < l; r += (!s.matches("^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$") | i == l
                                                 ? w(s)
                                                 : s)   + " "){
      s = a[++i];
    }
    return r;
  }

  static String w(String w) {
    return (char)(w.charAt(0) - 32) + w.substring(1);
  }

  public static void main(String[] a){
    System.out.println(c("the rule of thumb for title capitalization"));
    System.out.println(c("programming puzzles and code golf"));
    System.out.println(c("the many uses of the letter a"));
    System.out.println(c("title"));
    System.out.println(c("and and and"));
    System.out.println(c("a an and as at but by for in nor of on or the to up"));
    System.out.println(c("on computable numbers with an application to the entscheidungsproblem"));
  }
}

Đầu ra:

The Rule of Thumb for Title Capitalization 
Programming Puzzles and Code Golf 
The Many Uses of the Letter A 
Title 
And and And 
A an and as at but by for in nor of on or the to Up 
On Computable Numbers With an Application to the Entscheidungsproblem 

1

Groovy, 131 129

Hai byte được lưu nhờ vào tính toán carusocomputing

{it.split()*.with{a->a in "a an the at by for in of on to up and as but or nor".split()?a:a.capitalize()}.join(" ").capitalize()}

Thật tuyệt, tôi đã ở mức 137; bạn thắng. Loại bỏ nó i->và sử dụng itđể lưu 2 byte. {it.split()*.with{a->a in "a an the at by for in of on to up and as but or nor".split()?a:a.capitalize()}.join(" ").capitalize()}
Bạch tuộc ma thuật Urn

1
Tôi không biết Groovy nhưng điều này có thực sự viết hoa từ đầu tiên và cuối cùng không?
Emigna

@Emigna bìa viết hoa cuối cùng bắt đầu bằng một trong những từ.
Bạch tuộc ma thuật Urn

@Emigna không thực sự, tôi đã bỏ lỡ yêu cầu đó (từ cuối cùng cần phải được viết hoa). Tôi sẽ cần phải điều chỉnh anwser của tôi.
Krzysztof Atłasik

Hai cách sử dụng .capitalize()chiếm rất nhiều byte. Có một cách ngắn bạn có thể làm bí danh .capitalize()?
Cyoce

1

C #, 305 byte

Vẫn còn nhiều chỗ để cải thiện nhưng ở đây bạn đi:

s=>{;var b=s.Split(' ');b[0]=((char)(b[0][0]-32))+b[0].Substring(1);int i=0,n=b.Length;for(;++i<n;)if(!"a,an,the,at,by,for,in,of,on,to,up,and,as,but,or,nor".Split(',').Contains(b[i]))b[i]=((char)(b[i][0]-32))+b[i].Substring(1);b[n-1]=((char)(b[n-1][0]-32))+b[n-1].Substring(1);return string.Join(" ",b);};

1

Ruby, 123 117 111 102 byte

->s{s.gsub(/ .|^./,&:upcase).gsub(/ (A[nts]?|The|By|In|To|Up|And|But|[NF]or|O[rnf])(?= )/,&:downcase)}

Xin lỗi cho tất cả các chỉnh sửa - đây phải là lần cuối cùng.


1

Python, 177 byte

Cung cấp ở định dạng chức năng cho mục đích tiết kiệm byte. Đây không phải là một câu trả lời đặc biệt cạnh tranh, nhưng nó không phải là một câu trả lời repr()hay regexmánh khóe. Nó cũng là thuyết bất khả tri; nó hoạt động với Python 2 hoặc 3.

Mặc dù nó có lẽ là một giải pháp rất theo quy tắc.

def t(s):
 w="a an the the at by for in of on to up and as but or nor".split()
 l=[(s.title(),s)[s in w]for s in s.split()]
 for x in(0,-1):l[x]=l[x].title()
 return' '.join(l)

1

PHP, 109 142 byte

<?=preg_replace_callback("# (A[snt]?|And|[FN]or|Up|By|But|The|To|In|O[rnf])(?= )#",function($m){return strtolower($m[0]);},ucwords($argv[1]));

Một sự hợp nhất của user59178mbomb007 câu trả lời .

viết hoa chữ cái đầu tiên của mỗi từ, sau đó viết thường tất cả các từ trong danh sách được bao quanh bởi khoảng trắng.
Thật không may, cuộc gọi lại phải hoạt động trên bộ hoàn chỉnh; cái này có giá 29 byte.


nó hoạt động không dành choa an and as at but by for in nor of on or the to up
Jörg Hülsermann

1

Vợt 353 byte

(define(cap i)(set! i(string-append i))(define c(string-ref i 0))(string-set! i 0(if(char-upper-case? c)c(integer->char(-(char->integer c)32))))i)
(let*((ex(list"a""an""the""at""by""for""in""of""on""to""up""and""as""but""or""and""nor"))(sl(string-split s)))
(string-join(for/list((i sl)(n(in-naturals)))(cond[(= n 0)(cap i)][(member i ex)i][(cap i)]))))

Ung dung:

(define (f s)

  (define (cap i)                 ; sub-fn to capitalize first letter of a word
    (set! i (string-append i))
    (define c (string-ref i 0))
    (string-set! i 0
                 (if (char-upper-case? c)
                     c
                     (integer->char (-(char->integer c)32))))
    i)

  (let* ((ex (list "a""an""the""at""by""for""in""of""on""to""up""and""as""but""or""and""nor"))
         (sl (string-split s)))
    (string-join
     (for/list
         ((i sl)
          (n (in-naturals)))
       (cond
         [(= n 0) (cap i)]
         [(member i ex) i]
         [(cap i)]
         )))))

Kiểm tra:

(f "the rule of thumb for title capitalization")

Đầu ra:

"The Rule of Thumb for Title Capitalization"

1

Java 7, 431 317 311 byte

Cảm ơn @KevinCruijssen cho 114 byte.
Cảm ơn @RosLup vì đã lưu 6 byte.

String c(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","but,"by","for","in","of","on","to","‌​up","as","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=(z>0?i<1|i>l.length-2?x:c:x)+" ";i++;}return v;}

vô dụng

câu trả lời đầu tiên trên 250 byte

 static String c(String s) {
      String v = "", x, l[] = s.split(" "),
b[]={"a","an","the","at","by","for","in","of","on","to",
                                         "‌​up","and","as","or","nor","but"};
    int i , f , z = i = f = 0;
    for (String c : l) {

   for (f = 0; f < b.length; z = c.equals( b[f++] ) | z > 0 ? 1 : 0);
        x = (char)(c.charAt(0) - 32) + c.substring(1);

        v += (z > 0 ? i < 1 | i > l.length - 2 ? x : c : x) + " ";
        i++;
   }
    return v;
    }

1
Đó là quá nhiều để tóm tắt trong một nhận xét, nhưng bạn có thể đánh giá nó như thế này: String f(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","by","for","in","of","on","to","up","and","as","but","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=z>0?i<1|i++==l.length-1?x:c:x)+" ";}return v;}( 314 byte ) Tôi khuyên bạn nên xem những gì tôi đã thay đổi như lời khuyên cho lần sau. :) PS: Tôi đã đăng một câu trả lời với một cách tiếp cận khác ( 259 byte ).
Kevin Cruijssen

1
Đặc biệt là những thứ c.substring(0,1).toUpperCase()+c.substring(1,c.length())+" "mà bạn đã làm hai lần sẽ khiến bạn nghĩ về việc sử dụng lại nó bằng cách nào đó. Và kết hợp các khởi tạo như bạn đã làm đúng với int, nhưng vì một số lý do không phải với String. Ngoài ra, không cần thêm booleankhi bạn có thể lưu trữ ở mức int0 hoặc 1 và sau đó kiểm tra nó >0. Và tôi sẽ cố gắng tránh dấu ngoặc và breakcàng nhiều càng tốt; thường có một mẹo để loại bỏ chúng, như for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);tôi đã chỉ ra. :)
Kevin Cruijssen

1
Rất nhiều điều để học hỏi và cảm ơn vì luôn luôn hữu ích (Nederland sống lâu;)
Numberjack

1
Ồ, tôi đã tạo ra một lỗi sao chép-dán .. Nó sẽ là thế này String c(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","by","for","in","of","on","to","up","and","as","but","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=(z>0?i<1|i++>l.length-2?x:c:x)+" ";}return v;}và không có vấn đề gì. :) Tôi cũng đã học được rất nhiều khi tôi mới chơi golf. Tôi chỉ lập một danh sách với mỗi mẹo codegolf chung mà tôi học và tìm kiếm / cập nhật nó đôi khi. Nhưng mã của tôi vẫn bị người khác đánh golf rất nhiều.
Kevin Cruijssen

1
Trong chuỗi b [] có 2 'và' có ổn không?
RosLuP

1

PHP, 117 118 112 byte

<?=strtr(ucwords(preg_replace("# (?=(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) )#","!",$argv[1])),'!',' ');

Sử dụng hành vi của ucwords() và thoát khỏi các từ có liên quan được bao quanh bởi khoảng trắng sau đó xóa các ký tự thoát.

Tôi đã sao chép (a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) câu trả lời của Jörg Hülsermann nhưng vì cách tiếp cận hoàn toàn khác nên tôi đăng nó dưới dạng một câu trả lời riêng.

chỉnh sửa: lỗi được Titus chú ý, sửa nó tốn 1 byte. Ngoài ra: 6 byte được lưu nhờ nhận xét hữu ích của anh ấy về strtr


Lưu 6 byte với strtrthay vì str_replace. Hoặc thêm vào các từ có <>và thả the str_replacevà sử dụng đầu ra HTML.
Tít

Trong một số trường hợp, bạn có thể sử dụng preg_filterthay vì preg_replace. Tôi chưa thử nó với giải pháp của bạn
Jörg Hülsermann

Regex sẽ không hoạt động cho hai từ trong danh sách liên tiếp; kiểm tra nice try for a start. Thay thế một trong các khoảng trắng bằng một xác nhận sẽ giải quyết được điều đó (+4 byte).
Tít

Thật không may preg_filtersẽ thất bại trong titletrường hợp thử nghiệm, không trả lại gì.
dùng59178

1

Nguyên chất bash - 253

(không có chương trình bên ngoài nào được gọi) - cần bash v4

declare -A b;for x in A An The At By For In Of On To Up And As But Or Nor;do b[$x]=1;done
while read -a w;do
n=${#w[@]};o[0]=${w[0]^}
for((i=1;i<n-1;i++)){
g=${w[$i]^};((${b[$g]}))&&o+=(${g,,})||o+=($g);}
((n>1))&&o[$n]=${w[-1]^}
echo ${o[@]};o=()
done

xem bình thường với ý kiến

#create the "blacklist"
declare -A b
for w in A An The At By For In Of On To Up And As But Or Nor
do
    b[$x]=1
done

# logic:
# read each line (split by words) into array
# and each word is assigned capitalized to the new output array
# but the blacklisted ones

#read each line to array w (split on spaces)
while read -a w
do
    n=${#w[@]}         # get the number of words
    o[0]=${w[0]^}          # copy the capitalized word1
    for((i=1 ; i<n-1 ; i++)) { # loop over 2 up to last -1 words

        g=${w[$i]^}    # for the given word
        # check if it is in the blacklisted ones
        # if yes - convert to lowercase, if not leave as it is
        # and append to the output array
        (( ${b[$g]} )) && o+=(${g,,}) || o+=($g)
    }
    # capitalize the last word if here is more words
    (( n>1 )) && o[$n]=${w[-1]^}
    # make a line from the words
    echo ${o[@]}
    o=() #cleanup
done

đầu ra

Title
And and And
The Rule of Thumb for Title Capitalization
Programming Puzzles and Code Golf
The Many Uses of the Letter A
A an and as at but by for in nor of on or the to Up
On Computable Numbers With an Application to the Entscheidungsproblem

1

Japt , 71 byte

£`a  e  by f     up d  ¿t  n`¸aX >0©Y¦0©YĦZl ?X:Xg u +XÅ}S

Hãy thử trực tuyến!

Giải trình:

£`a  e  by f     up d  ¿t  n`¸aX >0©Y¦0©YĦZl ?X:Xg u +XÅ}S
£`...`qS aX >0&&Y!=0&&Y!=UqS l -1?X:Xg u +Xs1}S

£                                            }S   // Split at spaces and map each item X by this function:
 `...`                                            //  Backticks are used to decompress strings
      qS                                          //  Split the decompressed string at spaces.
         aX >J                                    //  If this contains X
              &&Y!=0                              //  and the index is non-zero (it's not the first word)
                    &&Y!=UqS l -1                 //  and the index is not the length of the input -1 (it's not the last word),
                                 ?X               //  return X.
                                   :Xg u +Xs1     //  Else, return X capitalized. (Literally X[0].toUpperCase() + X.slice(1))
                                             }S   // Rejoin with spaces

Một trong những tính năng Japt yêu thích của tôi là nén chuỗi, sử dụng thư viện shoco .

Bạn có thể nén một chuỗi bằng cách gói nó vào Oc"{string}"Oc"a an the at by for in of on to up and as but or nor"

Sau đó giải nén nó bằng backticks hoặc Od"{compressed string}"Od"a e by f up d ¿t n"


Các -Slá cờ đã được bổ sung sau khi thách thức này đã được đăng, vì vậy giải pháp hiện tại của bạn là phi cạnh tranh. Tuy nhiên, tôi nghĩ bạn có thể làm được £...+XÅ}S, điều này sẽ cạnh tranh cho cùng một số byte ( Hãy thử trực tuyến! )
ETHproductions

Theo bạn, làm thế nào để shoco so sánh với nén từ điển của Jelly?
Robert Fraser

@RobertFraser So với Jelly, nó không giỏi nén chuỗi các từ tiếng Anh, nhưng nó rất tốt tại nén chuỗi chữ thường tùy ý, trong đó có đôi khi thuận tiện.
Sản phẩm ETH

1

Tinh khiết bash - 205 192 181 byte

tc(){
while read -a x
do x=(${x[@]^})
for ((i=1;i<${#x[@]}-1;i++))
do
case "${x[i]}" in
A|A[nts]|The|By|[FN]or|In|O[fnr]|To|Up|And|But)x[i]=${x[i],};;
esac
done
echo ${x[@]}
done
}

Giống như câu trả lời của jm66 tc chấp nhận đầu vào tiêu chuẩn.


0

Trên thực tế , 79 byte

' ,ÿsd@p@`;0"A0An0The0At0By0For0In0Of0On0To0Up0And0As0But0Or0Nor"síu'ù*ƒ`Moq' j

Hãy thử trực tuyến!

Giải trình:

' ,ÿsd@p@`;0"longstring"síu'ù*ƒ`Moq' j
' ,ÿs                                   title case input, split on spaces
     d@p@                               pop first and last words to stack
         `;0"longstring"síu'ù*ƒ`M       for every word except the first and last:
          ;0"longstring"s                 duplicate word, split the long string on 0s
                         íu               1-based index of word in list (0 if not found)
                           'ù*            "ù"*(index)
                              ƒ           execute the resulting string as a function (lowercases word if it's in the list)
                                 oq' j  put the first and last word back in the list, join with spaces

0

Hàng loạt, 323 byte

@echo off
set s=
for %%w in (@%*@)do call:w %%w
echo%s%
exit/b
:w
for %%s in (a an the at by for in of on to up and as but or nor)do if %%s==%1 set s=%s% %1&exit/b
set w=%1
set w=%w:@=%
set f=%w:~0,1%
for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)do call set f=%%f:%%c=%%c%%
set s=%s% %f%%w:~1%

Với nhận xét:

@echo off
rem Start with an empty output string
set s=
rem Wrap the parameters in @ signs to identify the first and last words 
for %%w in (@%*@) do call :w %%w
rem Ignore the leading space when printing the result
echo%s%
exit/b
:w
rem Check whether this is a word that we don't change
for %%s in (a an the at by for in of on to up and as but or nor) do if %%s==%1 set s=%s% %1&exit/b
set w=%1
rem Delete any @ signs from the first and last words
set w=%w:@=%
rem Get the first character
set f=%w:~0,1%
rem Case insensitively replace each upper case letter with itself
for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do call set f=%%f:%%c=%%c%%
rem Concatenate with the rest of the word
set s=%s% %f%%w:~1%
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.