Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何返回二维字符串_Java_Sorting_Multidimensional Array_Hashmap - Fatal编程技术网

Java 如何返回二维字符串

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)

我不完全理解如何返回2D对象。所以我写了一个方法,它接受一个文档的输入,我必须返回一个列表,其中包含所有唯一的单词及其出现次数,按出现次数降序排序。这是一个要求,我无法控制它是否作为字符串的二维数组返回

以下是我到目前为止的情况:

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;
        }