Lua学习笔记

安装Lua最小开发运行环境:
apt-get install lua5.1-0-dev
find / -name lua.h
/home/hanxiaohua/work1/MathTool/lua/lua.h
/usr/include/lua5.1/lua.h
./luatest
./luatest: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0: no version information available (required by ./luatest)
root@ubuntu:/home/cpptest/lua# ./luatest NumberTheory.lua
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
4    -4    -4
4    6
totient(37)=36
totient(57)=36
totient(63)=36
totient(74)=36
totient(76)=36
100
7
PowerMod(5,-2,17)=15
PowerMod(5,-1,17)=7
PowerMod(5,0,17)=1
PowerMod(5,1,17)=5
PowerMod(5,2,17)=8
PowerMod(5,4,17)=13
PowerMod(5,8,17)=16
PowerMod(5,16,17)=1
在前30个正整数中,1,8,12,15,16,20,21,24,28,30,没有原根
lprimroot(2)=1,lprimroot(3)=2,lprimroot(4)=3,lprimroot(5)=2,lprimroot(6)=5,lprimroot(7)=3,lprimroot(9)=2,lprimroot(10)=3,lprimroot(11)=2,lprimroot(13)=2,lprimroot(14)=3,lprimroot(17)=3,lprimroot(18)=5,lprimroot(19)=2,lprimroot(22)=7,lprimroot(23)=5,lprimroot(25)=2,lprimroot(26)=7,lprimroot(27)=2,lprimroot(29)=2,有原根

function Factorial(n)
    if n==0 or n==1 then
        return 1
    else
        return n * Factorial(n-1)
    end
end

--print("Enter a number : ")
--i = io.read("*number")   
for i=5,12,1 do     
    io.write(i,"!=",Factorial(i),"\n")
end

--求2个整数的最大公约数
function GcdInt(a,b)
    if(a*b<0) then
        return -GcdInt(math.abs(a),math.abs(b))
    end
    if(a<b) then
        local temp=a
        a=b
        b=temp
    end
    if(a%b==0)then
        return b
    else
        return GcdInt(a%b,b)
    end
end

local ret=GcdInt(12,32)
local ret1=GcdInt(-12,32)
local ret2=GcdInt(12,-32)
print(ret,ret1,ret2)

function Iscoprime(a,b)
    local ret=0
    if(GcdInt(a,b)==1)then
        ret=1
    end
    return ret
end

--φ(n)表示不大于n且与n互素的正整数个数、n阶循环群中n阶元的个数、本原n次单位根(n次单位原根)的个数、整数模n乘法群(模n既约剩余类)(Z/p^nZ)^×中与n互素剩余类的个数
function Phi(n)
    local ret=0
    if(n==1)then
        return 1
    end
    for i=1,n-1,1 do     
        ret=ret+Iscoprime(n,i)
    end    
    return ret
end

--T(n)表示n的正因子的个数、n阶循环群子群的个数、Z/nZ理想的个数
function Sigma0(n)
    local ret=0
    for d=1,n,1 do 
        if(n%d==0)then
            ret=ret+1
        end
    end
    return ret
end

--totient(12)=4
--|S(C_12)|=T(12)=|{1,2,3,4,6,12}|=6
print(Phi(12),Sigma0(12))

local v36={37,57,63,74,76}
for i,v in pairs(v36) do
    io.write("totient(",v,")=",Phi(v),"\n")
end    

function Mod(ret,n)
    if(ret<0)then
        local ret1=ret+(-ret+1)*n
        return ret1%n
    end
    return ret%n
end

function mod(ret,n)
    local raw_mod=ret%n
    if (raw_mod==0) then
        return 0
    elseif (ret>= 0) then
        return raw_mod
    else
        return raw_mod+n
    end
end

function inverse_mod_p(u,p)
    for i=1,p-1,1 do 
        if (Mod(u * i, p ) == 1)then
            return i
        end        
    end
    return nil
--[[
    local t1 = 0
    local t3 = 0
    local q  = 0
    local u1 = 1
    local u3 = u
    local v1 = 0
    local v3 = p
    local inv_v = 0
    
    while( v3 ~= 0)    do
        q = u3 / v3
        t1 = u1 - v1 * q
        t3 = u3 - v3 * q
        u1 = v1
        u3 = v3
        v1 = t1
        v3 = t3
    end    
    inv_v=mod(u1,p)
    if (mod(u * inv_v, p ) ~= 1)then
        return 0
    end
    return inv_v
]]--
end

function PowerMod(a,k,p)
    if k<0 then
        local a1=inverse_mod_p(a,p)
        return PowerMod(a1,-k,p)
    end
    local ans=1
    for i=1,k,1 do 
        ans=ans*a%p
    end
    return ans
end

function OrderMod(a,p)
    local k=1
    while(k<=p)    do
        if(PowerMod(a,k,p)==1)then
         break
        end
        k=k+1
    end
    return k
end

function LogMod(b,a,p)
    local k=1
    while(k<=p)    do
        if(PowerMod(a,k,p)==b)then
         break
        end
        k=k+1
    end
    return k
end

print(LogMod(57, 3, 113))
print(inverse_mod_p(5,17))
local bArr={-2,-1,0,1,2,4,8,16}
for i,v in pairs(bArr) do
    io.write("PowerMod(5,",v,",17)=",PowerMod(5,v,17),"\n")
end    

function is_primitive_root(a,p)
    local k=OrderMod(a,p)
    return k==Phi(p)
end

--计算模n的最小原根
function PrimitiveRootMod(n)
    for a=1,n-1,1 do
        local ret=is_primitive_root(a,n)
        if(ret)then
            return a
        end
    end
    return nil
end

io.write("在前30个正整数中,")
for n=1,30,1 do 
    if PrimitiveRootMod(n)==nil then 
        io.write(n,",")
    end
end
io.write("没有原根\n")
for n=1,30,1 do 
    local ret=PrimitiveRootMod(n)
    if ret~=nil then 
        io.write("lprimroot(",n,")=",ret,",")
    end
end
io.write("有原根\n")

test.lua中依赖于宿主程序calllua的Lua代码:暂无
root@ubuntu:/home/cpptest/lua# g++ -o calllua calllua.cpp -I /usr/include/lua5.1/ -llua5.1
Hello, World!
10+30=40
1    灵智系
2    蛮荒系
3    地脉系
4    天羽系
5    蜚廉系
6    瑞兽系
7    神巫系
8    幽冥系
PHYLE_MAX=8
eWorldPhyle.P_TERRAN=0
eWorldPhyle.PHYLE_MAX=8
0    灵智系
1    蛮荒系
2    地脉系
3    天羽系
4    蜚廉系
5    瑞兽系
6    神巫系
7    幽冥系
(1/17)=1,x=1
(2/17)=1,x=6
(3/17)=-1,x=0
(4/17)=1,x=2
(5/17)=-1,x=0
(6/17)=-1,x=0
(7/17)=-1,x=0
(8/17)=1,x=5
(9/17)=1,x=3
(10/17)=-1,x=0
(11/17)=-1,x=0
(12/17)=-1,x=0
(13/17)=1,x=8
(14/17)=-1,x=0
(15/17)=1,x=7
(16/17)=1,x=4
(17/17)=0,x=0
3    8    8    1
1二次剩余:[1,2,4,8,9,13,15,16,]
-1二次非剩余:[3,5,6,7,10,11,12,14,]
0整除:[17,]
10+5=15

-- test.lua
print "Hello, World!"

myName = "beauty girl"  
helloTable = {name = "mutou", IQ = 125}  
  
function helloAdd(num1, num2)  
    return (num1 + num2)  
end;  

sum=helloAdd(10,30)
print("10+30="..sum)

gszWorldPhyle= {"灵智系", "蛮荒系", "地脉系", "天羽系", "蜚廉系", "瑞兽系", "神巫系", "幽冥系"}
--i 表示索引, v 表示值
for i,v in ipairs(gszWorldPhyle) do
   print(i, v)
end
PHYLE_MAX=#gszWorldPhyle
print("PHYLE_MAX="..PHYLE_MAX)

-- 填index=-1从0开始,填index=0或不填index从1开始,……
function CreateEnumTable(tbl, index) 
    local enumtbl = {} 
    local enumindex = index or 0 
    for i, v in ipairs(tbl) do 
        enumtbl[v] = enumindex + i 
    end 
    return enumtbl 
end
--[[
    种族= 0人型系,1野兽系,2植物系,3飞行系,4昆虫系,5龙系,6神系,7不死系
]]--
eWorldPhyle = CreateEnumTable({"P_TERRAN", "P_BEAST", "P_PLANTS", "P_FLY", "P_INSECT", "P_DRAGON", "P_PROTOSS", "P_UNDEAD", "PHYLE_MAX"},-1)
print("eWorldPhyle.P_TERRAN="..eWorldPhyle.P_TERRAN)
print("eWorldPhyle.PHYLE_MAX="..eWorldPhyle.PHYLE_MAX)

function getWorldPhyle(Phyle) 
    return gszWorldPhyle[Phyle+1]
end

for i=eWorldPhyle.P_TERRAN,eWorldPhyle.PHYLE_MAX-1,1 do
    local v=getWorldPhyle(i)
    print(i,v)
end

--正确的获取table的长度应该是遍历,而且要用pairs,不要用ipairs
local function get_len(tb)
  local len = 0
  for k,v in pairs(tb) do
    len= len+1
  end
return len
end

--[[
按定义计算二次剩余和二次非剩余
x=8,(13/17)=1
x=无解,(5/17)=-1
]]--
function Legendre(a,p)
    local x=0
    if(a%p==0) then
        return 0,x--是p的倍数
    end
    for i=1,p-1,1 do
       if((i*i-a)%p==0) then
              x=i
           return 1,x--a是p的二次剩余
       end
    end
    return -1,x--a是p的二次非剩余
end

local Ret17={[1]={}, [-1]={}, [0]={}}
for i=1,17,1 do
local ret,x=Legendre(i,17)
local str = string.format("(%d/17)=%d,x=%d",i,ret,x)
print(str)
--print(i,ret,x)
table.insert(Ret17[ret],i)
end
print(get_len(Ret17),#Ret17[1], #Ret17[-1], #Ret17[0])

function getRetStr(ret) 
    local strArr={"二次非剩余","整除","二次剩余"}
    return strArr[ret+2]
end

for k,v in pairs(Ret17) do
    io.write(k..getRetStr(k)..":[")
    for k1,v1 in pairs(v) do
        io.write(v1,",")
    end
    print("]")
end

lua中元表的应用例子1:lua复数类
root@ubuntu:/home/cpptest/lua# ./luatest2
./luatest2: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0: no version information available (required by ./luatest2)
4    5
-2    -3
-1    7
0.28    -0.04
c:4    5
The sum is 21
luapythagorean(3,4)=5.000000

-- test2.lua

function add(x,y)
    return x+y
end

function pythagorean(a,b) 
local c2 = a^2 + b^2 
return math.sqrt(c2) 
end

function fun(x)
    return math.sqrt(math.sqrt(4*x*x+1)-x*x-1)
end

complex={
__add=function(op1,op2)
             op = {}
             op.x = op1.x + op2.x
             op.y = op1.y + op2.y
             setmetatable(op,complex)
             return op
           end,

__sub=function(op1,op2)
 op = {}
 op.x = op1.x - op2.x
 op.y = op1.y - op2.y
 setmetatable(op,complex)
 return op
end,

__mul=function(op1,op2)
 op = {}
 op.x = op1.x * op2.x-op1.y * op2.y
 op.y = op1.x* op2.y + op2.x* op1.y
 setmetatable(op,complex)
 return op
end,

__div=function(op1,op2)
 op = {}
 op.x = (op1.x * op2.x+op1.y * op2.y)/(op2.x * op2.x+op2.y * op2.y)
 op.y = (-op1.x* op2.y + op2.x* op1.y)/(op2.x * op2.x+op2.y * op2.y)
 setmetatable(op,complex)
 return op
end,

create=function(o)
 o = o or {}
 setmetatable(o,complex)
 return o
end             
}
    
a=complex.create{x=1,y=1}
b=complex.create{x=3,y=4}
c = a + b
print(c.x, c.y)  -- 输出 4,5
d = a - b
print(d.x, d.y)  -- 输出 -2,-3
e = a * b
print(e.x, e.y)  -- 输出 -1,7
f = a / b
print(f.x, f.y)  -- 输出 0.28,-0.04

meta={
__add=function(op1,op2)
             op = {}
             op.x = op1.x + op2.x
             op.y = op1.y + op2.y
             return op
end
    }
    
a={x=1,y=1}
setmetatable(a,meta)
b={x=3,y=4}
c = a + b
print("c:"..c.x, c.y) -- 输出 4,5

大家可以参考lua手册,metatable是被译作元表,Lua 中的每个值都可以用一个 metatable。这个 metatable 就是一个原始的 Lua table ,它用来定义原始值在特定操作下的行为。
一个 metatable 可以控制一个对象做数学运算操作、比较操作、连接操作、取长度操作、取下标操作时的行为,metatable 中还可以定义一个函数,让 userdata 作垃圾收集时调用它。对于这些操作,Lua 都将其关联上一个被称作事件的指定健。当 Lua 需要对一个值发起这些操作中的一个时,它会去检查值中 metatable 中是否有对应事件。如果有的话,键名对应的值(元方法)将控制 Lua 怎样做这个操作。 
metatable通过其包含的函数来给所挂接的table定义一些特殊的操作,包括:
__add: 定义所挂接table的加法操作
__mul: 定义乘法操作
__div: 定义除法操作
__sub: 定义减法操作
__unm: 定义负操作, 即: -table的含义
__tostring: 定义当table作为tostring()函式之参数被呼叫时的行为(例如: print(table)时将呼叫tostring(table)作为输出结果)
__concat: 定义连接操作(".."运算符)
__index: 定义当table中不存在的key值被试图获取时的行为
__newindex: 定义在table中产生新key值时的行为
Lua中用表类型模拟复数,x表示实部,y表示虚部;然后把复数相加的逻辑(实部+实部,虚部+虚部)写进元表内 __add 方法中,因此,(1+1i) + (3+4i) = (4+5i)。元表是普通表变量中的一张隐藏的表,用 setmetatable 函数设置它,想要读出来则用 getmetatable。
如果我们正在编制一个复数计算程序,需要定义许多复数,那么能实现一个“永久”的复数类型 (complex)那是再好不过了。在该代码中,利用 complex.create 创建复数,只需要输入复数的实部和虚部的值即可,然后可以对复数使用加法运算,加法运算的结果(这里指 c)也是复数。我们这里说一个表是复数(表),不仅仅要求该表具有 x,y 两项数值,而且要具有复数的行为,类似“相加”、“相减”、“相乘”。。。等等。

Lua基础知识
常量
变量
a=10
a=2.5
a="诸葛量化"
=是赋值符号,==是等于符号
lua变量必须以字母或者下划线开头,区分大小写
lua的关键字不能用作变量名
8种数据类型:
nil、boolean、number、string、function、userdata、thread、table
局部变量由关键字local定义的,全局变量没有被local定义
Lua语言优势:
小巧、快速、易于嵌入到C语言、与C语言交互方便、易于在线更新
lua、luac一个是运行环境,一个是编译器
Lua语言调用C语言带参数的方法:getString
luaL_checkstring(L,1);//获取传进来的参数,检查第1个参数
lua_pushstring(L,buf);压入栈中
return 1;//指明返回值有1个
Lua语言和C语言的交互机制
lua语言的索引是从1开始的
从上到下是-1、-2、-3……
从下到上是1、2、3、……
数组语言不仅仅是C语言
Lua语言不依赖于数组语言的数据类型

C语言调用Lua语言的方法
Lua语言没有入口方法
执行Lua中的main方法(无参数、无返回值)
lua_getglobal(L,"main");//Lua栈的第一个位置放进方法
lua_call(L,0,0);//第二个表示传进参数的个数,第三个表示返回值的个数
方法调用结束后会自动把栈清空
使用C语言执行一个Lua文件
luaL_newstate创建一个lua_State
Lua_openlibs加载库(print是库里面的方法)
dofile(L,"app.lua")
使用C语言执行一段字符串Lua脚本
dostring(L,"print(\"Hello eoe\")","MyScript");
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章