找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 73894|回复: 41

批处理编程挑战题“物以类聚”-将字母按大小写归并

[复制链接]
发表于 2017-4-11 09:24:52 | 显示全部楼层 |阅读模式
[问题]
给你一个字符串,只由大小写字母构成。比如字符串: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
复制代码
发表于 2017-4-11 10:10:08 | 显示全部楼层
本帖最后由 523066680 于 2017-4-11 15:52 编辑

Perl
    1. my $lower = my $upper = 'bBAathToHOMmEe';
    2. $lower =~s/[A-Z]//g;
    3. $upper =~s/[a-z]//g;
    4. print $lower.$upper;
    复制代码
    如果不用正则,也就是遍历,加点糖
    1. my @s = split('', 'aDbEcFghijkLMN');
    2. my $n = 0;
    3. grep { print $_ if ( $_ ~~ ['a'..'z'] ) } @s;
    4. grep { print $_ if ( $_ ~~ ['A'..'Z'] ) } @s;
    复制代码


python也学了点毛皮
    1. u = ''
    2. l = ''

    3. for c in 'bBAathToHOMmEe':
    4.     if c in "abcdefghijklmnopqrstuvwxyz":
    5.         l+=c
    6.     else:
    7.         u+=c

    8. print(l+u)
    复制代码
发表于 2017-4-11 12:13:09 | 显示全部楼层
本帖最后由 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
复制代码

评分

参与人数 2技术 +2 收起 理由
老刘1号 + 1 unicode还能这么用,流弊了
happy886rr + 1 666

查看全部评分

 楼主| 发表于 2017-4-11 12:24:13 | 显示全部楼层
回复 2# 523066680
能来个批处理版吗,我想看看你怎么处理大小写。
发表于 2017-4-11 12:25:20 | 显示全部楼层
本帖最后由 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技术 +1 收起 理由
happy886rr + 1 delims很好

查看全部评分

发表于 2017-4-11 12:41:28 | 显示全部楼层
存批
……话说用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
复制代码
 楼主| 发表于 2017-4-11 13:58:35 | 显示全部楼层
回复 6# 老刘1号
用纯批试试
 楼主| 发表于 2017-4-11 14:01:34 | 显示全部楼层
回复 3# pcl_test
拼的好精致
发表于 2017-4-11 14:58:04 | 显示全部楼层
本帖最后由 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
复制代码

评分

参与人数 1技术 +1 收起 理由
happy886rr + 1 不错

查看全部评分

 楼主| 发表于 2017-4-11 15:37:13 | 显示全部楼层
回复 9# 523066680
批处理的坑太多。
发表于 2017-4-11 16:42:07 | 显示全部楼层
回复 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
复制代码

评分

参与人数 1PB +6 技术 +1 收起 理由
523066680 + 6 + 1 这细节掌控,惊人

查看全部评分

发表于 2017-4-11 18:30:20 | 显示全部楼层
本帖最后由 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
复制代码
发表于 2017-4-11 18:40:14 | 显示全部楼层
python正则查找两次。
  1. In [89]: bat = "bBAathToHOMmEe"

  2. In [90]: ''.join(re.findall("[a-z]",bat) + re.findall("[A-Z]",bat))
  3. Out[90]: 'bathomeBATHOME'
复制代码

评分

参与人数 1技术 +1 收起 理由
523066680 + 1 IPython

查看全部评分

发表于 2017-4-11 18:45:25 | 显示全部楼层
能不能做到一行正则处理这个问题啊?
我没有什么想法
发表于 2017-4-11 18:45:31 | 显示全部楼层
回复 13# codegay


    前辈,请帮忙指点下我写的代码(13楼),为什么会耗费将近2秒。该怎么改才对呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 22:23 , Processed in 0.026131 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表