【问题标题】:Count occurrences of elements inside array? (Java)计算数组中元素的出现次数? (爪哇)
【发布时间】:2014-01-20 07:27:53
【问题描述】:

我一直在努力尝试找出这个算法大约 6 个小时,但似乎无法提出解决方案。我正在尝试计算数组中元素的出现次数,并且可能还有两个单独的数组。一个用于唯一实例,一个用于这些实例发生的次数。我在这里发现了一些关于数组列表和 hashMaps 的其他想法,但我只能使用数组。

例如,我有这个数组(已经排序):

{cats, cats, cats, dog, dog, fish}

我正在尝试为实例创建一个数组,所以:

{cats, dog, fish}

最后,这些实例发生了多少次:

{3, 2, 1}

这是我到目前为止的代码:

public void findArrs( String[] words )
{
  int counter = 1;
  for(int i = 0; i < words.length - 1; i++){
  if(!(words[i].equals(words[i+1]))){
  counter++; 
  }
 }

 String[] unique = new String[counter];
 int[] times = new int[counter];

 for(int i = 0; i < words.length; i++){

   }    
}

这是我所有尝试后的所有代码。

【问题讨论】:

  • 使用两个 for 循环,首先复制您的对象。第一个循环,获取名字,在内部循环中,计算出现次数。并推送到新数组。继续前进,直到完成所有不同的值
  • 我做了一个贯穿分类数组的 for 外观,当它切换到不同的东西时,我增加了一个计数器,最后这就是唯一数组和实例数组的长度。但是我被困在如何将排序数组的元素移动到这两个中。
  • 我刚刚用我的代码编辑了帖子。

标签: java arrays elements find-occurrences


【解决方案1】:

这就是只使用数组的方式。棘手的部分是您必须在创建数组之前知道项目的数量。所以我必须创建自己的函数来创建更大的数组。实际上是两个,一个用于计数,一个用于唯一值。

如果你可以使用向量,你会更好。这是没有投票者的:

public class HelloWorld{

     public static void main(String []args){
        String[] initalArray;

        // allocates memory for 10 integers
        initalArray = new String[6];
        initalArray[0] = "cats";
        initalArray[1] = "cats";
        initalArray[2] = "cats";
        initalArray[3] = "dog";
        initalArray[4] = "dog";
        initalArray[5] = "fish";

        String[] uniqueValues = new String[0];
        int[] countValues = new int[0];
        for(int i = 0; i < initalArray.length; i++)
        {
            boolean isNewValue = true;
            for (int j = 0; j < uniqueValues.length; j++)
            {
                if (uniqueValues[j] == initalArray[i])
                {
                    isNewValue = false;
                    countValues[j]++;
                }
            }

            if (isNewValue)
            {
                // We have a new value!
                uniqueValues = addToArrayString(uniqueValues, initalArray[i]);
                countValues = addToArrayInt(countValues, 1);
            }
        }

        System.out.println("Results:");
        for(int i = 0; i < countValues.length; i++)
        {
            System.out.println(uniqueValues[i] + "=" +  countValues[i]);
        }
     }

     public static String[] addToArrayString(String[] initalArray, String newValue)
     {
         String[] returnArray = new String[initalArray.length+1];
         for(int i = 0; i < initalArray.length; i++)
         {
             returnArray[i] = initalArray[i];
         }
         returnArray[returnArray.length-1] = newValue;

         return returnArray;
     }

     public static int[] addToArrayInt(int[] initalArray, int newValue)
     {
         int[] returnArray = new int[initalArray.length+1];
         for(int i = 0; i < initalArray.length; i++)
         {
             returnArray[i] = initalArray[i];
         }
         returnArray[returnArray.length-1] = newValue;

         return returnArray;
     }
}

如cmets中所说,如果我们知道数组是有序的,那么我们不需要搜索整个前面的数组,直接检查uniqueValues即可。

public class HelloWorld{

     public static void main(String []args){
        String[] initalArray;

        // allocates memory for 10 integers
        initalArray = new String[6];
        initalArray[0] = "cats";
        initalArray[1] = "cats";
        initalArray[2] = "cats";
        initalArray[3] = "dog";
        initalArray[4] = "dog";
        initalArray[5] = "fish";

        String[] uniqueValues = new String[0];
        int[] countValues = new int[0];
        for(int i = 0; i < initalArray.length; i++)
        {
            boolean isNewValue = true;
            if (i > 0)
            {
                if (uniqueValues[uniqueValues.length-1] == initalArray[i])
                {
                    isNewValue = false;
                    countValues[uniqueValues.length-1]++;
                }
            }

            if (isNewValue)
            {
                // We have a new value!
                uniqueValues = addToArrayString(uniqueValues, initalArray[i]);
                countValues = addToArrayInt(countValues, 1);
            }
        }

        System.out.println("Results:");
        for(int i = 0; i < countValues.length; i++)
        {
            System.out.println(uniqueValues[i] + "=" +  countValues[i]);
        }
     }

     public static String[] addToArrayString(String[] initalArray, String newValue)
     {
         String[] returnArray = new String[initalArray.length+1];
         for(int i = 0; i < initalArray.length; i++)
         {
             returnArray[i] = initalArray[i];
         }
         returnArray[returnArray.length-1] = newValue;

         return returnArray;
     }

     public static int[] addToArrayInt(int[] initalArray, int newValue)
     {
         int[] returnArray = new int[initalArray.length+1];
         for(int i = 0; i < initalArray.length; i++)
         {
             returnArray[i] = initalArray[i];
         }
         returnArray[returnArray.length-1] = newValue;

         return returnArray;
     }
}

【讨论】:

  • 你可以使用List&lt;String&gt;(),添加你想要的,之后你可以调用stringlist.toArray()
  • 是的,但是 OP 在评论中说“我只能使用数组和循环”,所以我在回答中只使用了数组和循环,但建议他们改用 Vectors,Lists不过可能会更好(自从我用 java 编程以来已经有一段时间了 - 当时不存在泛型)。
  • 代码没有(ab)使用输入数组排序的属性。 ;)
  • @mrjink - 好收获!添加了一个假设数组已排序的版本。也可以更轻松地计算唯一值,但我把它作为练习留给读者......已经很晚了:)
【解决方案2】:

将唯一的时间作为实例变量,以便您可以使用 getter 方法从另一个类中检索它们。

注意:修改后的代码可以通过 cmets 找到(对于“添加的行”行。对于“添加的代码从这里开始”到“添加的代码在这里结束”之间的块)。我试图用代码解释实现。如果我需要更多地提高我的文档技能,请通过 cmets 告诉我

public class someClass(){
  private String[] unique;
  private int[] times;
  //Added code starts here
  public String[] getUnique(){
    return this.unique;
  }

  public int[] getTimes(){
    return this.times;
  }
  //Added code ends here
  //Below implementation would work as intended only when words array is sorted
  public void findArrs( String[] words ) 
  {
    int counter = 1;
    for(int i = 0; i < words.length - 1; i++){
        if(!(words[i].equals(words[i+1]))){
            counter++; 
        }
    }

    unique = new String[counter];
    times = new int[counter];
    //Added line.
    unique[0] = words[0];  
    for(int i=0,j=0; i < words.length&&j < counter; i++){
   //Added code starts here
       if(!(unique[j].equals(words[i]))){
            j++; //increment count when latest element in unique array is not equal to latest element in words array
            unique[j] = words[i]; //add newly found unique word from words array to unique array
            times[j] = 1; //make the count to 1 for first non repeated unique word

        }
        else{

            times[j]++; //increment the count every time the string repeats
        }
   //Added code ends here
   }    
  }
}

【讨论】:

    【解决方案3】:

    假设words数组至少有一个元素:

    int numberOfDifferentWords = 1;
    String firstWord = words[0];
    for(int i = 0; i < words.length; i++) {
        if(!firstWord.equals(words[i])) {
            numberOfDifferentWords++;
        }
    }
    
    // These two arrays will contain the results. 
    String[] wordResultArray = new String[numberOfDiffentWords];
    int[] countResultArray = new int[numberOfDiffentWords];
    
    // This will mark where we should put the next result
    int resultArrayIndex = 0;
    
    String currentWord = firstWord;
    int currentWordCount = 0;
    for(int i = 0; i < words.length; i++) {
        //if we're still on the same word, increment the current word counter
        if(currentWord.equals(words[i])) {
            currentWordCount++;
        }
        //otherwise, transition to a new word
        else {
            wordResultArray[resultArrayIndex] = currentWord;
            wordCountArray[resultArrayIndex] = currentWordCount;
            resultArrayIndex++;
    
            currentWord = words[i];
            currentWordCount = 1;
        }
    }
    

    正如其他答案所提到的,可以通过使用诸如 ArrayList 之类的 List 来存储结果来简化此问题。

    【讨论】:

    • 到目前为止,这段代码看起来不错。但是我们想要将 wordResultArray 和 countResultArray 限制为出现次数。和上面的例子一样,它以数组长度 6 开头,但它需要数组长度为 3。
    • 刚刚在开头添加了一段代码来解决这个问题。不过,它确实涉及到对 words 数组进行一次额外的迭代。
    • 抱歉,我又查看了您的代码。你能解释一下为什么会有 currentWord = words[i];当前字数 = 1;在 for 循环的末尾?此外,如果你在 for 中有一个 if。是否在满足条件后跳出 if 语句然后进入 for 循环然后重新启动?
    • 每当我们转换到原始数组中的新单词时都会遇到代码“currentWord = words[i]; currentWordCount = 1;”——当当前单词 (words[i]) 已经转换时例如,从“猫”到“狗”。它在结果数组中保存“cats”和“3”,然后将当前单词设置为“dog”和“1”,因为这是第一个被计数的“dog”。
    • 您的第二个问题涉及已更改的部分(您可以在此处查看旧版本:stackoverflow.com/posts/21229050/revisions)。 for 循环中的 if 旨在运行一次 - for 循环将一直运行,直到找到尚未填充的数组元素。一旦我找到一个空数组索引,我就给它赋值,然后使用“break”关键字,它基本上说“采用最近的 for 循环并停止迭代它”。
    【解决方案4】:

    您可以使用 TreeMap 来实现它:

    public class NumberOfOccurences {
    
        public static void main(String[] args) {
            String[] testArr = {"cats", "cats", "cats", "dog", "dog", "fish"};
            String output = countNumberOfChild(testArr);
    
            System.out.println(output);
    
        }
    
    
        public static String countNumberOfChild(String[] list){
            Arrays.sort(list);
    
            TreeMap<String,Integer> noOfOccurences = new TreeMap<String,Integer>();
    
    
            for(int i=0;i<list.length;i++){
                if(noOfOccurences.containsKey(list[i])){
                    noOfOccurences.put(list[i], noOfOccurences.get(list[i])+1);
                }
                else{
                    noOfOccurences.put(list[i], 1);
                }
            }
    
            String outputString = null;
            while(!noOfOccurences.isEmpty()){
                String key = noOfOccurences.firstKey();
                Integer value = noOfOccurences.firstEntry().getValue();
                if(outputString==null){
                    outputString = key+"="+value;
                }
                else{
                    outputString = outputString + ";" + key+"="+value;
                }
                noOfOccurences.remove(key);
            }
    
            return outputString;
        }
    }
    

    【讨论】:

      【解决方案5】:

      如果你使用 ArrayList 会很简单。但既然你特别想要数组,这是我的代码。

      int lth = words.length;
      // Specify a broad length
      String[] unique = new String[lth];
      int[] times = new int[lth];
      
      int i = 0;
      int j = 0;
      int count;
      while (i < lth) {
          String w = words[i];
          count = 1;
          while(++i < lth && words[i].equals(w)) ++count;
          unique[j] = w;
          times[j++] = count;
      }
      
      // Reduce the length of the arrays    
      unique = Arrays.copyOf(unique, j);
      times  = Arrays.copyOf(times, j);     
      
      for (i = 0; i < unique.length;++i)
          System.out.println(unique[i] + " " + times[i]);
      

      如您所见,真正的问题是您必须在使用它们之前指定数组的长度。有了 ArrayLists,您就不必这样做了。 此外,由于对项目进行排序,因此更喜欢使用 while 循环而不是 for 循环。只是看起来不错。

      【讨论】:

        【解决方案6】:

        String s[] = {"Arranged", "Administered", "Advised", "Administered", "Adapted"}; //存储预定数量的单词

        String k="I have administered and advised him to stay away."; //一个你想要匹配的字符串,如果它包含那些单词

        String ka[]=k.split("\\s");//在每个空格出现时拆分字符串,以便提取每个单词

        for(i=0;i&lt;ka.length;i++)

        {for(j=0;j&lt;s.length;j++){

        if(ka[i].equalsIgnoreCase(s[j]))

        {System.out.println("The occurred words are:" +s[j]);

        continue;//继续用于查找是否出现了多于一个单词

        }

        }

        }

        【讨论】:

          【解决方案7】:

          这是简单的 JavaScript:

          var myarray = {"cats", "cats", "cats", "dog", "dog", "fish"};
          var values = [];
          var instanceCount = []
          for(var i = 0; i < myarray.length; i++){
              var value = myarray[i];
              var counter = 0;
              for(var j = 0; j < myarray.length; j++){
                  if(firstVal == myarray[j]) counter++;
              }
              //Build your arrays with the values you asked for
              values.push(value);
              instanceCount.push(counter);
          
              //Remove All occurences further in the array
              var idx = myarray.indexOf(value);
              while (idx != -1) {
                  myarray.splice(idx, 1);
                  idx = array.indexOf(myarray, idx + 1);
              }
          }
          
          //Handle Result here
          

          【讨论】:

          • 我用 java 编码而不是 javascript。不过谢谢
          • 对不起 :) 但也许这可以让你知道你能做什么
          • 是的。我对 java 很陌生,实际上对编码很陌生,所以大多数其他代码和东西对我来说很难分解。
          • 如果你可以在你的java中使用ArrayLists,这也可以通过简单的方式来完成
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-30
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-16
          相关资源
          最近更新 更多