如何不借助库函数解析张量字符串的维度形状?
解析张量字符串获取形状的C++实现
核心思路
要解析张量字符串的形状,我们需要跟踪嵌套维度的层级,统计每个维度的元素数量:
- 用两个栈分别记录每个维度的分隔符(
,)数量,以及该维度是否包含有效元素(解决空数组判断问题)。 - 用有序映射记录每个维度深度对应的大小,确保同层级维度只保留一个有效值(假设输入张量合法,同维度元素形状一致)。
- 遍历字符串时,仅关注
[、]、,和数字字符,忽略空格、换行等无关内容。
实现代码
#include <vector> #include <stack> #include <map> #include <string> #include <cctype> std::vector<int> parse_shape_from_tensor_string(std::string s){ std::stack<int> delimiter_counts; std::stack<bool> has_element; std::map<int, int> depth_size_map; int current_depth = 0; for(char c : s){ if(c == '['){ current_depth++; // 标记父维度存在元素(当前子数组是父维度的一个元素) if(current_depth > 1 && !has_element.empty()){ has_element.top() = true; } delimiter_counts.push(0); has_element.push(false); } else if(c == ','){ if(!delimiter_counts.empty()){ int& top_val = delimiter_counts.top(); top_val++; } } else if(c == ']'){ if(!delimiter_counts.empty() && !has_element.empty()){ bool element_exist = has_element.top(); has_element.pop(); int delimiters = delimiter_counts.top(); delimiter_counts.pop(); // 空数组大小为0,非空数组大小为分隔符数+1 int dim_size = element_exist ? (delimiters + 1) : 0; depth_size_map[current_depth] = dim_size; current_depth--; // 标记父维度存在元素(当前子数组已确认是有效元素) if(current_depth > 0 && !has_element.empty()){ has_element.top() = true; } } } else if(isdigit(c)){ // 遇到数字,标记当前维度存在有效元素 if(!has_element.empty()){ has_element.top() = true; } } // 忽略空格、制表符等无关字符 } std::vector<int> shape; // map按维度深度从小到大遍历,得到从外到内的形状 for(auto& pair : depth_size_map){ shape.push_back(pair.second); } return shape; }
关键逻辑说明
- 维度层级跟踪:遇到
[时增加深度,并初始化当前维度的分隔符计数和元素存在标记;遇到]时减少深度,计算当前维度大小。 - 空数组处理:通过
has_element栈判断维度是否包含有效元素,空数组([后直接跟])的大小记为0。 - 维度大小计算:非空维度的大小等于分隔符数量加1(n个元素对应n-1个分隔符)。
- 结果生成:利用有序映射的特性,按维度深度从小到大取出大小,得到从外到内的张量形状。
测试案例
- 输入
"[[[1,2,3],[4,5,6]]]"→ 返回[1,2,3] - 输入
"[1,2,3,4]"→ 返回[4] - 输入
"[[[],[]]]"→ 返回[1,2,0] - 输入
"[]"→ 返回[0]
内容的提问来源于stack exchange,提问作者Sakura
相关产品推荐
相关产品推荐

