英文:
Finding the depth of a JSON String in JAVA
问题
我在Java方法中获得了一个字符串,必须返回该字符串的嵌套深度。
就像方法是这样的:
findDepthJSON(String s){
//代码
return count;
}
例如:
{
"0" : { "name" : "John", "City" : "NY"},
"1" : { "name" : "Mike", "City" : "LA"}
}
对于这个输入,深度为2。
英文:
I was given a String in java method and have to return the son depth of that string
like if the method is
find depthJSON(String s){
//code
return count;
}
for example:
{
"0" : { "name" : "John", "City" : "NY"},
"1" : { "name" : "Mike", "City" : "LA"}
}
for this input, depth is 2
答案1
得分: 1
您的问题需要一个JSON分词器。实际上,您不需要对文件进行解析(即构建某些树状结构作为Java对象),因为您只关心仅可以从令牌流中推导出的最大嵌套深度。
基本思想是跟踪表示对象开始和结束的令牌({
,}
),每当分词器看到对象的开始/结束时,增加/减少全局深度计数器;每当分词器看到对象结束时,检查当前的全局深度计数器是否大于迄今为止所见的最大值,并相应地更改该值。
作为提供JSON分词器的包,我建议使用 Jackson。将jar文件下载到您的源目录(或适当的开发工具集目录中)。以下是jar文件的下载链接:
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.3/jackson-core-2.10.3.jar
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.3/jackson-annotations-2.10.3.jar
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.3/jackson-databind-2.10.3.jar
请注意,您需要所有这些文件,并且不要忘记修改Java CLASSPATH,除非您的IDE会处理这一点。
以下是相关的代码部分:
import java.lang.*;
import java.io.*;
import java.nio.*;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
public class json_nesting {
public static void main(String[] args) {
// write your code here
// Second: read file back
String fpath = "<file path goes here>"; // 在Windows上使用双反斜杠!
ObjectMapper mapper = new ObjectMapper(); // 创建一次,重复使用
JsonFactory f = mapper.getFactory();
try {
JsonParser p = f.createParser(new File(fpath));
JsonToken t = p.nextToken();
int currentDepth = 0;
int maxDepth = 0;
while (t != null) {
if (t == JsonToken.START_OBJECT) {
currentDepth++;
} else {
if (t == JsonToken.END_OBJECT) {
if (currentDepth > maxDepth) {
maxDepth = currentDepth;
}
currentDepth--;
}
}
t = p.nextToken();
}
System.out.printf("Max depth = %4d.\n", maxDepth);
p.close();
} catch (IOException ioe) {
System.out.printf("File processing failed: = '%s'. Message: %s.\n", fpath, ioe.getMessage());
}
}
}
在Java SE 11、u 28版本下进行了测试。
注意(JSON语法):
请注意,您的示例文件不是有效的JSON - 某些属性名称未用双引号括起来,属性未用逗号分隔。以下是经过修正的版本:
{
"0" : { "name" : "John", "City" : "NY"},
"1" : { "name" : "Mike", "City" : "LA"}
}
英文:
Your problem calls for a JSON Tokenizer. You do not actually need to parse your file ( ie. build some tree structure as a Java object ) as you are only interested in the maximal nesting depth which can be deduced from the token stream alone.
The basic idea is to keep tabs on the tokens that represent the start and end of an object ( {
, }
). Whenever the tokenizer sees an object start/end, increment/decrement a global depth counter; Whenever the tokenizer sees an object end, check whether the current global depth counter is greater than the maximum seen so far and change the value accordingly.
As a package to furnish the JSON Tokenizer, I'd suggest Jackson. Download the jar files into your source directory (or to the suitable place in your development toolset directory). The jar files are available at:
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.3/jackson-core-2.10.3.jar
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.3/jackson-annotations-2.10.3.jar
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.3/jackson-databind-2.10.3.jar
Note that you need all of them and do not forget to alter the Java CLASSPATH unless your IDE takes care of that.
Code
The following class determines and prints the depth of your json:
// https://stackoverflow.com/questions/61097605/finding-the-depth-of-a-json-string-in-java
//
// javac.exe -cp "./jackson-core-2.10.3.jar;./jackson-annotations-2.10.3.jar;./jackson-databind-2.10.3.jar" .\json_nesting.java
// java.exe -cp "./jackson-core-2.10.3.jar;./jackson-annotations-2.10.3.jar;./jackson-databind-2.10.3.jar;." json_nesting
//
// Cf. https://github.com/FasterXML/jackson-databind#5-minute-tutorial-streaming-parser-generator
//
// Jar downloads
// https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.3/jackson-core-2.10.3.jar
// https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.3/jackson-annotations-2.10.3.jar
// https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.3/jackson-databind-2.10.3.jar
//
import java.lang.*;
import java.io.*;
import java.nio.*;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
public class json_nesting {
public static void main(String[] args) {
// write your code here
// Second: read file back
String fpath = "<file path goes here>"; // Double backslashes on Windows !
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
JsonFactory f = mapper.getFactory();
try {
JsonParser p = f.createParser(new File(fpath));
JsonToken t = p.nextToken();
int currentDepth = 0;
int maxDepth = 0;
while (t != null) {
if (t == JsonToken.START_OBJECT) {
currentDepth++;
} else {
if (t == JsonToken.END_OBJECT) {
if (currentDepth > maxDepth) {
maxDepth = currentDepth;
}
currentDepth--;
}
}
t = p.nextToken();
};
System.out.printf("Max depth = %4d.\n", maxDepth);
p.close();
} catch ( IOException ioe ) {
System.out.printf("File processing failed: = '%s'. Message: %s.\n", fpath, ioe.getMessage());
}
}
}
Tested with Java SE 11, u 28.
Note (JSON syntax)
Note that your sample file is NOT valid JSON - some property names are not enclosed in double quotes, properties are not separated with commas. A rectified version comes here:
{
"0" : { "name" : "John", "City" : "NY"}
, "1" : { "name" : "Mike", "City" : "LA"}
}
答案2
得分: 0
public static int levelCount(String word) {
int current = 0;
int max = 0;
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == '{') {
current++;
} else {
if (word.charAt(i) == '}') {
if (current > max) {
max = current;
}
current--;
}
}
}
return max;
}
英文:
public static int levelCount(String word) {
int current= 0;
int max = 0;
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == '{') {
current++;
} else {
if (word.charAt(i) == '}') {
if (current > max) {
max = current;
}
current--;
}
}
}
return max;
}
答案3
得分: -1
int JsonDepth(String S) {
int current_max = 0;
int max = 0;
int n = S.length();
for (int i = 0; i < n; i++) {
if (S.charAt(i) == '{') {
current_max++;
// update max if required
if (current_max > max) {
max = current_max;
}
} else if (S.charAt(i) == '}') {
if (current_max > 0) {
current_max--;
} else {
return -1;
}
}
}
if (current_max != 0) {
return -1;
}
return max;
}
英文:
my answer is
int JsonDepth (String S) {
int current_max = 0;
int max = 0;
int n = S.length();
for (int i = 0; i < n; i++) {
if (S.charAt(i) == '{') {
current_max++;
// update max if required
if (current_max > max) {
max = current_max;
}
} else if (S.charAt(i) == '}') {
if (current_max > 0) {
current_max--;
} else {
return -1;
}
}
}
if (current_max != 0) {
return -1;
}
return max;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论