[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[数值计算] 函数封装:数字排序的批处理(2007-11-24更新)

===========================   数字排序,使用方法  ==========================
1、要调用本段函数,先将代码从:sort开始及以下所有内容拷贝到批处理中即可。

2、调用方法:   call :sort str 0 0 -81 1583 1698 107 1 258 7 37 1583 6 -2 2 9 8 7 15
           :sort 为标签名,也可以自己定义.
           str 为call 的第一个参数,代表变量名,%str%就是这段函数运行后得到的结果.

3、注意事项: 变量名必须为call的第一个参数。参数中不能含有其它符号。
========================================================================
代码一、
  1. @echo off
  2. :: 将数字排序 原创作者:3742668  原帖出自 cn-dos联盟
  3. :: 整理:小楼一夜听春雨: 2007-11-21
  4. ::   
  5. :: 整理后功能:
  6. ::    可以对cmd范围内所有整数字进行排序,即:可以处理 负数、0、正数。
  7. ::    可以处理重复数字。
  8. :: 特点:  递归调用,速度快,
  9. :: 缺点:
  10. ::    若作为 函数调用,在全局中都不能使用“_+27va8t_/\r#”作为变量名,否则出错。
  11. ::    不能处理0开头的数。_+27va8t_/\r#  此代码特意用了这个生僻的名称为变量名,以避免重复。
  12. ::代码:
  13. set number=1 1698 107 2 258 0 37 1583 6 9 8 7 15 3 1 0 1 -5 -20 -1583 -1583
  14. echo 排序前:
  15. echo %number%
  16. call :sort str %number%
  17. echo.
  18. echo 排序后:
  19. echo %str%
  20. echo\&pause
  21. exit
  22. :sort
  23.    setlocal enabledelayedexpansion
  24.    set var=%2&set "th="
  25.    set var_=%*&set var_= !var_:%1=!
  26.    for %%i in (!var_!) do if !var! leq %%i set var=%%i
  27.    for %%i in (!var_!) do if !var! equ %%i set th=!th! %%i
  28.    set _+27va8t_/\r#=!th:~1! !_+27va8t_/\r#!
  29.    set var_= !var_: %var%= !
  30.    if not "!var_: =!"=="" (
  31.       endlocal&set _+27va8t_/\r#=%_+27va8t_/\r#%
  32.       call :sort _+27va8t_/\r# %var_%)
  33.    call set _+27va8t_/\r#=%%_+27va8t_/\r#%%
  34.    endlocal&set %1=%_+27va8t_/\r#%
  35. goto :eof
复制代码
代码二、
@echo off
::将数字排序 作者:小楼一夜听春雨 2007-11-24
::特点:  利用sort排序。
::   可以对0以上(包括0)的任何整数进行排序。(以下代码可以处理200位以内的整数)
::   速度一般,处理的数字越多,速度越快,可以处理重复的数字
::   利用8个随机数来确定变量名不被重复,以达到处理重复数字的目的。
::缺点:
::     不能处理负数,对0开头的数,结果会虑掉首位的0
::
  1. @echo off
  2. echo 排序前:
  3. set sis=1 20 2 0 5 1 0 38 20 3 1 5 4 3 1 22
  4. echo  %sis%
  5. call :sort str %sis%
  6. echo\&echo 排序后:
  7. echo %str%
  8. pause&exit
  9. :sort
  10. setlocal enabledelayedexpansion
  11. set num=&set str=
  12. for /l %%i in (1 1 200) do set str=0!str!
  13. for %%a in (%*) do (
  14.   set var=!str!%%a&set var=!var:~-200!
  15.   set _!var!_!random!!random!!random!!random!!random!!random!!random!!random!=a
  16. )
  17. for /f "tokens=1 delims=_=" %%a in ('set _^|sort') do (
  18. for /f "tokens=* delims=0" %%i in ("%%a") do (
  19.    if "%%i"=="" (set num=!num! 0) else set num=!num! %%i
  20. ))
  21. endlocal&set %1=%num%
  22. call set %1=%%%1:%1=%%
  23. goto :eof
复制代码
技术问题请到论坛发帖求助!

联盟里的3742斑竹也曾经写过sort函数,他是递归调用,经测试,他的代码执行效率比上段代码要高。
经粗略分析,以上代码虽然避开了call的调用,但是因为采用了大量的for循环(还存在循环嵌套),这种方法就会导致一个问题:数据越多,效率就会拖得越慢,但是递归调用几乎不受数字数目影响,不过以上方法也有它的优点:1、参数数目不受限制;2、支持相等的数字等。

附:根据3742斑竹改的代码:
  1. @echo off
  2. color 1f
  3. if "%1"=="" goto :instruction
  4. setlocal enabledelayedexpansion
  5. for %%i in (%1 %2 %3 %4 %5 %6 %7 %8 %9) do (
  6.   if not "%%i"==""  set number=!number! %%i)
  7. call :sort %number%
  8. echo.
  9. echo 以上数字由大到小依次为:
  10. echo.
  11. echo      %str%
  12. pause>nul
  13. :instruction
  14.    cls
  15.    echo.
  16.    echo                          数字排序
  17.    echo.
  18.    echo ============================================================
  19.    echo 说明:
  20.    echo      该程序只能说基本达到要求;没有对数字进行过滤;
  21.    echo 目前只支持最多9个数字的排序!
  22.    echo.
  23.    echo 使用方法如下:[%~nx0] [%%1] [%%2] [%%3] [%%4] ........
  24.    echo =============================================================
  25.    echo.
  26.    cmd /k
  27. :sort
  28.    set var=%1
  29.    set var_=%*
  30.    for %%i in (%var_%) do (
  31.        if !var! leq %%i set var=%%i)
  32.    set str=!str! !var!
  33.    set var_=!var_:%var%=!
  34.    if not "%var_%"=="" call :sort %var_%
复制代码

TOP

对了,还有一个就是想说的,当数值不在 批处理 范围之内的排序的问题啊,也可以封装成一个函数/////

TOP

2楼的代码速度虽快,但有几个缺点
1、最小的数若有2个或2个以上,代码会进入死循环。
2、代码并不受9个参数的影响,可以是N个。
3、以上代码不能作为函数,带入到别的代码中。
技术问题请到论坛发帖求助!

TOP

原帖由 随风 于 2007-11-20 16:46 发表
2楼的代码速度虽快,但有几个缺点
1、最小的数若有2个或2个以上,代码会进入死循环。
2、代码并不受9个参数的影响,可以是N个。
3、以上代码不能作为函数,带入到别的代码中。


前面的两点赞同,后面的一点 保留 意见...

TOP

:: 来一个排序的代码
::    可以对任何200位以内的超大数、负数、进行排序。可以处理重复数字。
::
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. ::  by  小楼一夜听春雨 2007-11-25
  4. for /l %%a in (1 1 200) do set lin=0!lin!
  5. for /f "delims=" %%a in (a.txt) do (
  6.    set str=%%a
  7.    if "!str:~0,1!"=="-" (set fus=a&set str=!str:~1!&set zf=_) else set zf=+
  8.    set str=!lin!!str!
  9.    set !zf!!str:~-200! !random!!random!!random!!random!!random!!random!!random!=a
  10. )
  11. if defined fus call :lis _ /r
  12. call :lis +
  13. pause&exit
  14. :lis
  15. for /f "tokens=1,2 delims=_+= " %%a in ('set %1^|sort %2') do (
  16.    for /f "tokens=* delims=0" %%i in ("%%a") do (
  17.       if "%1"=="_" (set fuhao=-) else set fuhao=
  18.       if "%%i"=="" (echo !fuhao!0) else echo !fuhao!%%i
  19.    )
  20. )
  21. goto :eof
复制代码
技术问题请到论坛发帖求助!

TOP

本帖最后由 Abracadabra 于 2017-6-28 17:25 编辑

可以参考java使用对象封装局部变量来防止数字重复时的变量名问题,而不需要使用random.
接受任意个数参数调用,无论数字还是字符。
如qs g e sdfsd z
qs 2342 6756 1231323 1 2 412
  1. ::以下代码保存为qs.bat
  2. @echo off
  3. setlocal enabledelayedexpansion
  4. setlocal
  5. set k=0
  6. for %%i in (%*) do (
  7. set /a k+=1
  8. set arr.!k!=%%i
  9. )
  10. set arr.length=%k%
  11. call :s arr
  12. for %%i in (%arr.re%) do (
  13. set /p a=%%i <nul
  14. )
  15. echo.
  16. endlocal
  17. exit /b
  18. :s
  19. if !%1.length! lss 2 (
  20. call :return %1
  21. exit /b
  22. )
  23. for /l %%i in (2,1,!%1.length!) do (
  24. if !%1.%%i! leq !%1.1! (
  25. call :push %1.1 !%1.%%i!
  26. ) else (
  27. call :push %1.2 !%1.%%i!
  28. )
  29. )
  30. call :s %1.1
  31. call :s %1.2
  32. set %1.re=!%1.1.re! !%1.1! !%1.2.re!
  33. exit /b
  34. :push
  35. set /a %1.length+=1
  36. set %1.!%1.length!=%2
  37. exit /b
  38. :return
  39. if !%1.length!==0 set "%1.re="
  40. for /l %%i in (1,1,!%1.length!) do (
  41. set %1.re=!%1.re! !%1.%%i!
  42. )
  43. exit /b
复制代码

TOP

返回列表