输入格式如下: -
CHAR-> CHAR-> CHAR-> ......任意数次= INTEGER
这里,CHAR - 代表Key的任何字符。 INTEGER - 表示此关系值的任何整数值。
我们有很多这样的序列。我们必须为此生成JSON格式。
示例: -
a->b = 12
a->b = 20
a->c->d = 190
a->d = 300
a->c->e = 90
c = 18
输出: -
{
a : {
b :[12, 20],
c : {
d : [190]
e : [90]
}
d : [300]
}
c : [18]
}
错误案例
如果任何键具有值并且它将指向任何其他键,那么它应该是不可能的
示例: -
a : {
[15],
d : {
// something here
}
}
我的算法: -
a
和c
是两棵树的根。这是我的算法,但不正确。请帮我纠正算法或开发新算法。
答案 0 :(得分:3)
改为使用树。代码是未经测试的(我很着急),但是如果您理解逻辑,它应该让您开始:
class Node {
public:
typedef enum {
Dictionary,
Integer
} Type;
Node(Type t, const std::string &n): type(t), name(n) {}
~Node() {
std::unordered_map<std::string, Node *>::const_iterator it;
for (it = children.begin(); it != children.end(); it++)
delete it->second; // delete it :P
}
// lazily inserts a child if non-existent yet. Returns it.
Node *insert(const std::string &n, Type t, int v) {
Node *child = children[n];
if (child == nullptr) {
child = new Node(t, n);
children[n] = child;
}
child->vals.push_back(v);
return child;
}
// this is supposed to de-serialize a tree in JSON format
void dump(int level, bool hasmore) {
for (int i = 0; i < level; i++)
std::cout << " ";
std::cout << "\"" << name << "\": ";
if (type == Node::Dictionary) {
std::cout << "{" << std::endl;
std::unordered_map<std::string, Node *>::const_iterator it;
std::size_t i = 0;
for (it = children.begin(); it != children.end(); it++) {
it->second->dump(level + 1, i++ + 1 < children.size());
}
for (int i = 0; i < level; i++)
std::cout << " ";
std::cout << "}";
} else {
std::cout << "[ ";
std::vector<int>::const_iterator it;
bool first = false;
for (it = vals.begin(); it != vals.end(); it++) {
if (first)
std::cout << ", ";
else
first = true;
std::cout << *it;
}
std::cout << " ]";
}
if (hasmore)
std::cout << ",";
std::cout << std::endl;
}
private:
std::unordered_map<std::string, Node *> children; // if type == Dictionary
std::string name;
Type type;
std::vector<int> vals; // if type == Integer
};
在解析文本时,假设行的顺序正确(即,您不会插入到尚不存在的节点中),您可以轻松地构建一个树。
int main()
{
Node root(Node::Dictionary, "root");
std::string line;
// parse line: key path and value
while (std::getline(std::cin, line)) {
// split line into keypath and number
std::size_t eqsign = line.find('=');
std::string path = line.substr(0, eqsign);
std::string nums = line.substr(eqsign + 1);
int num = std::stoi(nums);
// Iterate through key path
Node *child = &root;
std::size_t n = 0, k;
while ((k = path.find("->", n)) != std::string::npos) {
std::string key = path.substr(n, k - n);
child = child->insert(key, Node::Dictionary, 0);
n = k + 2;
// error handling can be implemented here and in Node::insert(), DIY
}
std::string key = path.substr(n);
child->insert(key, Node::Integer, num);
}
// then, deserialize our data structure as JSON
root.dump(0, false);
return 0;
}
这不处理任意空格;但它应该很容易修复。