这里是一个张量/矩阵的字符串表示形式,表示其打印结果。例如,字符串 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问题,但我们没有找到类似的描述。感谢您的帮助:)
#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