中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [求助]数值排序(难并已解)
English/Chinese Fix Translation
作者:
标题: [求助]数值排序(难并已解) 取消高亮 | 上一主题 | 下一主题
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『楼 主』:  [求助]数值排序(难并已解) 使用 LLM 解释/回答一下

如有一列数值如:56 12 33 48 99 105 5 16
怎么通过批处理输出为:5 12 16 33 48 56 99 105
要求不生成任何临时文件。
----------------------------------------------------------------------------------------------------------
综合所有,本人的通用代码如下:

@echo off&setlocal enabledelayedexpansion
set "str=56 12 33 48 99 105 5 16"
for %%i in (%str%) do call,set var=!var! n%%in
for %%i in (%var%) do set a=%%i&call :lp
echo !var:n=!
pause>nul&goto :eof
:lp
for %%i in (%var%) do (
set b=%%i&set b=!b:~1,-1!&set c=%a:~1,-1%
if !b! lss !c! (
set var=!var:%a% =!
set var=!var:%%i=%%i %a%!
) else (
set var=!var!
)
)

再扩展:

@echo off&setlocal enabledelayedexpansion
set "str=%random% %random% -%random% %random% %random% %random% -%random%"
for %%i in (%str%) do call,set var=!var! n%%in
for %%i in (%var%) do set a=%%i&call :lp
echo !var:n=!
pause>nul&goto :eof
:lp
for %%i in (%var%) do (
set b=%%i&set b=!b:~1,-1!&set c=%a:~1,-1%
if !b! lss !c! (
set var=!var:%a% =!
set var=!var:%%i=%%i %a%!
) else (
set var=!var!
)
)


Last edited by zw19750516 on 2008-5-4 at 09:20 PM ]




批处理之家新域名:www.bathome.net
2008-4-29 22:22
查看资料  发送邮件  发短消息  网志  OICQ (841615149)  编辑帖子  回复  引用回复
qingfushuan
高级用户





积分 502
发帖 327
注册 2006-12-30
状态 离线
『第 2 楼』:  先弄清问题,你写的是一行啊 使用 LLM 解释/回答一下

按小>大的顺序排列吧


2008-4-29 22:40
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 3 楼』:   使用 LLM 解释/回答一下

纯P的话,我一般是先比较长度,如果长度相同再比较大小。


2008-4-29 22:44
查看资料  发短消息  网志   编辑帖子  回复  引用回复
bjsh
银牌会员





积分 2000
发帖 621
注册 2007-1-1
状态 离线
『第 4 楼』:   使用 LLM 解释/回答一下

Linux

$ cat TEST
56
12
33
48
99
105
5
16

$ sort -n <TEST
5
12
16
33
48
56
99
105


2008-4-29 23:21
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
plp626
银牌会员

钻石会员


积分 2278
发帖 1020
注册 2007-11-19
状态 离线
『第 5 楼』:   使用 LLM 解释/回答一下

版主也来凑热闹啦。。。

cmd就是没有shell强悍




山外有山,人外有人;低调做人,努力做事。

进入网盘(各种工具)~~ 空间~~cmd学习
2008-4-29 23:34
查看资料  发短消息  网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 6 楼』:   使用 LLM 解释/回答一下

到目前还没有完善的答案!




批处理之家新域名:www.bathome.net
2008-4-29 23:37
查看资料  发送邮件  发短消息  网志  OICQ (841615149)  编辑帖子  回复  引用回复
terse
银牌会员





积分 2404
发帖 946
注册 2005-9-8
状态 离线
『第 7 楼』:   使用 LLM 解释/回答一下

@echo off&setlocal enabledelayedexpansion
set/p str=输入数字(用空格隔开)
for %%i in (%str%) do (
set str=0000000000%%i
set .!str:~-10! !random!=a
)
for /f "delims=.= " %%i in ('set .') do for /f "tokens=* delims=0" %%i in ("%%i") do if "%%i"=="" (set/p=0 <nul) else set/p=%%i <nul
pause>nul


   此帖被 +38 点积分        点击查看详情   
评分人:【 bat-zw 分数: +15  时间:2008-4-30 00:16
评分人:【 huahua0919 分数: +8  时间:2008-4-30 17:13
评分人:【 PPdos 分数: +4  时间:2008-5-2 06:40
评分人:【 plp626 分数: +11  时间:2008-5-4 22:00




简单!简单!再简单!
2008-4-29 23:56
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
plp626
银牌会员

钻石会员


积分 2278
发帖 1020
注册 2007-11-19
状态 离线
『第 8 楼』:   使用 LLM 解释/回答一下

@echo off&if not %1.==. goto%*
::plp@cn-dos.net|08-4-29
::数字排序。数字范围:(0-10^99)数字保存在dat.txt里,每行一个数字
if not exist dat.txt echo 缺少dat.txt&pause&exit
for /f "delims= " %%a in ('"%0" :sor^|sort')do echo %%a
pause
:sor
setlocal enabledelayedexpansion
for /f %%a in (dat.txt)do (set d=%%a
call:byte&call:space
echo\!sp!!d!
)
exit/b
:byte
for /l %%z in (1 1 100)do if "!d:~%%z,1!"=="" set/a byte=100-%%z&goto:eof
:space
set "sp="
for /l %%z in (1 1 %byte%)do set "sp=!sp! "
goto:eof


数字不是每行一个的,先用这个代码改为每行一个

@echo off
for /f "delims=" %%a in (test.txt)do call:dd %%a
exit
:dd
if %1.=. goto:eof
>>dat.txt echo %1
shift
goto:dd


Last edited by plp626 on 2008-4-30 at 01:41 PM ]




山外有山,人外有人;低调做人,努力做事。

进入网盘(各种工具)~~ 空间~~cmd学习
2008-4-29 23:59
查看资料  发短消息  网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 9 楼』:   使用 LLM 解释/回答一下

不知道 s11ss 兄的排序算法能否满足楼主的需求

''''''''      排序      ''''''''
''''''''s11ss 2007-10-18''''''''

option explicit
'接收输入:
dim s,r,n,i
s=inputbox(vbcrlf&vbcrlf&"以空格隔开:","请输入一组数:","2007 10 18 21 15")
if s="" then wscript.quit
r=split(s," ")
n=ubound(r)
'把字符串转换为Double 子类型:
for i=0 to n
r(i)=cdbl(r(i))
next

'快速排序方法调用:
quicksort r,0,n
'其它排序方法的调用:
'insertsort r
'shellsort r
'bubblesort r
'selectsort r
'heapsort r

'输出结果:
inputbox vbcrlf&vbcrlf&"按升序排列是:","结果",join(r," ")

'各种排序子过程自定义:
'直接插入排序:
sub insertsort(r)
dim i,n,t,j
n=ubound(r)
for i=1 to n'依次插入r(1),r(2),...,r(n)
t=r(i)
j=i-1
do while t<r(j)'查找r(i)的插入位置
r(j+1)=r(j)'将大于r(i)的数后移
j=j-1
if j=-1 then exit do
loop
r(j+1)=t'插入r(i)
next
end sub

'希尔排序:
sub shellsort(r)
'设置增量序列:
dim i,d(),n,t,k,h,j
n=ubound(r)
i=0
redim d(n)
d(i)=fix(n/2)
do until d(i)=1
t=d(i)
i=i+1
d(i)=fix(t/2)
loop
'排序:
k=0
do
h=d(k)'取本趟增量
for i=h to n'r(h)到r(n)插入当前有序区
t=r(i)'保存待插入数
j=i-h
do while t<r(j)'查找正确的插入位置
r(j+h)=r(j)'后移
j=j-h'得到前一数的位置
if j<0 then exit do
loop
r(j+h)=t'插入r(i)
next'本趟排序完成
k=k+1
loop while h<>1
end sub

'冒泡排序:
sub bubblesort(r)
dim i,n,noswap,j,t
n=ubound(r)
for i=0 to n-1'做n趟排序
noswap=True'置未交换标志
for j=n-1 to i step -1'从下往上扫描
if r(j+1)<r(j) then'交换
t=r(j)
r(j)=r(j+1)
r(j+1)=t
noswap=False
end if
next
if noswap then exit for'本趟排序中未发生交换则终止算法
next
end sub

'快速排序:
'划分:
function partition(r,l,h)
dim i,j,t
i=l
j=h
t=r(i)'初始化,t为基准
do
while r(j)>=t and i<j
j=j-1'从右向左扫描,查找第1个小于t的数
wend
if i<j then
r(i)=r(j)'交换r(i)和r(j)
i=i+1
end if
while r(i)<=t and i<j
i=i+1'从左向右扫描,查找第1个大于t的数
wend
if i<j then
r(j)=r(i)'交换r(i)和r(j)
j=j-1
end if
loop while i<>j
r(i)=t'基准t已被最后定位
partition=i
end function
'排序:
sub quicksort(r,s1,t1)
dim i
if s1<t1 then'只有一个数或无数时无须排序
i=partition(r,s1,t1)'对r(s1)到r(t1)做划分
quicksort r,s1,i-1'递归处理左区间
quicksort r,i+1,t1'递归处理右区间
end if
end sub

'直接选择排序:
sub selectsort(r)
dim i,n,k,j,t
n=ubound(r)
for i=0 to n-1'做n趟排序
k=i
for j=i+1 to n'在当前无序区选最小的数r(k)
if r(j)<r(k) then k=j
next
if k<>i then
t=r(i)
r(i)=r(k)
r(k)=t
end if
next
end sub

'堆排序:
'筛选:
sub sift(r,i,m)'以r(i)为根的完全二叉树构成堆
dim t,j
t=r(i)
j=2*i
do while j<=m'j<=m,r(2*i)是r(i)的左孩子
if j<m then
if r(j)<r(j+1) then j=j+1'j指向r(i)的右孩子
end if
if t<r(j) then'孩子节点的数较大
r(i)=r(j)'将r(j)换到双亲位置上
i=j'修改当前被调整节点
j=2*i
else
exit do'调整完毕,退出循环
end if
loop
r(i)=t'最初被调整节点放入正确位置
end sub
'排序:
sub heapsort(r)
dim i,n,t
n=ubound(r)
for i=fix(n/2) to 0 step -1'建初始堆
sift r,i,n
next
for i=n to 0 step -1'进行n+1趟排序
t=r(0)'当前堆顶数和最后一个数交换
r(0)=r(i)
r(i)=t
sift r,0,i-1'r(0)到r(i-1)重建成堆
next
end sub


   此帖被 +15 点积分         点击查看详情   
评分人:【 terse 分数: +15  时间:2008-4-30 00:02


2008-4-30 00:01
查看资料  发短消息  网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 10 楼』:  我只想了个通用性不是很强的: 使用 LLM 解释/回答一下

郁闷啊,个位数不能有重复的:
@echo off&setlocal enabledelayedexpansion
set "str=101 20 14 13 19 18 16 11 5"
for %%i in (%str%) do set a=%%i&call :lp
echo %str%
pause>nul&goto :eof
:lp
for %%i in (%str%) do (
if %%i lss %a% (
set str=!str:%a% =!
set str=!str:%%i=%%i %a%!
)
)




批处理之家新域名:www.bathome.net
2008-4-30 00:04
查看资料  发送邮件  发短消息  网志  OICQ (841615149)  编辑帖子  回复  引用回复
terse
银牌会员





积分 2404
发帖 946
注册 2005-9-8
状态 离线
『第 11 楼』:   使用 LLM 解释/回答一下

我8楼的不合要求吗
set/p str=输入数字(用空格隔开) 改成 set "str=101 20 14 13 19 18 16 11 5"
应该可以的吧




简单!简单!再简单!
2008-4-30 00:11
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 12 楼』:   使用 LLM 解释/回答一下

Originally posted by terse at 2008-4-30 00:11:
我8楼的不合要求吗
set/p str=输入数字(用空格隔开) 改成 set "str=101 20 14 13 19 18 16 11 5"
应该可以的吧

terse八楼的代码太强了,说老实话,我现在还没看明白是怎么一回事,请terse兄弟能帮解释下啊!




批处理之家新域名:www.bathome.net
2008-4-30 00:18
查看资料  发送邮件  发短消息  网志  OICQ (841615149)  编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 13 楼』:   使用 LLM 解释/回答一下

Originally posted by plp626 at 2008-4-30 12:04 AM:
要不用cmd,哪有linux的shell来的方便,快捷,高效?
声明,我不懂linux.

这个不需要懂linux吧,只需要下载GNU的sort.exe然后在批处理中调用即可。


2008-4-30 00:32
查看资料  发短消息  网志   编辑帖子  回复  引用回复
pusofalse
银牌会员




积分 1604
发帖 646
注册 2008-4-13
状态 离线
『第 14 楼』:   使用 LLM 解释/回答一下

Originally posted by terse at 2008-4-29 11:56 PM:
@echo off&setlocal enabledelayedexpansion
set/p str=输入数字(用空格隔开)
for %%i in (%str%) do (
set str=0000000000%%i
set .!str:~-10! !random!=a
)
for /f "delims=.= " ...

果真很强! 刚开始时没明白咋回事。。。
@echo off&setlocal enabledelayedexpansion
set/p str=输入数字(用空格隔开)
for %%i in (%str%) do (
set str=0000000000%%i
set .!str:~-10! !random!=a
)
set .
pause
for /f "delims=.= " %%a in ('set .') do for /f "tokens=* delims=0" %%i in ("%%a") do if "%%i"=="" (set/p=0 <nul) else set/p=%%i <nul
pause>nul
把代码改成这样之后 有点开窍了。。


2008-4-30 00:39
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 15 楼』:   使用 LLM 解释/回答一下

以前用过的,忘了出自哪里了
@echo off
setlocal enabledelayedexpansion
set numbers=%random% %random% %random% %random% %random% %random% %random% %random%
echo 排序前数组为: %numbers%
call :sort %numbers%
echo 排序后数组为: %ret:~1%
pause
goto :eof

:sort
set num=%1
set str=%*
for %%i in (%str%) do if !num! gtr %%i set num=%%i
set ret=%ret% %num%
if not "!str:%num%=!" == "" call :sort !str:%num%=!
goto :eof


   此帖被 +19 点积分        点击查看详情   
评分人:【 plp626 分数: +11  时间:2008-4-30 06:37
评分人:【 huahua0919 分数: +8  时间:2008-4-30 17:18




2008-4-30 01:51
查看资料  发短消息  网志   编辑帖子  回复  引用回复

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


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



论坛跳转: