时间限制:1秒
空间限制:128M
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。
为了方便处理,本题的JSON字符串满足以下限制:
JSON对象具有以下形式:
{左括号 ,逗号隔开的数个键值对 }右括号
例如:
{}(0个键值对){ }(0个键值对){键值对}(1个键值对){键值对,键值对}(2个键值对){键值对 , 键值对 }(2个键值对){键值对, 键值对, 键值对}(3个键值对)键值对具有以下形式:
字符串 : 值
例如:
字符串: 值字符串 :值本题不用考虑多个键值对是否相同的问题
字符串具有以下形式:
“双引号 字符串内容 ”双引号
例如:
"字符串内容"字符串内容可以包括字母、数字、以及非"字符(本题不需要考虑字符串转义的问题)
例如:
LetMeFlyTisfyHa?ks_998Ys.;lsfjie:值可以是字符串,也可以是JSON对象(此题不考虑数字、布尔值、数组等)
例如:
"LetMeFly"(这是一个字符串){"LetMeFly": "Tisfy"}(这是一个JSON对象)以下都是符合本题题意的JSON对象:
{}{"LetMeFly" : "Tisfy"}{"LetMeFly": "Tisfy", "aHa?": "888"}{"LetMeFly" : {"TaoWa?": "Yes!"}}{"____" : {"TaoWa?": {"ZaiLaiYiCeng": "..."}}, "DouHao": "GeKai"}{"ZiFuChuan_string": "FakeJSONObject{"}{"data":{"problemsetStreakCounter":{"today":"2022-08-22T16:04:39.145943197+08:00","streakCount": "399","daysSkipped":"0","todayCompleted":"true","__typename":"StreakCounterNode"}}}{"ZuiHouYiTi?" : "MayBe"}到此为止,此题的JSON对象的格式终于讲完了。
但是需求才刚刚开始😷
这道题的需求是,给你一个符合上述条件的JSON对象,请你按照要求将其格式化。
JSON对象格式化后为:
{左括号
四个空格的缩进 键值对1 逗号
四个空格的缩进 键值对2 逗号
四个空格的缩进 键值对3
}右括号
例如:
{
键值对1,
键值对2,
键值对3
}
或者(键值对数量为0)
{
}
空的JSON对象这样格式化好像挺丑的,但是此题就不再要求空的JSON对象要格式化到一行了
键值对格式化后为:
字符串 :冒号 一个空格 值
例如
"LetMeFly": "Tisfy"
或者(值为JSON对象)
"MaoHaoHouDeKongGeShiJianZhiDuiDeGeShiHuaYaoQiu": {
"QianMianYaoZaiYou4GeSuoJin": "ZheShiJSONDuiXiangDeGeShiHuaYaoQiu"
}
以下都是符号要求的格式化后的JSON对象
{
}
{
"1234567890": "!@#$%^&*()"
}
{
"1": "2",
"3": "4"
}
{
"1": "2",
"3": {
"4": "5"
},
"6": "7"
}
{
"^_^": "^_^",
"^_^.": {
"^_^": {
"^_^": {
"^_^": "^_^"
}
}
},
".^_^": "^_^"
}
输入格式:
输入为一行一个没有空格的JSON对象字符串,保证数据合法
数据范围:
输入字符串的长度不超过2000
输出按照题目要求格式化后的JSON字符串
例如:
{"^_^":"^_^","^_^.":{"^_^":{"^_^":{"^_^":"^_^"}}},".^_^":"^_^"}
↓
{
"^_^": "^_^",
"^_^.": {
"^_^": {
"^_^": {
"^_^": "^_^"
}
}
},
".^_^": "^_^"
}
再例如:
{"LetMeFly":{"Tisfy":"^_^"},"BeCarefulOfMe:":"TheCharacter'{'IsFake"}
↓
{
"LetMeFly": {
"Tisfy": "^_^"
},
"BeCarefulOfMe:": "TheCharacter'{'IsFake"
}
再例如:
{"1":"2","3":{"4":"5"},"6":"7"}
↓
{
"1": "2",
"3": {
"4": "5"
},
"6": "7"
}
再例如:
{"1":{"2":{"3":{"4":{"5":"6"}}}}}
↓
{
"1": {
"2": {
"3": {
"4": {
"5": "6"
}
}
}
}
}
再例如:
{"1":{"2":{"3":{"4":"5"}}},"6":"7"}
↓
{
"1": {
"2": {
"3": {
"4": "5"
}
}
},
"6": "7"
}
再例如:
{"1":"2","3":{"4":"5"}}
↓
{
"1": "2",
"3": {
"4": "5"
}
}
再例如:
{"1":{}}
↓
{
"1": {
}
}
{"LetMeFly":{"Tisfy":"^_^"},"BeCarefulOfMe:":"TheCharacter'{'IsFake"}
{
"LetMeFly": {
"Tisfy": "^_^"
},
"BeCarefulOfMe:": "TheCharacter'{'IsFake"
}
这道题我觉得题目描述已经很详细了(自夸一波)
题目中已经把所有可能出现的情况全部讲出来了,以及可能出现的“坑”等都在样例中出现过。
因此,我觉得这道题主要在考察细心程度(读题明规则)以及编码能力(规则变实际)
这道题的解题思路就是“按照规则分析并格式化字符串”
其实也就两大需要处理的东西:
那么,不如把这些交给两个函数:
string formatJSON()用来处理JSON对象的左右大括号string formatKeyValPair()用来处理JSON对象中的数个键值对为了方便,我们使用两个变量:
nowIndent用来记录当前处理过程中应有的缩进(键值对全面有几个空格)nowTo用来记录处理到了字符串的哪个字符(值为下一个该处理的字符的下标)实现formatJSON()时:
首先第一个字符一定是左大括号{
处理完大括号就该处理键值对了,直接丢给formatKeyValPair()函数来处理。
等formatKeyValPair()函数处理完后,下一个字符一定是右大括号}
这样,formatJSON()的使命就这么轻松愉快地完成了。
至于缩进,处理完左大括号后,缩进+4。
等formatKeyValPair()函数处理完键值对后,再把缩进-4即可。
接下来的问题就只剩下“如何处理数个键值对”了
实现formatKeyValPair()时:
因为键值对的数量不确定,因此这个函数的终止条件是:遇到右终止大括号}
这里需要特别注意的是,“遇到右终止大括号}”是指遇到“非字符串中的}字符”,也不是某个键值对的“JSON对象”的值的右大括号。
在没有遇到右终止大括号的时候,首先会遇到一个字符串,然后会遇到“:”
之后得看下一个字符是“{”还是“"”。
{”说明“值”是“JSON对象”,那么直接丢给formatJSON()函数来处理"”说明“值”是“字符串”,那么就自己处理,直到找到下一个“"”为止伪代码为:
string formatKeyValPair() {
while (s[nowTo] != '}') {
处理左字符串
处理“:”
看“值”的第一个字母
如果是“"”,就值为“字符串”,直接遍历到下一个“"”为止
否则,就说明是JSON对象,丢给formatJSON()处理
}
}
处理完一个键值对后,如果下一个字符是“}”,就说明已无下一个键值对。
否则说明还有下一个键值对,记得输出逗号再换行。
代码去掉注释也就100行,还行还行
#include
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
class JSONFormatter {
private:
string s;
int nowIndent; // 现在已有的缩进量
int onceIndent; // 每次缩进4个空格
int nowTo; // 现在处理到了哪个下标
/*
格式化JSON对象
如题,JSON对象的左大括号无需考虑4个空格的缩进问题,而右大括号需要考虑缩进问题
也就是说,先输出左大括号,再增加缩进。等输出完所有键值对后,先减少缩进,再输出右括号
管辖范围:“{”到与之匹配的“}”
*/
string formatJSON() {
string formatted = "{\n";
nowTo++;
nowIndent += onceIndent;
formatted += formatKeyValPair();
nowIndent -= onceIndent;
formatted += nSpaces(nowIndent);
formatted += "}";
nowTo++; // }
return formatted;
}
/*
格式化键值对
*/
string formatKeyValPair() {
string formatted;
while (s[nowTo] != '}') {
formatted += nSpaces(nowIndent);
formatted += '"';
nowTo++;
// 寻找 “":”
while (s[nowTo] != '"') {
formatted += s[nowTo++];
}
formatted += "\": ";
nowTo += 2; // "、:
// 处理值
if (s[nowTo] == '"') { // 键值是字符串
formatted += '"';
nowTo++;
while (s[nowTo] != '"') {
formatted += s[nowTo++];
}
formatted += '"';
nowTo++; // "
}
else { // 键值是JSON对象
formatted += formatJSON();
}
// 看是否有下一个键值对
if (s[nowTo] == '}') {
formatted += '\n';
}
else {
formatted += ",\n";
nowTo++; // ,
}
}
return formatted;
}
/*
返回n个空格
*/
string nSpaces(int n) {
return string(n, ' ');
}
public:
JSONFormatter(string s) : s(s) {
nowIndent = 0;
onceIndent = 4;
nowTo = 0;
};
string format() {
return formatJSON();
}
};
int main() {
string s;
cin >> s;
JSONFormatter formatter(s);
cout << formatter.format();
return 0;
}
点关注,不迷路
题解.md文件写了500多行呜呜呜
原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/126473189