You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GDScript将整数数组高效压缩为可还原的紧凑字符串?

整数数组压缩需求与优化方案

目标

将类似[12, 1, -34, 55, 13, 341, 11, 56, 321, -3422, 1222, -4, 237]的整数数组压缩为更小尺寸的可还原字符串。

原因

过长的字符串会导致使用的数据库管理器交互时冻结(数组以字符串格式存储)。

背景

实际存储的是网格坐标列表,例如[Vector3(1,2,3), Vector3(4,5,6)]会转换为[1,2,3,4,5,6],基于GDScript开发。


现有尝试

针对上述示例数组,我实现的最优压缩结果为:"c1-y.Td,y1.bU,w1-ym,cm-4,n7"

实现逻辑:将大于9的数值对映射为非数字字符(如10=a,11=b,61=Z),仅在多字符转换结果间使用逗号,同时把"-"用作类逗号符号(逻辑较复杂)。经200组随机数组测试,平均减容48%(不含空白字符)。

问题

是否有更优的方法实现该需求?


补充:个人GDScript实现方案

以下是我编写的GDScript代码,供参考:

extends Node
var negative_character_index = 50000
# 跳过空白字符以及"."、","、"()",这些用于特殊场景
var start_char = 47

func num_to_char(num: int):
    var x = abs(num)
    if x > negative_character_index:
        # 数值过大,无法转换
        return
    else:
        x += start_char
        if num < 0:
            x += negative_character_index
        var char = String.chr(x)
        return char

func char_to_num(char : String):
    var x = char.unicode_at(0) - start_char
    if x == null:
        # 可能negative_character_index被修改
        breakpoint
    
    if x > negative_character_index:
        x -= negative_character_index
        x *= -1
        
    return x

# 压缩单个整数
func int_to_compact_int_string(n:int):
    
    var compact_n = ""
    # 记录当前可转换的最长前缀
    var head = ""
    
    var last_head_int = null
    var last_char = null
    
    var get_zeros_code = func(head):
        
        var zeros = 0
        
        if head.begins_with("0"):
            
            for char2 in head:
                if char2 == "0":
                    
                    zeros += 1
                else:
                    break
            if head.right(1) == "0":
                
                zeros -=1
            if zeros > 0:
                return "("+str(zeros)+")"
        return ""
    
    for num in str(n):
        
        head += num
        print(head)
        if num != "-":
            
            var head_int = str_to_var(head)
            var char = get_zeros_code.call(head) + num_to_char(head_int)
            print(char)
            if last_head_int != null && char == null:
                compact_n += last_char
                head = ""
                head += num
                
                last_head_int = str_to_var(head)
                last_char = get_zeros_code.call(head) + num_to_char(last_head_int)
            else:
                last_head_int = head_int
                last_char = char
        print("~~~")
    if head != "":
        print(head)
        print(last_char)
        print("~~~")
        compact_n += last_char
    
    return compact_n

# 将整数数组压缩为字符串
func int_arr_to_compact_str(int_arr):
    var compact_str = ""
    var is_multi = false
    for n in int_arr:
        
        var compact_n:String = int_to_compact_int_string(n)
        if compact_n.length() > 1: # 多字符压缩结果用逗号分隔
            compact_str += ","
            is_multi = true
        elif is_multi:
            compact_str += "."
            is_multi = false
        
        compact_str += compact_n
        
    return compact_str

# 还原单个压缩后的整数
func new_compact_int_string_to_int(compact_n:String):
    
    var n = ""
    
    var is_zeros = false
    var zeros = ""
    
    for char in compact_n:
        if char == "(":
            is_zeros = true
            zeros = ""
        elif char == ")":
            is_zeros = false
            var i = 0
            
            while i < str_to_var(zeros):
                
                n += "0"
                i+=1
        elif is_zeros:
            zeros += char
        else:
            var index = char_to_num(char)
            if index > negative_character_index:
                index -= negative_character_index
                index *= -1
            
            n += str(index)
    
    return str_to_var(n)

# 将压缩字符串还原为整数数组
func new_compact_str_to_int_arr(compact_str):
    var int_arr = []
    
    var is_multi = false
    var multi_compiler = ""
    for char in compact_str:
        if char == ',' || char == '.':
            is_multi = char == ','
            
            # 结束当前多字符数值的编译
            if multi_compiler.length() >0:
                int_arr.append(new_compact_int_string_to_int(multi_compiler))
                multi_compiler = ""
            
        else:
            if is_multi:
                multi_compiler += char
            else:
                int_arr.append(new_compact_int_string_to_int(char))
    
    if multi_compiler.length() > 0:
        int_arr.append(new_compact_int_string_to_int(multi_compiler))
        multi_compiler = ""
    
    return int_arr

func _ready():
    var arr2 = [237, 50001, -5000000003, 250000000]
    
    # print("---")
    # for i in range(999):
    #     print(String.chr(i)+" -> "+str(i))
    # print("---")
    
    print(arr2)
    var comp = int_arr_to_compact_str(arr2)
    print(comp)
    var r_arr2 = new_compact_str_to_int_arr(comp)
    print(r_arr2)

内容的提问来源于stack exchange,提问作者DED

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:31:03