如何解析张量串的维度形状?

问题描述 投票:0回答:1

这里是一个张量/矩阵的字符串表示形式,表示其打印结果。例如,字符串 s = "[[[1,2,3],[4,5,6]]]" 表示张量为:

[
    [
        [1,2,3],
        [4,5,6],
    ]
]

我们知道它具有三个维度。从外到内,第一维度有一个元素。第二个维度有两个元素。第三维度具有三个元素。结果,我们知道形状是[1,2,3]。

那么,如何在不使用库函数的情况下一般解析维度形状。界面可能是: std::vector<int> parse_shape_from_tensor_string(std::string s){ }

这更像是LeetCode问题,但我们没有找到类似的描述。感谢您的帮助:)

c++ string algorithm
1个回答
0
投票

#include <stdio.h> #include <stdlib.h> #include <string> #include <vector> #include <iostream> using namespace std; vector<int> g_result; int RecrusiveParser(vector<string> s, int& i, int layer) { int res = 0; while (i < s.size()) { if (s[i] == "[") { i = i + 1; int temp = RecrusiveParser(s, i, layer + 1); res++; g_result[layer] = temp; } else if (s[i] == "]") { i++; return res; } else { if (g_result.size() == 0) g_result.resize(layer); while (s[i] != "[" && s[i] != "]") { i += 1; res++; } i += 1; return res; } } return -1; } // "[[2,2],[2,2]]" void Parser(vector<string> s) { g_result.clear(); int i = 0; RecrusiveParser(s, i, 0); } vector<string> tokenize(string s) { vector<string> res; string temp = ""; for (char i : s) { if (i == ',' || i == '[' || i == ']') { if (temp.size() > 0) { res.push_back(temp); temp = ""; } if (i != ',') { string temp(1, i); res.push_back(temp); } } else { temp += i; } } return res; } template <typename T> void printVect(vector<T> result) { for (T i : result) { cout << i << " "; } cout << endl; } int main() { auto v = tokenize("[[[2,22],[2,2],[111,2]],[[2,22],[2,2],[111,2]]]");// out 2,3,2 printVect(v); Parser(v); printVect(g_result); v = tokenize("[[[2,22],[2,2],[111,2]],[[2,22],[2,2],[111,2]],[[2,22],[2,2],[111,2]]]");// out 3,3,2 printVect(v); Parser(v); printVect(g_result); v = tokenize("[1,2,3,4]");// out 4 printVect(v); Parser(v); printVect(g_result); }

在获取字符串的第一步中,我将其分解为标记,使用“,”和“[”,“]”作为分隔符,其中“[”,“]”应保留。

vector<string> tokenize(string s) { vector<string> res; string temp = ""; for (char i : s) { if (i == ',' || i == '[' || i == ']') { if (temp.size() > 0) { res.push_back(temp); temp = ""; } if (i != ',') { // "[","]" should be retained string temp(1, i); res.push_back(temp); } } else { // Numbers containing multiple digits temp += i; } } return res; }

接下来,递归处理令牌序列。

int RecrusiveParser(vector<string> s, int& i, int layer) { int res = 0; while (i < s.size()) { if (s[i] == "[") { i = i + 1; int temp = RecrusiveParser(s, i, layer + 1); res++; g_result[layer] = temp; } else if (s[i] == "]") { i++; return res; } else { if (g_result.size() == 0) g_result.resize(layer); while (s[i] != "[" && s[i] != "]") { i += 1; res++; } i += 1; return res; } } return -1; }

每次遇到‘[’就向下递归,每次遇到‘]’就返回。

这里,res是每层的维度。

当为最内层时,res为数字中的一个,例如“[[[2,22],[2,2],[111,2]],[[2,22],[2, 2] ,[111,2]]]" ,最内层为 [2,22],res = 2。

当不是最内层时,当前层的res为从当前层向下递归的次数。例如,对于“[,[,2,22,],[,2,2,] ,[,111,2],]”,我们从i=1,i=5,i=9各向下递归一次,所以当前level的res为3

© www.soinside.com 2019 - 2024. All rights reserved.