中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 关于去最大值去最小值,中间值求平均数的脚本
作者:
标题: 关于去最大值去最小值,中间值求平均数的脚本 上一主题 | 下一主题
maya0su
中级用户




积分 241
发帖 131
注册 2005-9-28
状态 离线
『楼 主』:  关于去最大值去最小值,中间值求平均数的脚本

如题:
比如有一组数值,是否可以用批处理或者VBS脚本,去除其中的最大最小值,然后其余的数值求平均值?



房东说:这娃是个好孩子!
2006-5-24 13:26
查看资料  发送邮件  发短消息 网志  OICQ (55115315)  编辑帖子  回复  引用回复
3742668
荣誉版主





积分 2013
发帖 718
注册 2006-2-18
状态 离线
『第 2 楼』:  

当然可以,如果用JS的话,它带有一个排序函数:sort,用来解决是很简单的,如果用VBS,也有多种方法,最理想的莫过于利用创建断开的数据集对象来操作,可以像操作数据库一样来编辑那些数据,还能保存为各种格式的文件,不过,在中国DOS联盟,我还是给你个命令行下的批处理版吧:
@echo off
set Count=10                       rem 参加计算的数的个数
call :GetNum %Count%          rem 产生随机数
echo 要处理的数据为:%Num%
call :EditNum %Num%
pause
exit

:EditNum
    set /a intMax=1,intMin=2147483647      rem 批处理最大只能处理32位数据
    setlocal enabledelayedexpansion
    for %%i in (%*) do (if %%i GEQ !intMax! set /a intMax=%%i) & (if %%i LEQ !intMin! set /a intMin=%%i)
    for %%j in (%*) do set /a intCount=!intCount! + 1
    echo 有%intCount%个数,其中最大和最小分别为%intMax%,%intMin%
    set total=%Num: =+%
    set /a total=%total%
    set /a total=(%total% - %intMax% - %intMin%) / (%intCount% - 2)
    echo 总数为:%total%
goto end

:GetNum
    if "%Flag%" == "%1" goto end
    set Num=%Num% %Random%
    set /a Flag = %Flag% + 1
goto GetNum

:end
    endlocal
    set Flag=
    set intMax=
    set intMin=
    set intCount=
    set total=


2006-5-25 21:28
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 3 楼』:  

Re 3742668:

      很不错的方案。

      只是似乎intMax的初值似应取-2147483648,或者intMax和intMin都取%1初值也是可以的。

      另外,:EditNum使用了全局变量%Num%,虽然这是一个很巧妙的技巧,但它不符合局部模块不应访问全局变量的习惯,通用性被降低了,通常我们是在判断最小值和最大值的循环中求得变量和的,同时可以进行一些溢出错误处理。



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-5-25 22:57
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
3742668
荣誉版主





积分 2013
发帖 718
注册 2006-2-18
状态 离线
『第 4 楼』:  

对于intMax的初值开始是考虑过,不过考虑到%random%只能产生1-32767之间的数,所以就选择的是1,至于intMin用2147483647是因为觉得32767的范围似乎太小了一点,再说正整数的比较是比较常见的。
    至于访问%Num%全局变量的问题,如果是用VBS或者其他的话,可能不会出现这种情况,只不过实在懒得去多写一个for来从%*获得算式,因为我认为在批处理中并不存在什么局部变量,统统都是全局变量。

2006-5-25 23:14
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 5 楼』:  

Re 3742668:

      你的代码不应该只能适应你的测试数据,我们无法假定测试数据必然是正整数,所以初值的修改还是必要的。

      2147483647是个与环境相关的数,我们在设计算法时应避免使用,否则如果在64位的系统中可能会出现问题。

      批处理中是存在局部变量的,至少在CMD中,我们可以使用setlocal来限定变量的作用域和生存周期。

      如果将你的:EditNum移植到其他程序中或者直接调用它,则很可能出现问题。

      求和和求个数可以在判断最小值和最大值的for循环一体实现,并不很麻烦。

[ Last edited by willsort on 2006-5-25 at 23:27 ]



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-5-25 23:24
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
maya0su
中级用户




积分 241
发帖 131
注册 2005-9-28
状态 离线
『第 6 楼』:  

我的意思是,能不能打开后,程序等待输入数字,这些数字可能是N个,然后去大去小,最后的求平均值!



房东说:这娃是个好孩子!
2006-6-2 22:54
查看资料  发送邮件  发短消息 网志  OICQ (55115315)  编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 7 楼』:  

Re maya0su:

      有了 3742668 兄的代码在前,编写等待输入求平均数的代码应该不是很难,根据你的要求作了相应的修改。
:: Average.cmd - Eval average of a batch of numbers
:: Will Sort - 2006-06-03 - CMD@WinXP
@echo off
call :GetNum
echo 要处理的数据为:%return%
call :Average %return%
echo 去除最大值和最小值的平均数为 %return%
goto :eof

:GetNum
if "%_n%"=="" setlocal
set _n=-
set /p _n=请输入一个整数(直接回车结束输入):
if "%_n%"=="-" endlocal&set return=%return%&goto :eof
set /a _i=_n
if "%_i%" NEQ "%_n%" (echo 无效的输入数据:%_n%
) else set return=%return% %_i%
goto GetNum

:Average
setlocal EnableDelayedExpansion
if "%3"=="" set return=N/A&goto :eof
set /a iMax=%1,iMin=%1
for %%i in (%*) do (   
    if %%i GTR !iMax! set /a iMax=%%i
    if %%i LSS !iMin! set /a iMin=%%i
    set /a iTotal+=%%i
    set /a iCount+=1
)
set /a return=(iTotal-iMax-iMin) / (iCount-2)
endlocal&set return=%return%&goto :eof




※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-6-3 19:33
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
maya0su
中级用户




积分 241
发帖 131
注册 2005-9-28
状态 离线
『第 8 楼』:  

又有一个新的问题出现了
我想利用另一个批处理调用此程序,从而实现循环
@echo off
:loop
cls
call itbat.bat


set /p start=是否继续?(是Y 否N)
if "%start%"=="y" goto :loop
if "%start%"=="n" goto :end

:end
exit

在实现循环的过程出现了一个现象就是
上次计算后的结果,也就是那个平均值会出现下一次的输入数中
同时也参与下一次的运算!
请问有办法解决吗?

[ Last edited by maya0su on 2006-7-24 at 14:11 ]



房东说:这娃是个好孩子!
2006-7-24 14:09
查看资料  发送邮件  发短消息 网志  OICQ (55115315)  编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 9 楼』:  

  问题出在call :Average %return%这一句。如果在循环调用的时候能清空%return%的值就好办了。



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-7-24 17:25
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 10 楼』:  

直接在“call itbat.bat”后加入“set return=”不就行了么

2006-7-24 18:30
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 11 楼』:  

  呵呵,楼上的,我也曾有过这样的冲动,可是,你试验过了吗?发言要慎重哦。



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-7-24 22:09
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 12 楼』:  



  Quote:
Originally posted by namejm at 2006-7-24 22:09:
  呵呵,楼上的,我也曾有过这样的冲动,可是,你试验过了吗?发言要慎重哦。

改一下willsort版主的:

  Quote:
:: Average.cmd - Eval average of a batch of numbers
:: Will Sort - 2006-06-03 - CMD@WinXP
@echo off
set return=
call :GetNum
echo 要处理的数据为:%return%
call :Average %return%
echo 去除最大值和最小值的平均数为 %return%
goto :eof

:GetNum
if "%_n%"=="" setlocal
set _n=-
set /p _n=请输入一个整数(直接回车结束输入):
if "%_n%"=="-" endlocal&set return=%return%&goto :eof
set /a _i=_n
if "%_i%" NEQ "%_n%" (echo 无效的输入数据:%_n%
) else set return=%return% %_i%
goto GetNum

:Average
setlocal EnableDelayedExpansion
if "%3"=="" set return=N/A&goto :eof
set /a iMax=%1,iMin=%1
for %%i in (%*) do (   
    if %%i GTR !iMax! set /a iMax=%%i
    if %%i LSS !iMin! set /a iMin=%%i
    set /a iTotal+=%%i
    set /a iCount+=1
)
set /a return=(iTotal-iMax-iMin) / (iCount-2)
endlocal&set return=%return%&goto :eof
set return=

OK

或者maya0su的:

  Quote:
@echo off
:loop
cls
set return=
call itbat.bat
set return=


set /p start=是否继续?(是Y 否N)
if "%start%"=="y" goto :loop
if "%start%"=="n" goto :end

:end
exit

也OK

[ Last edited by zxcv on 2006-7-25 at 00:41 ]

2006-7-25 00:39
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 13 楼』:  

  原来是要加两处,zxcv的代码不错。看来自己得对 call 标号 参数 的格式多加揣摩才是。



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-7-25 12:50
查看资料  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: