Java 如何返回二维字符串
我不完全理解如何返回2D对象。所以我写了一个方法,它接受一个文档的输入,我必须返回一个列表,其中包含所有唯一的单词及其出现次数,按出现次数降序排序。这是一个要求,我无法控制它是否作为字符串的二维数组返回 以下是我到目前为止的情况:Java 如何返回二维字符串,java,sorting,multidimensional-array,hashmap,Java,Sorting,Multidimensional Array,Hashmap,我不完全理解如何返回2D对象。所以我写了一个方法,它接受一个文档的输入,我必须返回一个列表,其中包含所有唯一的单词及其出现次数,按出现次数降序排序。这是一个要求,我无法控制它是否作为字符串的二维数组返回 以下是我到目前为止的情况: static String[][] wordCountEngine(String document) { // your code goes here if (document == null || document.length() == 0)
static String[][] wordCountEngine(String document) {
// your code goes here
if (document == null || document.length() == 0)
return null;
Map<String, String> map = new HashMap<>();
String[] allWords = document.toLowerCase().split("[^a-zA-Z]+");
for (String s : allWords) {
if (map.containsKey(s)) {
int newVersion = (Integer.parseInt(map.get(s).substring(1, map.get(s).length())) + 1);
String sb = Integer.toString(newVersion);
map.put(s, sb);
} else {
map.put(s, "1");
}
}
String[][] array = new String[map.size()][2];
int count = 0;
for (Map.Entry<String, String> entry : map.entrySet()) {
array[count][0] = entry.getKey();
array[count][1] = entry.getValue();
count++;
}
return array;
}
输出应为:
output: [ ["practice", "3"], ["perfect", "2"],
["by", "1"], ["get", "1"], ["just", "1"],
["makes", "1"], ["only", "1"], ["youll", "1"] ]
如何将这样的数据存储在二维数组中?
String[][]
对于此任务来说是错误的数据结构。
在方法运行期间,您应该使用映射
而不是
,只需准确返回该映射即可
这有多种原因:
- 您将整数存储为字符串,甚至通过再次将字符串解析为整数来执行计算,计算然后再解析回来——这是个坏主意
- 返回的数组不保证维度,无法强制每个子数组正好有两个元素
关于您的评论,请注意:如果(出于某种原因)您需要将映射转换为
字符串[][]
,您当然可以这样做,但转换逻辑应该与生成映射的代码本身分离。这样,wordCountEngine
的代码保持干净,易于维护 仅仅因为需要返回特定类型的数据结构,并不意味着需要在方法中创建类似类型的映射。没有任何东西阻止您使用映射
,然后将其转换为字符串[]【】
:
以下是不使用Java8 Streems的代码:
static String[][] wordCountEngine(String document) {
// your code goes here
if (document == null || document.length() == 0)
return null;
Map<String, Integer> map = new HashMap<>();
for ( String s : document.toLowerCase().split("[^a-zA-Z]+") ){
Integer c = map.get(s);
map.put(s, c != null ? c + 1: 1);
}
String[][] result = new String[ map.size() ][ 2 ];
int count = 0;
for ( Map.Entry<String, Integer> e : map.entrySet() ){
result[count][0] = e.getKey();
result[count][1] = e.getValue().toString();
count += 1;
}
return result;
}
这是我对普拉普问题的解决方案,尽管在C#中,我认为这是相同的想法
[TestMethod]
public void PrampWordCountEngineTest()
{
string document = "Practice makes perfect. you'll only get Perfect by practice. just practice!";
string[,] result = WordCountEngine(document);
string[,] expected =
{
{"practice", "3"}, {"perfect", "2"},
{"makes", "1"}, {"youll", "1"}, {"only", "1"},
{"get", "1"}, {"by", "1"}, {"just", "1"}
};
CollectionAssert.AreEqual(expected,result);
}
public string[,] WordCountEngine(string document)
{
Dictionary<string, int> wordMap = new Dictionary<string, int>();
string[] wordList = document.Split(' ');
int largestCount = 0;
foreach (string word in wordList)
{
string lowerWord = word.ToLower(); // can't assing to the same variable
//remove special/punctuation characters
var sb = new StringBuilder();
foreach (var c in lowerWord)
{
if (c >= 'a' && c <= 'z')
{
sb.Append(c);
}
}
string cleanWord = sb.ToString();
if (cleanWord.Length < 1)
{
continue;
}
int count = 0;
if (wordMap.ContainsKey(cleanWord))
{
count = wordMap[cleanWord];
count++;
}
else
{
count = 1;
}
if (count > largestCount)
{
largestCount = count;
}
wordMap[cleanWord] = count;
}
// we have a list of all of the words in the same length in a given cell of the big list
List<List<string>> counterList = new List<List<string>>();
for (int i = 0; i < largestCount + 1; i++)
{
counterList.Add(new List<string>());
}
foreach (var word in wordMap.Keys)
{
int counter = wordMap[word];
counterList[counter].Add(word);
}
string[,] result = new string[wordMap.Keys.Count,2];
int key = 0;
//foreach list of words with the same length we insert the count of that word into the 2D array
for (var index = counterList.Count-1; index > 0; index--)
{
var list = counterList[index];
List<string> wordListCounter = list;
if (wordListCounter == null)
{
continue;
}
foreach (var word in wordListCounter)
{
result[key, 0] = word;
result[key, 1] = index.ToString();
key++;
}
}
return result;
}
[TestMethod]
public void PrampWordCountEngineTest()
{
string document=“熟能生巧。你只有通过练习才能变得完美。只要练习!”;
字符串[,]结果=WordCountEngine(文档);
应为字符串[,]=
{
{“练习”,“3”},{“完美”,“2”},
{“makes”,“1”},{“youll”,“1”},{“only”,“1”},
{“get”,“1”},{“by”,“1”},{“just”,“1”}
};
集合资产等于(预期结果);
}
公共字符串[,]WordCountEngine(字符串文档)
{
Dictionary wordMap=新字典();
string[]wordList=document.Split(“”);
int最大计数=0;
foreach(单词列表中的字符串单词)
{
string lowerWord=word.ToLower();//不能分配到同一个变量
//删除特殊/标点符号
var sb=新的StringBuilder();
foreach(lowerWord中的变量c)
{
如果(c>='a'&&c最大计数)
{
最大计数=计数;
}
wordMap[cleanWord]=计数;
}
//我们有一个大列表中给定单元格中相同长度的所有单词的列表
列表计数器列表=新列表();
对于(int i=0;i0;索引--)
{
var列表=计数器列表[索引];
List wordListCounter=List;
if(wordListCounter==null)
{
继续;
}
foreach(wordListCounter中的var字)
{
结果[键,0]=字;
结果[key,1]=index.ToString();
key++;
}
}
返回结果;
}
这是一个糟糕的主意,因为你使用字符串来表示数字数据。为什么不简单地返回一个映射
或创建一个保存字符串和int值的自定义类型?@hovercraftfullofels是的,我想你是对的。我最好创建自己的数据类型来存储值。这是一个编码挑战,所以我必须返回一个字符串[][]不是我的选择。无论如何,谢谢。嗯,我不同意他们的要求。“这是一个编码挑战,所以我必须返回字符串[][]。不是我的选择。”编码挑战不是学习Java的最佳方式。你最好先阅读官方教程:@TimothyTruckle谢谢,我会记住这一点。过度使用字符串来表示非文本数据是一种设计气味。这是合适的解决方案。这是一个编码挑战,他们想要一个字符串[][]作为返回值。但无论如何,谢谢。@RockySingh我添加了一条关于这种情况的注释。@luk2302谢谢。
static String[][] wordCountEngine(String document) {
// your code goes here
if (document == null || document.length() == 0)
return null;
return Arrays
//convert words into map with word and count
.stream( document.toLowerCase().split("[^a-zA-Z]+") )
.collect( Collectors.groupingBy( s -> s, Collectors.summingInt(s -> 1) ) )
//convert the above map to String[][]
.entrySet()
.stream().map( (e) -> new String[]{ e.getKey(), e.getValue().toString() } )
.toArray( String[][]::new );
}
[TestMethod]
public void PrampWordCountEngineTest()
{
string document = "Practice makes perfect. you'll only get Perfect by practice. just practice!";
string[,] result = WordCountEngine(document);
string[,] expected =
{
{"practice", "3"}, {"perfect", "2"},
{"makes", "1"}, {"youll", "1"}, {"only", "1"},
{"get", "1"}, {"by", "1"}, {"just", "1"}
};
CollectionAssert.AreEqual(expected,result);
}
public string[,] WordCountEngine(string document)
{
Dictionary<string, int> wordMap = new Dictionary<string, int>();
string[] wordList = document.Split(' ');
int largestCount = 0;
foreach (string word in wordList)
{
string lowerWord = word.ToLower(); // can't assing to the same variable
//remove special/punctuation characters
var sb = new StringBuilder();
foreach (var c in lowerWord)
{
if (c >= 'a' && c <= 'z')
{
sb.Append(c);
}
}
string cleanWord = sb.ToString();
if (cleanWord.Length < 1)
{
continue;
}
int count = 0;
if (wordMap.ContainsKey(cleanWord))
{
count = wordMap[cleanWord];
count++;
}
else
{
count = 1;
}
if (count > largestCount)
{
largestCount = count;
}
wordMap[cleanWord] = count;
}
// we have a list of all of the words in the same length in a given cell of the big list
List<List<string>> counterList = new List<List<string>>();
for (int i = 0; i < largestCount + 1; i++)
{
counterList.Add(new List<string>());
}
foreach (var word in wordMap.Keys)
{
int counter = wordMap[word];
counterList[counter].Add(word);
}
string[,] result = new string[wordMap.Keys.Count,2];
int key = 0;
//foreach list of words with the same length we insert the count of that word into the 2D array
for (var index = counterList.Count-1; index > 0; index--)
{
var list = counterList[index];
List<string> wordListCounter = list;
if (wordListCounter == null)
{
continue;
}
foreach (var word in wordListCounter)
{
result[key, 0] = word;
result[key, 1] = index.ToString();
key++;
}
}
return result;
}