标题: 批处理编程挑战题“物以类聚”-将字母按大小写归并 [打印本页]
作者: happy886rr 时间: 2017-4-11 09:24 标题: 批处理编程挑战题“物以类聚”-将字母按大小写归并
[问题]
给你一个字符串,只由大小写字母构成。比如字符串:aAbBD,请将所有小写字母移到左端,大写移到右端,形成这种格式:abABD。也就是原字符串中小写a在小写b前面,移动后小写a仍然在小写b的前面,原字符串中大写A在大写B前面,移动后大写A仍然在大写B前面。
要求:不限编程语言(但最好是用批处理去完成才有挑战性),只要能实现这种移动效果就行。你可以拿字符串 bBAathToHOMmEe 做测试,移动后应该输出为 bathomeBATHOME。
[示例]
CMD脚本- @echo off
- set str=bBAathToHOMmEe
-
- 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 %%A=%%A
- )
- setlocal enabledelayedexpansion
- :cut
- set letter=!str:~0,1!
- for %%a in (!letter!) do (
- if "#%%a"=="!#%%a!" (
- set uprstr=!uprstr!%%a
- ) else (
- set lowstr=!lowstr!%%a
- )
- )
- set str=!str:~1!
- if "!str!"=="" (set/p=%lowstr%%uprstr%&exit)
- goto :cut
复制代码
作者: 523066680 时间: 2017-4-11 10:10
本帖最后由 523066680 于 2017-4-11 15:52 编辑
Perl- my $lower = my $upper = 'bBAathToHOMmEe';
- $lower =~s/[A-Z]//g;
- $upper =~s/[a-z]//g;
- print $lower.$upper;
复制代码
如果不用正则,也就是遍历,加点糖- my @s = split('', 'aDbEcFghijkLMN');
- my $n = 0;
- grep { print $_ if ( $_ ~~ ['a'..'z'] ) } @s;
- grep { print $_ if ( $_ ~~ ['A'..'Z'] ) } @s;
复制代码
python也学了点毛皮- u = ''
- l = ''
-
- for c in 'bBAathToHOMmEe':
- if c in "abcdefghijklmnopqrstuvwxyz":
- l+=c
- else:
- u+=c
-
- print(l+u)
复制代码
作者: pcl_test 时间: 2017-4-11 12:13
本帖最后由 pcl_test 于 2017-4-11 13:11 编辑
标题最好标明下明确内容如将字母按大小写归并/分组- @echo off
- powershell ^
- $a='bBAathToHOMmEe'.ToCharArray()^|group {1*$_ -lt 97};^
- -join ($a[0].group+$a[1].group);
- pause
复制代码
- @echo off
- cd /d %tmp%&cmd /u /c echo;bBAathToHOMmEe|more>$
- (for /f %%a in ('findstr [abcdefghijklmnopqrstuvwxyz] $^&findstr [ABCDEFGHIJKLMNOPQRSTUVWXYZ] $') do set /p=%%a)<nul
- pause
复制代码
作者: happy886rr 时间: 2017-4-11 12:24
回复 2# 523066680
能来个批处理版吗,我想看看你怎么处理大小写。
作者: a20150604 时间: 2017-4-11 12:25
本帖最后由 a20150604 于 2017-4-11 12:54 编辑
JS:- str = "bBAathToHOMmEe";
- console.log(str.replace(/[A-Z]/g, '') + str.replace(/[a-z]/g, ''));
复制代码
cmd:- @echo off & setlocal enableDelayedExpansion
- set "str=bBAathToHOMmEe"
- for /L %%i in (0 1 8000) do (
- set "c=!str:~%%i,1!"
- if "!c!" neq "" (
- (for /f "delims=ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%c in ("!c!") do ( set "rl=!rl!!c!" )) || (set "RU=!RU!!c!")
- ) else echo;!rl!!RU! & pause & exit
- )
复制代码
作者: 老刘1号 时间: 2017-4-11 12:41
存批
……话说用VBS写是不是太简单了,以后有时间用汇编重新写一下- '&@(Cls&Cscript -nologo -e:vbscript "%~0"&Pause&Exit)
-
- str="bBAathToHOMmEe"
-
- For Cut = 1 To Len(str)
- If LCase(Mid(str,cut,1)) = Mid(str,cut,1) Then
- NewLstr=NewLstr & Mid(str,cut,1)
- ElseIf UCase(Mid(str,cut,1)) = Mid(str,cut,1) Then
- NewUstr=NewUstr & Mid(str,cut,1)
- End If
- Next
-
- 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的,勉强写一个- @echo off & setlocal enabledelayedexpansion
- set str=BaAbTcHdOeMfEg
- set dupl=%str%
- set "uc="
- set "lc="
- 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 dupl=!dupl:%%a=%%a!
- )
-
- set /a n = 0
- :lp
- if "!str:~%n%, 1!" == "!dupl:~%n%, 1!" (
- set lc=!lc!!str:~%n%, 1!
- ) else (
- set uc=!uc!!str:~%n%, 1!
- )
- set /a n+=1
- if not "!str:~%n%!" == "" goto :lp
-
- echo %lc%%uc%
- pause
复制代码
作者: happy886rr 时间: 2017-4-11 15:37
回复 9# 523066680
批处理的坑太多。
作者: pcl_test 时间: 2017-4-11 16:42
回复 9# 523066680
还有这两种- @echo off&setlocal enabledelayedexpansion
- set s=bBAathToHOMmEe
- for /f "delims=" %%a in ('tree "\*\%s%"^|find ":\*\"') do set "t=%%~nxa"
- rem 或者dir /L
- set n=0
- :lp
- if "!s:~%n%,1!" neq "!t:~%n%,1!" (
- set /p=!s:~%n%,1!<nul
- ) else (
- set r=!r!!s:~%n%,1!
- )
- set /a n+=1
- if "!s:~%n%!" neq "" goto :lp
- echo;%r%
- pause
复制代码
作者: taofan712 时间: 2017-4-11 18:30
本帖最后由 taofan712 于 2017-4-11 21:07 编辑
- @echo off&setlocal enabledelayedexpansion
- set str=bBAathToHOMmEe
- set str_bp=%str%
- 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%%
- for /l %%a in (0 1 14) do (
- for /f "tokens=1,2 delims=#" %%b in ('call echo;%%str:~%%a^,1%%#%%str_bp:~%%a^,1%%') do (
- if not "%%b"=="%%c" (set lc=!lc!%%b) else ( set uc=!uc!%%c)
- ))
- echo;!lc!!uc!
- pause
复制代码
请各位帮忙看下我的代码为什么这么慢,我原以为是用了call set和call echo,改成下面的,还是一样的慢。将近2秒。- @echo off&setlocal enabledelayedexpansion
- set str=bBAathToHOMmEe
- set str_bp=%str%
- 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!
- for /l %%a in (0 1 14) do (
- for /f "tokens=1,2 delims=#" %%b in ('echo;!str:~%%a^,1!#!str_bp:~%%a^,1!') do (
- if not "%%b"=="%%c" (set lc=!lc!%%b) else ( set uc=!uc!%%c)
- ))
- echo;!lc!!uc!
- pause
复制代码
@terse 感谢指点,去掉了中间一个for。- @echo off&setlocal enabledelayedexpansion
- set str=bBAathToHOMmEe
- set str_bp=%str%
- 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!
- for /l %%a in (0 1 14) do (
- if not "!str:~%%a,1!"=="!str_bp:~%%a,1!" (set lc=!lc!!str:~%%a,1!) else ( set uc=!uc!!str_bp:~%%a,1!)
- )
- echo;!lc!!uc!
- pause
复制代码
作者: codegay 时间: 2017-4-11 18:40
python正则查找两次。- In [89]: bat = "bBAathToHOMmEe"
-
- In [90]: ''.join(re.findall("[a-z]",bat) + re.findall("[A-Z]",bat))
- 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- for /l %%a in (0 1 14) do (
- if not "!str:~%%a,1!"=="!str_bp:~%%a,1!" (set lc=!lc!!str:~%%a,1!) else ( set uc=!uc!!str_bp:~%%a,1!)
- )
复制代码
作者: 523066680 时间: 2017-4-11 20:38
本帖最后由 523066680 于 2017-4-11 22:28 编辑
回复 14# codegay
一行正则可以啊,加循环算不算... 只要有小写跟在大写后面,就反转,直到没有这种情况为止- $s = "cDbEFa";
- while ( $s =~s/([A-Z])([a-z])/$2$1/) {}
- 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- ::*****************************************************************************
- @ECHO OFF&MODE CON COLS=100 LINES=30&CLGO "%~F0"&PAUSE>NUL&EXIT /B
- ::*****************************************************************************
-
- /*
- 谢尔宾斯基地毯,酷码;
- */
-
- //入口函数
- TO MAIN
- FOR :A 1 6
- CS
- WAIT 10
- MAKE :PENX=-330 :PENY=220
- TEXT 22 3 8 微软雅黑 Sierpinski-Level:{:A}
- MAKE :PENX=-200 :PENY=-200 :PENC=6 :PENW=10 :PENS=0
- XEBD 380 :A
- WAIT 500
- ]
-
- //谢尔宾斯基主循环
- TO XEBD :L :N
- REPEAT 4
- FD :L
- RT 90
- ]
-
- XK :L
- XEB :L/3 :N-1
-
- //地毯分循环
- TO XEB :L :N
- IF :N=0
- STOP
- ]
-
- XK :L
- XEB :L/3 :N-1
-
- REPEAT 2
- PU
- FD :L
- PD
- XK :L
- XEB :L/3 :N-1
- ]
-
- REPEAT 2
- PU
- RT 90
- FD :L
- LT 90
- PD
- XK :L
- XEB :L/3 :N-1
- ]
-
- REPEAT 2
- PU
- BK :L
- PD
- XK :L
- XEB :L/3 :N-1
- ]
-
- PU
- LT 90
- FD :L
- RT 90
- PD
- XK :L
- XEB :L/3 :N-1
-
- PU
- LT 90
- FD :L
- RT 90
- PD
-
- //细节补枝
- TO XK :L
- PU
- FD :L/3
- RT 90
- FD :L/3
- LT 90
- PD
-
- REPEAT 4
- FD :L/3
- RT 90
- ]
-
- MAKE :PENC=RAND(15)+1
- PU
- BK :L/3
- LT 90
- FD :L/3
- RT 90
- PD
复制代码
- ::*****************************************************************************
- @ECHO OFF&MODE CON COLS=100 LINES=30&CLGO "%~F0"&PAUSE>NUL&EXIT /B
- ::*****************************************************************************
-
- //入口函数
- TO MAIN
- FOR :A 2 12
- CS
- WAIT 10
- MAKE :PENX=-330 :PENY=220
- TEXT 22 3 8 微软雅黑 Sierpinski-Level:{:A}
- MAKE :PENX=0 :PENY=-200 :PENC=6 :PENW=2 :PENS=2
- TREE 100 :A 20 0.75
- WAIT 50
- ]
-
-
-
- TO TREE :L :N :ANGEL :RATE
- IF :N=0
- STOP
- ]
- FD :L
- RT :ANGEL
- TREE :L*:RATE :N-1 :ANGEL :RATE
- LT :ANGEL*2
- TREE :L*:RATE :N-1 :ANGEL :RATE
- RT :ANGEL
- BK :L
- 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
- echo bBAathToHOMmEe | sed -r ":a;s/([a-z])([A-Z])/\2\1/;ta"
复制代码
作者: CrLf 时间: 2017-4-15 02:33
另类解:- @echo off & setlocal enabledelayedexpansion
- %1 echo bBAathToHOMmEe | %1 cmd /c %0 : & exit /b
-
- set "list=#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
-
- for /l %%a in () do (
- choice /c %list:~1% /cs >nul 2>nul
-
- for %%e in (!errorlevel!) do (
- if %%e leq 26 (
- set uppercase=!uppercase!!list:~%%e,1!
- ) else if %%e leq 52 (
- set lowercase=!lowercase!!list:~%%e,1!
- ) else (
- echo !lowercase!!uppercase!
- pause
- exit /b
- )
- )
- )
复制代码
作者: CrLf 时间: 2017-4-15 02:37
回复 3# pcl_test
用 [char[]] 好像也行:[char[]]'bBAathToHOMmEe' ...
作者: CrLf 时间: 2017-4-15 02:54
- @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年之后的填坑:- ;Code By 老刘
- ;编译环境:MASM32 SDK
- ;编译指令:ml /coff 字母按大小写归并.ASM /link /subsystem:console
- ;调用方法:CMD传参,参数1为要处理的字符串。
- ;其他:非大小写字母的字符将被丢弃;传入字符串长度最长为126字符。
-
- Include Masm32rt.INC
- .Data?
- Arg db 128 dup (?)
- UpperCaseString db 128 dup (?)
- LowerCaseString db 128 dup (?)
- NewString db 128 dup (?)
- .Code
- Start:
- Invoke ArgClC,1,Offset Arg
- .If Eax == 1
- Mov Esi,Offset Arg
- Mov Ecx,Offset LowerCaseString
- Mov Edx,Offset UpperCaseString
-
- .While Al != 0 ;分割为两个字符串
- LodSB
- .If Al >= 41h && Al <= 5Ah
- Mov Byte Ptr [Edx],Al
- Inc Edx
- .ElseIf Al >= 61h && Al <= 7Ah
- Mov Byte Ptr [Ecx],Al
- Inc Ecx
- .EndIf
- .EndW
-
- ;合并到同一个字符串中。
- Mov Edi,Offset NewString
-
- ;处理小写字符串
- Sub Ecx,Offset LowerCaseString
- Mov Esi,Offset LowerCaseString
- Rep MovSB
-
- ;处理大写字符串
- Sub Edx,Offset UpperCaseString
- Mov Ecx,Edx
- Mov Esi,Offset UpperCaseString
- Rep MovSB
-
- ;字符串结尾
- Mov Al,0Ah
- StoSB
- Xor EAX,EAX
- StoSB
-
- ;回显字符串
- Invoke StdOut,Offset NewString
- .EndIf
- Invoke ExitProcess,NULL
- End Start
- 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
- @echo off
- set "str=bBAathToHOMmEe"
- echo;%str%>%temp%\$
- sed "s/[A-Z]//g" %temp%\$
- sed "s/[a-z]//g" %temp%\$
- del %temp%\$
复制代码
- @echo off
- set "str=bBAathToHOMmEe"
-
- :lp
- set "ch=%str:~,1%"
- 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 (
- if "%%a"=="%ch%" (set "LowerCASE=%LowerCASE%%%a")
- )
- 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 (
- if "%%a"=="%ch%" (set "UperCASE=%UperCASE%%%a")
- )
- set "str=%str:~1%"
- if "%str%" neq "" goto :lp
- echo;%LowerCASE%%UperCASE%
复制代码
作者: 老刘1号 时间: 2018-9-5 19:28
回复 36# happy886rr
感谢大佬支持,
大佬改行实在是可惜啊……
为啥突然不搞了呢?
作者: Wiki 时间: 2018-9-26 08:33
用纯perl试试- #!perl
- my $test = 'bBAathToHOMmEe';
- print sort { ( $b cmp '^' ) <=> ( $a cmp '^' ) } split '', $test;
复制代码
作者: Wiki 时间: 2018-9-28 10:09
只要能实现这种效果就行。- # include <stdio.h>
- # include <stdlib.h>
- # include <string.h>
-
- char* classify (char*);
-
- int main (){
- char *test = "bBAathToHOMmEe";
- char *clas = classify(test);
-
- puts(clas);
-
- }
-
- # define new(T, N) malloc ((N) *sizeof(T))
- char* classify(char *test){
- int len = strlen (test);
- char *ret = new(char, len + 1);
- ret[len] = 0;
- int i = 0, j = len - 1;
-
- for (char *a = test, *b = test + j; i <= j; a++, b--) {
- if (*a >= 'a') ret[i++] = *a;
- if (*b < 'a') ret[j--] = *b;
- }
- return ret;
- }
复制代码
作者: 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 |