Board logo

标题: 批处理编程挑战题“物以类聚”-将字母按大小写归并 [打印本页]

作者: happy886rr    时间: 2017-4-11 09:24     标题: 批处理编程挑战题“物以类聚”-将字母按大小写归并

[问题]
给你一个字符串,只由大小写字母构成。比如字符串:aAbBD,请将所有小写字母移到左端,大写移到右端,形成这种格式:abABD。也就是原字符串中小写a在小写b前面,移动后小写a仍然在小写b的前面,原字符串中大写A在大写B前面,移动后大写A仍然在大写B前面。

要求:不限编程语言(但最好是用批处理去完成才有挑战性),只要能实现这种移动效果就行。你可以拿字符串 bBAathToHOMmEe 做测试,移动后应该输出为 bathomeBATHOME。

[示例]
CMD脚本
  1. @echo off
  2. set str=bBAathToHOMmEe
  3. for %%A 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 (
  4. set %%A=%%A
  5. )
  6. setlocal enabledelayedexpansion
  7. :cut
  8. set letter=!str:~0,1!
  9. for %%a in (!letter!) do (
  10. if "#%%a"=="!#%%a!" (
  11. set uprstr=!uprstr!%%a
  12. ) else (
  13. set lowstr=!lowstr!%%a
  14. )
  15. )
  16. set str=!str:~1!
  17. if "!str!"=="" (set/p=%lowstr%%uprstr%&exit)
  18. goto :cut
复制代码

作者: 523066680    时间: 2017-4-11 10:10

本帖最后由 523066680 于 2017-4-11 15:52 编辑

Perl

python也学了点毛皮
作者: pcl_test    时间: 2017-4-11 12:13

本帖最后由 pcl_test 于 2017-4-11 13:11 编辑

标题最好标明下明确内容如将字母按大小写归并/分组
  1. @echo off
  2. powershell ^
  3.     $a='bBAathToHOMmEe'.ToCharArray()^|group {1*$_ -lt 97};^
  4.     -join ($a[0].group+$a[1].group);
  5. pause
复制代码
  1. @echo off
  2. cd /d %tmp%&cmd /u /c echo;bBAathToHOMmEe|more>$
  3. (for /f %%a in ('findstr [abcdefghijklmnopqrstuvwxyz] $^&findstr [ABCDEFGHIJKLMNOPQRSTUVWXYZ] $') do set /p=%%a)<nul
  4. pause
复制代码

作者: happy886rr    时间: 2017-4-11 12:24

回复 2# 523066680
能来个批处理版吗,我想看看你怎么处理大小写。
作者: a20150604    时间: 2017-4-11 12:25

本帖最后由 a20150604 于 2017-4-11 12:54 编辑

JS:
  1. str = "bBAathToHOMmEe";
  2. console.log(str.replace(/[A-Z]/g, '') + str.replace(/[a-z]/g, ''));
复制代码
cmd:
  1. @echo off & setlocal enableDelayedExpansion
  2. set "str=bBAathToHOMmEe"
  3. for /L %%i in (0 1 8000) do (
  4.     set "c=!str:~%%i,1!"
  5.     if "!c!" neq "" (
  6.         (for /f "delims=ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%c in ("!c!") do ( set "rl=!rl!!c!" )) || (set "RU=!RU!!c!")
  7.     ) else echo;!rl!!RU! & pause & exit
  8. )
复制代码

作者: 老刘1号    时间: 2017-4-11 12:41

存批
……话说用VBS写是不是太简单了,以后有时间用汇编重新写一下
  1. '&@(Cls&Cscript -nologo -e:vbscript "%~0"&Pause&Exit)
  2. str="bBAathToHOMmEe"
  3. For Cut = 1 To Len(str)
  4. If LCase(Mid(str,cut,1)) = Mid(str,cut,1) Then
  5. NewLstr=NewLstr & Mid(str,cut,1)
  6. ElseIf UCase(Mid(str,cut,1)) = Mid(str,cut,1) Then
  7. NewUstr=NewUstr & Mid(str,cut,1)
  8. End If
  9. Next
  10. WScript.Echo str & " -- > " & NewLstr & NewUstr
复制代码

作者: happy886rr    时间: 2017-4-11 13:58

回复 6# 老刘1号
用纯批试试
作者: happy886rr    时间: 2017-4-11 14:01

回复 3# pcl_test
拼的好精致
作者: 523066680    时间: 2017-4-11 14:58

本帖最后由 523066680 于 2017-4-11 15:22 编辑

回复 4# happy886rr

    我想到了 find, 速度慢;我想到了 if , 大小写区分,虽然 'A' gtr 'a' 成立, 但是 'A' gtr 'z' 居然不成立;
这个时候我想到了把 a b c, A B C 分组放到变量名里,很可惜,变量名不区分大小写。对批处理感到无助

不过,OK的,勉强写一个
  1. @echo off & setlocal enabledelayedexpansion
  2. set str=BaAbTcHdOeMfEg
  3. set dupl=%str%
  4. set "uc="
  5. set "lc="
  6. for %%a 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 (
  7.     set dupl=!dupl:%%a=%%a!
  8. )
  9. set /a n = 0
  10. :lp
  11.     if "!str:~%n%, 1!" == "!dupl:~%n%, 1!" (
  12.         set lc=!lc!!str:~%n%, 1!
  13.     ) else (
  14.         set uc=!uc!!str:~%n%, 1!
  15.     )
  16.     set /a n+=1
  17. if not "!str:~%n%!" == "" goto :lp
  18. echo %lc%%uc%
  19. pause
复制代码

作者: happy886rr    时间: 2017-4-11 15:37

回复 9# 523066680
批处理的坑太多。
作者: pcl_test    时间: 2017-4-11 16:42

回复 9# 523066680
还有这两种
  1. @echo off&setlocal enabledelayedexpansion
  2. set s=bBAathToHOMmEe
  3. for /f "delims=" %%a in ('tree "\*\%s%"^|find ":\*\"') do set "t=%%~nxa"
  4. rem 或者dir /L
  5. set n=0
  6. :lp
  7. if "!s:~%n%,1!" neq "!t:~%n%,1!" (
  8.     set /p=!s:~%n%,1!<nul
  9. ) else (
  10.     set r=!r!!s:~%n%,1!
  11. )
  12. set /a n+=1
  13. if "!s:~%n%!" neq "" goto :lp
  14. echo;%r%
  15. pause
复制代码

作者: taofan712    时间: 2017-4-11 18:30

本帖最后由 taofan712 于 2017-4-11 21:07 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. set str=bBAathToHOMmEe
  3. set str_bp=%str%
  4. for %%a 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 str_bp=%%str_bp:%%a=%%a%%
  5. for /l %%a in (0 1 14) do (
  6. for /f "tokens=1,2 delims=#" %%b in ('call echo;%%str:~%%a^,1%%#%%str_bp:~%%a^,1%%') do (
  7. if not "%%b"=="%%c" (set lc=!lc!%%b) else ( set uc=!uc!%%c)
  8. ))
  9. echo;!lc!!uc!
  10. pause
复制代码
请各位帮忙看下我的代码为什么这么慢,我原以为是用了call set和call echo,改成下面的,还是一样的慢。将近2秒。
  1. @echo off&setlocal enabledelayedexpansion
  2. set str=bBAathToHOMmEe
  3. set str_bp=%str%
  4. for %%a 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 set str_bp=!str_bp:%%a=%%a!
  5. for /l %%a in (0 1 14) do (
  6. for /f "tokens=1,2 delims=#" %%b in ('echo;!str:~%%a^,1!#!str_bp:~%%a^,1!') do (
  7. if not "%%b"=="%%c" (set lc=!lc!%%b) else ( set uc=!uc!%%c)
  8. ))
  9. echo;!lc!!uc!
  10. pause
复制代码
@terse 感谢指点,去掉了中间一个for。
  1. @echo off&setlocal enabledelayedexpansion
  2. set str=bBAathToHOMmEe
  3. set str_bp=%str%
  4. for %%a 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 set str_bp=!str_bp:%%a=%%a!
  5. for /l %%a in (0 1 14) do (
  6.     if not "!str:~%%a,1!"=="!str_bp:~%%a,1!" (set lc=!lc!!str:~%%a,1!) else ( set uc=!uc!!str_bp:~%%a,1!)
  7. )
  8. echo;!lc!!uc!
  9. pause
复制代码

作者: codegay    时间: 2017-4-11 18:40

python正则查找两次。
  1. In [89]: bat = "bBAathToHOMmEe"
  2. In [90]: ''.join(re.findall("[a-z]",bat) + re.findall("[A-Z]",bat))
  3. Out[90]: 'bathomeBATHOME'
复制代码

作者: codegay    时间: 2017-4-11 18:45

能不能做到一行正则处理这个问题啊?
我没有什么想法
作者: taofan712    时间: 2017-4-11 18:45

回复 13# codegay


    前辈,请帮忙指点下我写的代码(13楼),为什么会耗费将近2秒。该怎么改才对呢
作者: codegay    时间: 2017-4-11 18:46

回复 15# taofan712


    我不懂批处理。
作者: taofan712    时间: 2017-4-11 19:04

回复 16# codegay


    谢谢,因为经常见到你的id...现在才注意到你主要在python区发帖 ^_^
作者: terse    时间: 2017-4-11 20:19

回复 17# taofan712
去掉一个FOR
  1. for /l %%a in (0 1 14) do (
  2.     if not "!str:~%%a,1!"=="!str_bp:~%%a,1!" (set lc=!lc!!str:~%%a,1!) else ( set uc=!uc!!str_bp:~%%a,1!)
  3. )
复制代码

作者: 523066680    时间: 2017-4-11 20:38

本帖最后由 523066680 于 2017-4-11 22:28 编辑

回复 14# codegay


    一行正则可以啊,加循环算不算... 只要有小写跟在大写后面,就反转,直到没有这种情况为止
  1. $s = "cDbEFa";
  2. while ( $s =~s/([A-Z])([a-z])/$2$1/) {}
  3. print $s
复制代码

作者: happy886rr    时间: 2017-4-14 23:27

回复 19# 523066680
顾森,北京大学中国语言文学系应用语言专业07级本科生,Matrix67博客作者。Matrix67名字来源:“有一次申请邮箱,matrix这个id被人占用了,于是我就开始往后面加数字。”试过123,试过456,直到67才最终定下来。这就是Matrix67的来历,它也成为了顾森在网络这个虚拟世界上的大名。 2006年以文科生身份参加全国信息学奥林匹克竞赛获夏令营银牌,并保送至中文系应用语言专业。现任启明星学校初中奥数教师、果壳网“死理性派”栏目编辑。   大三由于忙于一些事物,休学一年。   个人主页:http://www.matrix67.com/blog/   果壳网主页http://www.guokr.com/i/0376718656/
作者: codegay    时间: 2017-4-14 23:35

回复 20# happy886rr


    他从果壳离职都好几年了。
作者: 老刘    时间: 2017-4-14 23:38

回复 20# happy886rr


    我开始怀疑我为何要注册老刘1号
这个号还不是一样没被占用么……
不明白一年前的心理……
不过可能和那位有些雷同吧,
轻易不换昵称的我《<v<《
作者: happy886rr    时间: 2017-4-14 23:39

本帖最后由 happy886rr 于 2017-4-15 00:14 编辑

回复 19# 523066680
酷语言分形
1.地毯(图片均为外链)

2.树

3.圆

.
.
请使用CLGO解释器3.0版运行。下载地址:http://www.bathome.net/thread-43178-1-1.html
  1. ::*****************************************************************************
  2.   @ECHO OFF&MODE CON COLS=100 LINES=30&CLGO "%~F0"&PAUSE>NUL&EXIT /B
  3. ::*****************************************************************************
  4. /*
  5.   谢尔宾斯基地毯,酷码;
  6. */
  7. //入口函数
  8. TO MAIN
  9. FOR :A 1 6
  10. CS
  11. WAIT 10
  12. MAKE :PENX=-330 :PENY=220
  13. TEXT 22 3 8 微软雅黑 Sierpinski-Level:{:A}
  14. MAKE :PENX=-200 :PENY=-200 :PENC=6 :PENW=10 :PENS=0
  15. XEBD 380 :A
  16. WAIT 500
  17. ]
  18. //谢尔宾斯基主循环
  19. TO XEBD :L :N
  20. REPEAT 4
  21. FD :L
  22. RT 90
  23. ]
  24. XK :L
  25. XEB :L/3 :N-1
  26. //地毯分循环
  27. TO XEB :L :N
  28. IF :N=0
  29. STOP
  30. ]
  31. XK :L
  32. XEB :L/3 :N-1
  33. REPEAT 2
  34. PU
  35. FD :L
  36. PD
  37. XK :L
  38. XEB :L/3 :N-1
  39. ]
  40. REPEAT 2
  41. PU
  42. RT 90
  43. FD :L
  44. LT 90
  45. PD
  46. XK :L
  47. XEB :L/3 :N-1
  48. ]
  49. REPEAT 2
  50. PU
  51. BK :L
  52. PD
  53. XK :L
  54. XEB :L/3 :N-1
  55. ]
  56. PU
  57. LT 90
  58. FD :L
  59. RT 90
  60. PD
  61. XK :L
  62. XEB :L/3 :N-1
  63. PU
  64. LT 90
  65. FD :L
  66. RT 90
  67. PD
  68. //细节补枝
  69. TO XK :L
  70. PU
  71. FD :L/3
  72. RT 90
  73. FD :L/3
  74. LT 90
  75. PD
  76. REPEAT 4
  77. FD :L/3
  78. RT 90
  79. ]
  80. MAKE :PENC=RAND(15)+1
  81. PU
  82. BK :L/3
  83. LT 90
  84. FD :L/3
  85. RT 90
  86. PD
复制代码
  1. ::*****************************************************************************
  2.   @ECHO OFF&MODE CON COLS=100 LINES=30&CLGO "%~F0"&PAUSE>NUL&EXIT /B
  3. ::*****************************************************************************
  4. //入口函数
  5. TO MAIN
  6. FOR :A 2 12
  7. CS
  8. WAIT 10
  9. MAKE :PENX=-330 :PENY=220
  10. TEXT 22 3 8 微软雅黑 Sierpinski-Level:{:A}
  11. MAKE :PENX=0 :PENY=-200 :PENC=6 :PENW=2 :PENS=2
  12. TREE 100 :A 20 0.75
  13. WAIT 50
  14. ]
  15. TO TREE :L :N :ANGEL :RATE
  16. IF :N=0
  17. STOP
  18. ]
  19. FD :L
  20. RT :ANGEL
  21. TREE :L*:RATE :N-1 :ANGEL :RATE
  22. LT :ANGEL*2
  23. TREE :L*:RATE :N-1 :ANGEL :RATE
  24. RT :ANGEL
  25. BK :L
  26. MAKE :PENC=RAND(15)+1
复制代码

作者: happy886rr    时间: 2017-4-14 23:47

回复 21# codegay
哦,我都不知道,不过他文章写得好。
作者: happy886rr    时间: 2017-4-14 23:48

本帖最后由 happy886rr 于 2017-4-14 23:49 编辑

回复 22# 老刘
你这账号太嫩了,还是一号好点。对了,酷语言也能彩色地毯。
作者: 老刘    时间: 2017-4-14 23:50

回复 25# happy886rr


    嘿嘿,这个号就当小号了
作者: 老刘1号    时间: 2017-4-14 23:52

回复 25# happy886rr


    酷语言在绘图上果然不是一般的给力啊
已测试,很震撼
作者: happy886rr    时间: 2017-4-15 00:12

回复 27# 老刘1号
只要代码巧妙,理论上没有画不出的图来,你就当他是控制台上的ppt吧。ICMD, Capis也能干这些,不过没酷语言绘图速度快。
作者: CrLf    时间: 2017-4-15 02:12

  1. echo bBAathToHOMmEe | sed -r ":a;s/([a-z])([A-Z])/\2\1/;ta"
复制代码

作者: CrLf    时间: 2017-4-15 02:33

另类解:
  1. @echo off & setlocal enabledelayedexpansion
  2. %1 echo bBAathToHOMmEe | %1 cmd /c %0 : & exit /b
  3. set "list=#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  4. for /l %%a in () do (
  5.   choice /c %list:~1% /cs >nul 2>nul
  6.   for %%e in (!errorlevel!) do (
  7.     if %%e leq 26 (
  8.       set uppercase=!uppercase!!list:~%%e,1!
  9.     ) else if %%e leq 52 (
  10.       set lowercase=!lowercase!!list:~%%e,1!
  11.     ) else (
  12.       echo !lowercase!!uppercase!
  13.       pause
  14.       exit /b
  15.     )
  16.   )
  17. )
复制代码

作者: CrLf    时间: 2017-4-15 02:37

回复 3# pcl_test


    用 [char[]] 好像也行:[char[]]'bBAathToHOMmEe' ...
作者: CrLf    时间: 2017-4-15 02:54

  1. @for %%a in (a-z A-Z) do @echo aAbBdD | grep -o [%%a] | gawk "ORS=s;1"
复制代码

作者: 523066680    时间: 2017-4-15 10:48

本帖最后由 523066680 于 2017-4-15 10:57 编辑

回复 24# happy886rr


    Matrix67我知道,还买了他的第一版书作为支持。现在他博客上有很多更新文章还未看,忙于工作和重新补习不同语言的语法(糖)。
作者: 老刘1号    时间: 2018-9-1 15:08

回复 6# 一年前挖下的坑
来自1年之后的填坑:
  1. ;Code By 老刘
  2. ;编译环境:MASM32 SDK
  3. ;编译指令:ml /coff 字母按大小写归并.ASM /link /subsystem:console
  4. ;调用方法:CMD传参,参数1为要处理的字符串。
  5. ;其他:非大小写字母的字符将被丢弃;传入字符串长度最长为126字符。
  6. Include Masm32rt.INC
  7. .Data?
  8. Arg db 128 dup (?)
  9. UpperCaseString db 128 dup (?)
  10. LowerCaseString db 128 dup (?)
  11. NewString db 128 dup (?)
  12. .Code
  13. Start:
  14. Invoke ArgClC,1,Offset Arg
  15. .If Eax == 1
  16. Mov Esi,Offset Arg
  17. Mov Ecx,Offset LowerCaseString
  18. Mov Edx,Offset UpperCaseString
  19. .While Al != 0 ;分割为两个字符串
  20. LodSB
  21. .If Al >= 41h && Al <= 5Ah
  22. Mov Byte Ptr [Edx],Al
  23. Inc Edx
  24. .ElseIf Al >= 61h && Al <= 7Ah
  25. Mov Byte Ptr [Ecx],Al
  26. Inc Ecx
  27. .EndIf
  28. .EndW
  29. ;合并到同一个字符串中。
  30. Mov Edi,Offset NewString
  31. ;处理小写字符串
  32. Sub Ecx,Offset LowerCaseString
  33. Mov Esi,Offset LowerCaseString
  34. Rep MovSB
  35. ;处理大写字符串
  36. Sub Edx,Offset UpperCaseString
  37. Mov Ecx,Edx
  38. Mov Esi,Offset UpperCaseString
  39. Rep MovSB
  40. ;字符串结尾
  41. Mov Al,0Ah
  42. StoSB
  43. Xor EAX,EAX
  44. StoSB
  45. ;回显字符串
  46. Invoke StdOut,Offset NewString
  47. .EndIf
  48. Invoke ExitProcess,NULL
  49. End Start
  50. End
复制代码

作者: ai20110304    时间: 2018-9-2 01:31

回复 3# pcl_test


    思维敏捷
作者: happy886rr    时间: 2018-9-3 21:26

本帖最后由 happy886rr 于 2018-9-3 21:29 编辑

回复 34# 老刘1号
技术有长进,我都改行了,不再写任何代码。
作者: yhcfsr    时间: 2018-9-4 00:06

  1. @echo off
  2. set "str=bBAathToHOMmEe"
  3. echo;%str%>%temp%\$
  4. sed "s/[A-Z]//g" %temp%\$
  5. sed "s/[a-z]//g" %temp%\$
  6. del %temp%\$
复制代码
  1. @echo off
  2. set "str=bBAathToHOMmEe"
  3. :lp
  4. set "ch=%str:~,1%"
  5. for %%a in (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,e,s,t,u,v,w,x,y,z) do (
  6. if "%%a"=="%ch%" (set "LowerCASE=%LowerCASE%%%a")
  7. )
  8. for %%a 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 (
  9. if "%%a"=="%ch%" (set "UperCASE=%UperCASE%%%a")
  10. )
  11. set "str=%str:~1%"
  12. if "%str%" neq "" goto :lp
  13. echo;%LowerCASE%%UperCASE%
复制代码

作者: 老刘1号    时间: 2018-9-5 19:28

回复 36# happy886rr


    感谢大佬支持,
大佬改行实在是可惜啊……
为啥突然不搞了呢?
作者: Wiki    时间: 2018-9-26 08:33

用纯perl试试
  1. #!perl
  2. my $test = 'bBAathToHOMmEe';
  3. print sort { ( $b cmp '^' ) <=> ( $a cmp '^' ) } split '', $test;
复制代码

作者: Wiki    时间: 2018-9-28 10:09

只要能实现这种效果就行。
  1. # include <stdio.h>
  2. # include <stdlib.h>
  3. # include <string.h>
  4. char* classify (char*);
  5. int main (){
  6.     char *test = "bBAathToHOMmEe";
  7.     char *clas = classify(test);
  8.     puts(clas);
  9. }
  10. # define new(T, N) malloc ((N) *sizeof(T))
  11. char* classify(char *test){
  12.     int len   = strlen (test);
  13.     char *ret = new(char, len + 1);
  14.     ret[len]  = 0;
  15.     int i = 0, j = len - 1;
  16.     for (char *a = test, *b = test + j; i <= j; a++, b--) {
  17.         if (*a >= 'a') ret[i++] = *a;
  18.         if (*b <  'a') ret[j--] = *b;
  19.     }
  20.     return ret;
  21. }
复制代码

作者: CrLf    时间: 2018-9-28 13:07

回复 36# happy886rr


    啊?改行了?
作者: 523066680    时间: 2018-9-28 13:38

回复 36# happy886rr

    才看到你说改行,好奇现在做什么了?业余也不写代码了吗




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2