Board logo

标题: [转]纯批处理解一次方程 [打印本页]

作者: 路过    时间: 2021-1-1 16:37     标题: [转]纯批处理解一次方程

转自百度bat吧。https://tieba.baidu.com/p/7173843754
v1.1的代码
  1. @echo off
  2. for /f "tokens=*" %%i in ('more +2 "%~s0"^|find "\"') do (echo%%i)
  3. for /f "delims==" %%w in ('set') do (set "%%w=")
  4. ::初始化常量
  5. ::_MAX为最大未知数个数
  6. set/a _MAX=100
  7. setlocal enabledelayedexpansion
  8. set/a num=0,mod=1
  9. set "#=echo;$&pause&goto put"
  10. set .=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
  11. set _=0 1 2 3 4 5 6 7 8 9
  12. set ..+=2
  13. set ..-=2
  14. set ..`=1
  15. set/a .10=1,.20=1,.1`=1,.2`=1
  16. for %%a in (%.%) do (set ..%%a=3)
  17. for %%a in (%_%) do (set ..%%a=4)
  18. pause
  19. setlocal
  20. :put 用户输入计算式
  21. cls
  22. title 一次方程计算器V1.1
  23. for /l %%a in (1,1,%num%) do (echo.%%a:!equ%%a!)
  24. set/a e=num+1,att=1,n=1,un=0
  25. set "d="
  26. set /p d=%e%:
  27. if "!d!"=="" (%#:$=表达式不能为空%)
  28. set d=!d: =!
  29. set f=!d!
  30. for %%a in (%.% %_% + -) do (set f=!f:%%a=0!)
  31. if "!f:0=!" neq "=" (%#:$=方程式有误%)
  32. for /f "delims== tokens=1,2" %%a in ("!d!#") do (
  33. if "%%b"=="" (set d=`%%a) else (set d=%%a`%%b))
  34. set d=!d:#=!
  35. ::检验命令表达式
  36. if %e% neq 1 (
  37.     if /i %d%==`run (set mod=1&goto solve)
  38.     if /i %d%==`ret (set mod=2&goto solve)
  39.     if /i %d:~0,4%==`del (set h=%d:~4%
  40.         if defined equ!h! (set equ!h!=!equ%num%!)
  41.         set/a num-=1
  42.         set "equ%num%="
  43.     goto put)
  44.     if /i %d%==`cls (%#:echo;$&pause=endlocal&setlocal%)
  45. )
  46. ::检验方程式表达式
  47. set/a y=2048,g=0
  48. set "nd="
  49. for /l %%y in (1,1,12) do (set/a "len=(y+g)/2"
  50. for /f "delims=" %%z in ("!len!") do (if "!d:~%%z!" equ "" (set y=!len!) else (set g=!len!)))
  51. for /l %%a in (0,1,%len%) do (set m=!d:~%%a,1!
  52.     set ck=0
  53.     if defined .!att!!m! (%#:$=格式有误%)
  54.     for %%b in (!m!) do (set att=!..%%b!)
  55.     if !un!==1 (if !att!==3 (%#:$=未知数不能乘未知数%)
  56.     if !att! leq 2 (set/a un=0,ck=1
  57.     set nd=!nd!]!m!))
  58.     if !att!==3 (set nd=!nd![!m!
  59.     set/a un=1,ck=1)
  60.     if !ck!==0 (set nd=!nd!!m!)
  61. set n=!n!!att!)
  62. if %n:3=0%==%n% (%#:$=无未知数%)
  63. if %att%==1 (set nd=%nd%0)
  64. if %att%==2 (%#:$=加减号最后%)
  65. if %un%==1 (set nd=%nd%])
  66. :simple 符号化简
  67. set ck=%nd%
  68. set nd=%nd:--=+%
  69. set nd=%nd:++=+%
  70. set nd=%nd:+-=-%
  71. set nd=%nd:-+=-%
  72. if %nd% neq %ck% (goto simple)
  73. for /f "delims=` tokens=1,2" %%a in ("!nd!") do (set "nd=%%a=%%b")
  74. ::开始下一个方程式的输入
  75. set/a num+=1
  76. set equ%e%=%nd%
  77. goto put
  78. :solve 解方程初始化
  79. setlocal enabledelayedexpansion
  80. set/a ukc=0,err=0
  81. set "unk="
  82. set "ukn="
  83. set pl=+
  84. set pr=-
  85. set ql=-
  86. set qr=+
  87. ::获取未知数
  88. for /l %%a in (1,1,%num%) do (set x=!equ%%a:[= !
  89.     for %%b in (!x!) do (set y=%%b
  90.         if "!y:]=!" neq "!y!" (for /f "delims=] tokens=1,2" %%c in ("%%b") do (set unk=%%c
  91.                 if not defined @!unk! (set/a ukc+=1
  92.                     set @!unk!=!ukc!
  93.                     set ukn=!ukn!!unk!,
  94.                 )
  95.             )
  96.         )
  97.     )
  98. )
  99. echo;未知数个数%ukc% 方程式个数%num%
  100. if %ukc% neq %num% (endlocal&%#:$=未知数个数不等于方程式个数%)
  101. ::格式转化
  102. for /f "delims==" %%a in ('set @') do (set x=%%a
  103.     set x=!x:@=[!]
  104.     set y=!%%a!
  105.     for /f "delims== tokens=1,2" %%b in ("!x!=!y!") do (
  106. for /l %%d in (1,1,%num%) do (set equ%%d=!equ%%d:%%b=_%%c!)))
  107. for /l %%d in (1,1,%num%) do (set equ%%d=!equ%%d:-=+-!)
  108. ::获取系数
  109. for /l %%a in (1,1,%num%) do (%Made%
  110.     for /f "delims== tokens=1,2" %%b in ("!equ%%a!") do (%By%
  111.         for /l %%d in (0,1,%ukc%) do (set @%%a_%%d=0)
  112.         set sl=%%b
  113.         set sr=%%c
  114.         for %%d in (l r) do (if "!s%%d:~0,1!"=="+" (set s%%d=0!s%%d!)
  115.             set s%%d=!s%%d:+= !
  116.             for %%e in (!s%%d!) do (set cy=%%e
  117.                 if "!cy:_=!" neq "!cy!" (%绽放ad%
  118.                     if "!cy:~0,1!"=="_" (set cy=1!cy!)
  119.                     set cy=!cy:-_=-1_!
  120.                     for /f "delims=_ tokens=1,2" %%f in ("!cy!") do (set @%%a_%%g=!@%%a_%%g!!p%%d!%%f)
  121.                 ) else (
  122.                     set @%%a_0=!@%%a_0!!q%%d!!cy!
  123.                 )
  124.             )
  125.         )
  126.     )
  127. )
  128. ::计算系数
  129. for /f "delims== tokens=1,2" %%a in ('set @') do (set/a %%a=%%b||set err=1)
  130. if %err%==1 (endlocal&%#:$=溢出%)
  131. if %mod%==2 (set file=%~sdp0rect.txt
  132.     (echo;!ukn!常数项
  133.         for /l %%a in (1,1,%num%) do (set "x="
  134.             for /l %%b in (1,1,%num%) do (set x=!x!!@%%a_%%b!,)
  135.     echo;!x!!@%%a_0!))>!file!
  136.     endlocal&%#:$=结果已保存到rect.txt%
  137. )
  138. if %ukc% gtr %_MAX% (endlocal&%#:$=超出程序允许的最多未知数!_MAX!%)
  139. ::清除无关紧要的变量
  140. set @u_m=,
  141. set @n_m=%num%
  142. for /l %%a in (1,1,%num%) do (set @u_m=!@u_m!%%a,)
  143. for /f "delims== eol=@" %%a in ('set ') do (set "%%a=")
  144. for /f "delims== tokens=1,2" %%a in ('set @') do (set q=%%a
  145.     if "!q:_=!"=="!q!" (set @%%b=!q:@=!
  146. set "%%a="))
  147. set/a "all=2*%@n_m%*(%@n_m%+1)*(%@n_m%-1)/3,now=0,fx=%@n_m%"
  148. ::高斯列主消元法,省去了排序,但多了约分操作。
  149. ::第一步化为三角矩阵
  150. echo;正在解方程组...复杂度o(%@n_m%)=!all!
  151. set ux=%@u_m%
  152. set uy=%@u_m%
  153. for %%a in (his sih ls) do (set "%%a=")
  154. for /l %%z in (1,1,%@n_m%) do (set q=0
  155.     for %%a in (!uy!) do (for %%b in (!ux!) do (if !q!==0 (
  156.                 if "!@%%a_%%b!" neq "0" (set his=!his!%%a_%%b
  157.                     if %%z neq %@n_m% (set/a m=0,n=0,a0=0
  158.                         for /l %%x in (0,1,%@n_m%) do (if "!@%%a_%%x!" neq "0" (set/a a!m!=!@%%a_%%x!,m+=1))
  159.                         set/a n=m-1
  160.                         for /l %%x in (1,1,!n!) do (set c=0
  161.                             for /l %%y in (0,1,32) do (if !c!==0 (set/a d=!a%%x!,z=!a%%x! %% !a0!
  162.                         if !z! neq 0 (set/a a%%x=!a0!,a0=!z!) else (set c=1))))
  163.                         if !a0!==0 (set a0=1)
  164.                         for /l %%x in (0,1,%@n_m%) do (set/a @%%a_%%x/=a0)
  165.                         set ux=!ux:,%%b,=,!
  166.                         set uy=!uy:,%%a,=,!
  167.                         for %%c in (!uy!) do (
  168.                             for %%d in (!ux!0) do (set/a @%%c_%%d=!@%%c_%%d!*!@%%a_%%b!-!@%%a_%%d!*!@%%c_%%b!)
  169.                             set @%%c_%%b=0
  170.                             set/a m=0,n=0,a0=0
  171.                             for /l %%x in (0,1,%@n_m%) do (if "!@%%c_%%x!" neq "0" (set/a a!m!=!@%%c_%%x!,m+=1))
  172.                             set/a n=m-1
  173.                             for /l %%x in (1,1,!n!) do (set c=0
  174.                                 for /l %%y in (0,1,32) do (if !c!==0 (set/a d=!a%%x!,z=!a%%x! %% !a0!
  175.                             if !z! neq 0 (set/a a%%x=!a0!,a0=!z!) else (set c=1))))
  176.                             if !a0!==0 (set a0=1)
  177.                             for /l %%x in (0,1,%@n_m%) do (set/a @%%c_%%x/=a0)
  178.                         )
  179.                         set q=1
  180.                     )
  181.                 )
  182.             )
  183.         )
  184.     )
  185.     set/a m=fx*fx-fx
  186.     set/a now+=m,fx-=1,n=1000*now/all
  187.     title 进度 !n:~0,-1!.!n:~-1!%%
  188. )
  189. ::第二步转标准矩阵
  190. echo;===============
  191. set/a ck=0,fx=%@n_m%
  192. for %%a in (%his%) do (if !ck!==0 (set ls=%%a)
  193.     set sih=%%a !sih!
  194. set/a ck+=1)
  195. set his=!sih!
  196. set ux=%@u_m%
  197. set uy=%@u_m%
  198. for %%z in (%his%) do (
  199.     for /f "delims=_ tokens=1,2" %%a in ("%%z") do (set/a m=0,n=0,a0=0
  200.         for /l %%x in (0,1,%@n_m%) do (if "!@%%a_%%x!" neq "0" (set/a a!m!=!@%%a_%%x!,m+=1))
  201.         set/a n=m-1
  202.         for /l %%x in (1,1,!n!) do (set c=0
  203.             for /l %%y in (0,1,32) do (if !c!==0 (set/a d=!a%%x!,z=!a%%x! %% !a0!
  204.         if !z! neq 0 (set/a a%%x=!a0!,a0=!z!) else (set c=1))))
  205.         if !a0!==0 (set a0=1)
  206.         for /l %%x in (0,1,%@n_m%) do (set/a @%%a_%%x/=a0)
  207.         if "%%z" neq "%ls%" (
  208.             set ux=!ux:,%%b,=,!
  209.             set uy=!uy:,%%a,=,!
  210.             for %%c in (!uy!) do (
  211.                  for %%d in (!ux!0) do (set/a @%%c_%%d=!@%%c_%%d!*!@%%a_%%b!-!@%%a_%%d!*!@%%c_%%b!)
  212.                  set @%%c_%%b=0
  213.                  set/a m=0,n=0,a0=0
  214.                  for /l %%x in (0,1,%@n_m%) do (if "!@%%c_%%x!" neq "0" (set/a a!m!=!@%%c_%%x!,m+=1))
  215.                  set/a n=m-1
  216.                  for /l %%x in (1,1,!n!) do (set c=0
  217.                      for /l %%y in (0,1,32) do (if !c!==0 (set/a d=!a%%x!,z=!a%%x! %% !a0!
  218.                  if !z! neq 0 (set/a a%%x=!a0!,a0=!z!) else (set c=1))))
  219.                  if !a0!==0 (set a0=1)
  220.                  for /l %%x in (0,1,%@n_m%) do (set/a @%%c_%%x/=a0)
  221.             )
  222.         )
  223.     )
  224.     set/a m=fx*fx-fx
  225.     set/a now+=m,fx-=1,n=1000*now/all
  226.     title 进度 !n:~0,-1!.!n:~-1!%%
  227. )
  228. ::输出方程组的各个解
  229. set e=0
  230. for /l %%a in (1,1,%@n_m%) do (set/a ck=0
  231.     set "his="
  232.     for /l %%b in (1,1,%@n_m%) do (set q=!@%%a_%%b!
  233.         if "!q!" neq "0" (set/a ck+=1
  234.             if "!q!"=="1" (set his=!his!!@%%b!+) else (if "!q!"=="-1" (set his=!his!-!@%%b!+) else (set his=!his!!q!!@%%b!+))
  235.         )
  236.     )
  237.     if !ck!==0 (
  238.         if "!@%%a_0!"=="0" (
  239.             if !e! neq 1 (set e=2)
  240.         ) else (
  241.             echo;    %%a:0=!@%%a_0!    ×
  242.             set e=1
  243.         )
  244.     ) else (
  245.         set "his=!his:~0,-1!=!@%%a_0!"
  246.         echo;    %%a:!his:+-=-!
  247.     )
  248. )
  249. ::输出方程组结果
  250. echo;===============
  251. set ck=0
  252. for %%a in (有唯一解 无解 无穷多解) do (if %e%==!ck! (echo;方程组%%a)
  253. set/a ck+=1)
  254. pause
  255. endlocal
  256. goto put
  257. \欢迎使用一次方程计算器,本程序能解决大部分线性方程组并显示解答结果。
  258. \用户需按要求输入方程或命令,回车输入下一个,只有正确方程才保留。
  259. \命令在回车、执行后便被删除,错误或不合法的方程也会在回车后被删除。
  260. \
  261. \支持的字符有26个英文字母(不区分大小写)、数字0-9、运算符号+ - =。
  262. \只支持整数计算,含小数分数请人工化为整数形式(两边同乘以一个数)再输入。
  263. \
  264. \用户在本程序里输入的方程式有以下要求:
  265. \    ①方程式必须有且只有一个等号,至少含1个未知数。
  266. \    ②为避免0引起的BUG,规定数字开头不能为0。如果要输入"a=0",请输入"a="。
  267. \    ③未知数既可以是单个字母也可以是字母加任意下标数字。
  268. \    ④数字和未知数之间省略乘号,未知数前的数字1可省略,未知数后面必须跟运算符。
  269. \    ⑤加减号不能出现在方程式末尾,且后面不能是等号。未知数和方程式的个数一致。
  270. \
  271. \命令(等号开头,不区分大小写)如下:
  272. \    ①=run:解方程(组)。
  273. \    ②=ret:获取方程组的系数矩阵(不解答)。
  274. \    ③=deln:删除输入的第n个方程。
  275. \如输入"=del3"会删除第三个方程表达式。n未找到会删除最近的一个方程。
  276. \    ④=cls:清除所有方程
  277. \
复制代码





欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2