为了账号安全,请及时绑定邮箱和手机立即绑定

LUA 关于取出两个table中不同元素的算法。

LUA 关于取出两个table中不同元素的算法。

富国沪深 2019-03-29 19:18:00
首先我建立两个table定义一个临时table,把T_letter_tbl赋值给临时table,然后用一个双循环遍历两个table,找出两个table相同的一项,清空我想用Interim_tbl[j]=nil清空这些元素,循环只能执行一次,如果我用table.remove来做,则出现这种情况并且求这种操作的其他算法  
查看完整描述

3 回答

?
慕的地10843

TA贡献1785条经验 获得超8个赞

【我理解下你的意思你是要把 T_letter_tbl 中所有元素的 letter标签和  和 hope_letter_tbl 中的元素比较,如果 发现重复 的 则删除 T_letter_tbl 中的 重复标签吗?【一般做法】用 lua 做这种很容易,但是要注意方法,不是比较,那样遍历比较 效率太低。先把 需要比较的 table 的元素作为 索引 建立一个 hash直接取元素 进行 标签判断,

下面是一个演示:table.print 自定义的输出,可以删去,自己选择输出方式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

  

function table.print ( tbl, name )

    name = name or "table"

    local prompt = '  '

    local i = 1

    local printed = {}

    local function tostring2 ( var )

        if (type( var) == "string" ) then

               return '"' ..var ..'"'

        end

        

        return tostring(var )

    end

    local function itor ( t , i )

        printed[ tostring( t)] = true;

        for key , ele in pairs (t ) do

            if not (type( ele) == "table" ) then

                print( string .format('%s[%s] = %s;' , string.rep( prompt, i ), tostring2 ( key ),tostring2 (ele )) )

            elseif printed [tostring( ele)] then

                print( string .format('%s[%s] = %s;' , string.rep( prompt, i ), tostring2 ( key ),tostring2 (ele )) )

            else

                print( string .format('%s[%s] = {' , string.rep( prompt, i ), tostring2 ( key )) )

                i = i + 1

                itor( ele, i)

                i = i - 1

                print( string .format('%s};' , string.rep( prompt, i )) )

            end

        end

    end

  

    print( string.format( "%s = {" , name ) )

    itor( tbl, i)

    print("};" )

end

-----------------------------------------------------

tbl_letter_HOPE = {

    [1] = "bbbbbb";

    [2] = "ffffff";

    [3] = "cccccc";

    [4] = "xxxxxx";

    [5] = "eeeeee";

};

tbl_letter_T = {

    [1] = {["letter"] = "Y"};

    [2] = {["letter"] = "M"};

    [3] = {["letter"] = "P"};

    [4] = {["letter"] = "K"};

    [5] = {["letter"] = "bbbbbb"};

    [6] = {["letter"] = "R"};

    [7] = {["letter"] = "Q"};

    [8] = {["letter"] = "xxxxxx"};

    [9] = {["letter"] = "L"};

    [10] = {["letter"] = "D"};

    [11] = {["letter"] = "B"};

    [12] = {["letter"] = "ffffff"};

    [13] = {["letter"] = "Z"};

    [14] = {["letter"] = "T"};

    [15] = {["letter"] = "["};

    [16] = {["letter"] = "cccccc"};

    [17] = {["letter"] = "E"};

    [18] = {["letter"] = "C"};

    [19] = {["letter"] = "W"};

    [20] = {["letter"] = "I"};

    [21] = {["letter"] = "F"};

    [22] = {["letter"] = "eeeeee"};

    [23] = {["letter"] = "O"};

    [24] = {["letter"] = "X"};

    [25] = {["letter"] = "U"};

    [26] = {["letter"] = "S"};

};

--- 根据 tbl_letter_HOPE 中的元素 去除 tbl_letter_T 中的元素

-- 

local function main ()

    local tbl_erase = {}

    for key, ele in pairs(tbl_letter_HOPE) do

       -- 不考虑 元素权重则 改为  = true

        tbl_erase[tostring(ele)] = (tbl_erase[tostring(ele)] or 0) + 1 

    end

     

     

    for key, ele in pairs(tbl_letter_T) do

        if tbl_erase[ele.letter] then

            -- 移除 整行 [12] = {["letter"] = "ffffff"};

            tbl_letter_T[key] = nil

             

            -- 还是 一个标签 letter

            --tbl_letter_T[key].letter = nil

        end

    end

    table.print(tbl_letter_T)

end

startTime = os.time()

main()

print( string.format(">> This function cost: %s ms", tostring(os.time()-startTime) ) )

【附】

如果只想 获得去除给定元素后的 table

可以先 复制原 tbl_letter_T

注意:

不要用 浅复制 你之前 那个代码 可能 就是 希望做一个 tbl_letter_T 的副本

但是 使用 浅复制 相当于仅复制了指向table的句柄。

1

tbl_Interim = tbl_letter_T   -- 2个变量指向同一个 table表

要用

1

2

3

for key, ele in pairs(tbl_letter_T) do

 tbl_Interim [key] = ele

end

 


查看完整回答
反对 回复 2019-03-31
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

不要用remove操作表
因为remove操作后表的长度改变了 后面的元素也会往前移
而你循环的次数则是在一开始就定好了 这就会导致最后几次访问出错

打个比方
两个table 各15个元素 只有第7个那一对是相同的
你for到第7次的时候remove了第7个 而原来的第8个 变成了7 9变成了8
当你for到15的时候 已经是个nil了

查看完整回答
反对 回复 2019-03-31
  • 3 回答
  • 0 关注
  • 2403 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信