ahk系列-windows超级运行框-表达式计算(11)—avg /sum 平均求和

1、环境准备

  1. windows 7,8,10,11操作系统
  2. ahk 2.x_64位

2、使用方式

avg /sum 计算平均值,计算总和

支持数字中可以简写 k(千) , w(万) ,y(亿)

可以计算运行框中的数据,也可以计算剪切板中的数据,数据以空格分隔,或者是回车,或者是换行符号

我们可以把记事本中或者是excel等分行的数据计算总和或者是平均值、

  1. 输入win+R打开windows运行框
  2. 在运行框中输入:sum 100 200 300 输出:600
  3. 在运行框中输入: sum ,计算"【剪切板】"中数据总和,数据一般都是以换行分隔、
  4. 在运行框中输入: avg 100 200 300 输出:200
  5. 在运行框中输入:avg ,计算"【剪切板】"中数据平均值,数据一般都是以换行分隔、
  6. 表达式按**==**触发结果

3、演示

4、代码

cpp 复制代码
#HotIf  winActive("运行") and winActive("ahk_class #32770")
#MaxThreadsPerHotkey 10
;在运行框中执行强大的计算功能,包括数学运算等
:*?:==::{
  try{
       rawText:=ControlGetText("Edit1","A") ;
       fullResult:=runbox.calculateExpression(rawText)
       if fullResult{
           ControlsetText(fullResult,"Edit1","A")
       }
       ControlSend("{END}","Edit1","A")
   }
}
#HotIf
;==========================================================================================================系统快捷键映射
;执行各种运算取值
class runbox
{
    ;执行比表达式计算,"==" 触发,callflag是其他函数调用该方法
    static calculateExpression(rawstr,callflag:=0)
    {
         ;计算平均值
         if not (str:=Trim(LTrim(rawStr,"avg")))  or inStr(rawStr,"avg ")==1 {
             result:=this.avgExpression(str)
             fulltxt:= rawStr . (str?"":"[剪切板]") . result
             return fulltxt
         }
         ;计算总和
         if not (str:=Trim(LTrim(rawStr,"sum")))  or inStr(rawStr,"sum ")==1 {
             result:=this.avgExpression(str,0)
             fulltxt:= rawStr . (str?"":"[剪切板]") . result
             return fulltxt
         }
    }
    ;计算平均值或者总和 flag:=1 平均值,flag:=0 总和 ,返回结果带有"="或者是"≈"
    static avgExpression(str,flag:=1)
    {
        str:= not str ? A_clipboard :str ;获取剪切板数据
        str:=RegExReplace(RegExReplace(trim(str),"^[\s\r\n]+"),"[\s\r\n]+$","") ;截取开头结尾的空格换行回车
        str:=RegExReplace(trim(str),"[\s\r\n]+","+",&rcount) ;缩减空格
        mathExp:="(" . str . ")" . (flag? ("/" . (rcount+1)):"")
        result:=this.mathExpression(mathExp)
        index:=inStr(result,"=") || inStr(result,"≈") ;获取结果
        return subStr(result,index)
    }
    ;计算数学表达式+,- ,x ,/ % ** 操作,支持括号,支持k(千),w(万),y(亿)
    static mathExpression(str)
    {
        ;计算数学表达式
        str2:=RegExReplace(str,"[abcdefghijlmnopqrstuvxzABCDEFGHIJLMNOPQRSTUVXZ]+","")
        if str!=str2
            return
        if(InStr(str, "+") or InStr(str, "-") or  InStr(str, "*") or InStr(str, "/")
            or InStr(str, "%")  or InStr(str, "**")or  InStr(str, "=") or InStr(str,"≈")or InStr(str, "^"))
        {
             str:=InStr(str, "=")>0 ? ak.getSuffix(str,"="):str ;使连续计算成为可能
             str:=InStr(str,"≈")>0 ? ak.getSuffix(str,"≈"):str ;连续计算约等于
             str:=RegExReplace(str,"\s+","")         ;缩紧字符串
             if inStr(str,"y") or inStr(str,"w") or inStr(str,"k")
                 char_flag:=1
             str2:=ak.set_bignumber(str)              ;处理字符y,w,k
             result:=ak.polish_notation(str2)         ;用逆波兰表达式计算值
             result:=ak.get_bignumber(result,3,char_flag??0)      ;保留三位小数
             fulltxt:=str . result                                ;result中有等号
             return fulltxt
        }
    }
}
;==========================================================================================================系统快捷键映射
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ak工具类class
class ak
{
    ;Fucn 逆波兰表达式计算 + - x ÷ 幂(**/^) 模(%)  expression:数学表达式可以带括号
    ;参考:https://blog.csdn.net/assiduous_me/article/details/101981332
    static polish_notation(expression)
    {
        operator_list:=Map("+",0,"-",0,"*",0,"`/",0,"%",0,"^",0) ;注意list的haskey操作只是检测索引
        operatorlevel_map:=Map("(",0,"+","1","-",1,"*",2,"/","2","%",2,"^",3,")",4)
        operator_map:=Map("+","add","-","sub" ,"*","multi","/","divi","%","mod2","^","pow")
        expression:=strReplace(strReplace(RegExReplace(trim(expression),"\s+",""),"**","^") ,"(-","(0-")
        expression:=inStr(expression,"-(")==1?strReplace(this.insertStrAt(expression,this.mirrorSymbolIndex(expression,"(",")"),")"),"-(","(0-("):expression
        ;①.获取一个中缀表达式集合类似 100+2 -> ["100","+","2"]
        middlefix_list:=[],fix:=""
        Loop parse,expression{
            current_value:=A_LoopField
            if(operatorlevel_map.has(current_value))
            {
              tmp:=""!=fix?middlefix_list.push(fix):""
              middlefix_list.push(current_value)
              fix:=""
            }else fix:=fix . current_value
        }
       tmp2:=fix!=""?middlefix_list.push(fix):""
       if(middlefix_list[1]="-"){ ;处理开头为负数
           middlefix_list.insertAt(1,"(")
           middlefix_list.insertAt(2,"0")
           middlefix_list.insertAt(5,")")
       }
       ;②.转换为后缀表达式(逆波兰表达式)
        operator_stack:=[] ,suffix_list:=[],number_stack:=[]
        for index ,currentElmt in middlefix_list
        {
          if(operator_list.has(currentElmt))
          {
              while(operator_stack.length>0 && operatorlevel_map.get(operator_stack.get(operator_stack.Length))>=operatorlevel_map.get(currentElmt))
                 suffix_list.push(operator_stack.pop())
              operator_stack.push(currentElmt)
          }else if(currentElmt=="(")
             operator_stack.push("(")
          else if(currentElmt==")"){
             while(operator_stack.length>0 && operatorlevel_map.get(operator_stack.get(operator_stack.length))>operatorlevel_map.get("("))
                suffix_list.push(operator_stack.pop())
             if(operator_stack.length>0)
                 operator_stack.pop()
          }else
              suffix_list.push(currentElmt)
        }
        while(operator_stack.length>0)
            suffix_list.push(operator_stack.pop())
        ;③.计算表达式最终的值,规则数字入栈,操作符就出栈两个元素计算值并把结果入栈
        for key,opertor_or_number in suffix_list{
           if(operator_list.has(opertor_or_number)){
                number2:=number_stack.pop(),number1:=number_stack.pop()
                tmpObj:={add:number1+number2,sub:number1-number2,multi:number1*number2,pow:number1**number2}
                T1:=opertor_or_number=="/"?(tmpObj.divi:=number1/number2):""       ;除法容易引发除0异常
                T2:=opertor_or_number=="%"?(tmpObj.mod2:=mod(number1,number2)):""  ;取模容易引发除0异常
                number_stack.push(tmpObj.%operator_map.get(opertor_or_number)%)
           }else
                number_stack.push(opertor_or_number)
        }
        return number_stack.pop()
    }
    ;Func 处理算式中含有k,w,y的,formula 表达式
    static set_bignumber(formula)
    {
      formula:=RegExReplace(formula,"(\d*\.*\d*)k|K","($1*1000)")      ;处理1k
      formula:=RegExReplace(formula,"(\d*\.*\d*)w|W","($1*10000)")     ;处理 1w
      formula:=RegExReplace(formula,"(\d*\.*\d*)y|Y","($1*100000000)") ;处理1亿
      return formula
    }
    ;func 作用:处理大的数字,
    ;参数:bigNumber数字类型的大数字,char_flag:0,1(是否带k,w,y), scale 数字类型保留几位小数
    ;返回:返回字符串
    ;msgBox % Round(100,2)
    static get_bignumber(bigNumber,scale:=0,char_flag:=1)
    {
        ;判断有几位小数
        index:=InStr(bigNumber,".")
        left :=index=0?strLen(bigNumber):InStr(bigNumber,".")-1
        unit:="",prefix:="="
        if char_flag{
            if(left==4) ;单位K
            {
                result:=Round(bigNumber/1000,scale)
                prefix:=(result==bigNumber/1000)?"=":"≈"
                unit:="k"
            }else if(left>4 && left <9) ;单位w
            {
                result:=Round(bigNumber/10000,scale)
                prefix:=(result==bigNumber/10000)?"=":"≈"
                unit:="w"
            }else if(left>=9) ;单位亿
            {
                result:=Round(bigNumber/100000000,scale)
                prefix:=(result==bigNumber/100000000)?"=":"≈"
                unit:="亿"
            }else{ ;小于1k
                result:=Round(bigNumber,scale)
                prefix:=(result==bigNumber)?"=":"≈"
            }
        }else{ ;正常表示方式
            result:=Round(bigNumber,scale)
            prefix:=(result==bigNumber)?"=":"≈"
        }
        result:=RegExReplace(result,"\.0+$","") ;去掉 2.000这样式的
        if(InStr(result,".")>0)
            result:=RegExReplace(result,"0+$","")
        return prefix . result . unit
    }
}
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ak工具类class

5、总结

由于很多操作代码可以复用,单个功能代码臃肿,

完整功能参考:windows超级运行框-表达式计算(12)汇总

各位大佬觉得还可以怎么操作? 欢迎评论区留言讨论!

相关推荐
面朝大海,春不暖,花不开24 分钟前
Python 文件操作与输入输出:从基础到高级应用
windows·python·microsoft
染指11102 小时前
35.x64汇编写法(二)
汇编·windows·x64游戏·x64汇编·游戏攻防
新兴AI民工3 小时前
windows上的visual studio2022的项目使用jenkins自动打包
windows·jenkins·visual studio
WarPigs3 小时前
Visual Studio问题记录
ide·windows·visual studio
love530love4 小时前
【笔记】旧版MSYS2 环境中 Rust 升级问题及解决过程
开发语言·人工智能·windows·笔记·python·rust·virtualenv
Java Fans6 小时前
如何在Windows本机安装Python并确保与Python.NET兼容
开发语言·windows·python
Abigail_chow17 小时前
EXCEL如何快速批量给两字姓名中间加空格
windows·microsoft·excel·学习方法·政务
love530love18 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
代码搬运媛20 小时前
“packageManager“: “[email protected]“ 配置如何正确启动项目?
windows·webpack
小道士写程序21 小时前
Qt 5.12 上读取 .xlsx 文件(Windows 平台)
开发语言·windows·qt