Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/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_Loops - Fatal编程技术网

Java 如何计算唯一的;“模式”;从一个数组?

Java 如何计算唯一的;“模式”;从一个数组?,java,loops,Java,Loops,我的任务是找到给定数组的模式(未指定长度)。模式定义为最唯一出现的数字。例如,数组[1.0,2.0,3.0,2.0]的模式是2.0。但是,如果该值没有唯一的数字,例如[1.0、2.0、2.0、3.0、3.0],则程序在我的程序中返回“no mode”或“Double.NaN” 我已经编写了适用于3/4测试用例的代码,但在捕获两种模式相同的情况时总是会出错 public double mode() { double modeOne = data[0]; double modeTw

我的任务是找到给定数组的模式(未指定长度)。模式定义为最唯一出现的数字。例如,数组[1.0,2.0,3.0,2.0]的模式是2.0。但是,如果该值没有唯一的数字,例如[1.0、2.0、2.0、3.0、3.0],则程序在我的程序中返回“no mode”或“Double.NaN”

我已经编写了适用于3/4测试用例的代码,但在捕获两种模式相同的情况时总是会出错

public double mode() {

    double modeOne = data[0];
    double modeTwo = 0;
    int count = 0;
    int countOne = 0;
    int countTwo = 0;

    if(data.length == 1) { // special case: if array length is 1 the mode will always just be that value
        modeOne = data[0];
        return modeOne;
    } // end if

    for(int i = 0; i < data.length; i++) { // pulling out first value
        double value = data[i];
        for(int n = 0; n < data.length; n++) { // comparing first value to all other values
            if (data[n] == value) {
                count ++; // adding onto a count of how many of the same number there are
            }
        }
        if(modeOne == value || modeTwo == value) { // move on if the modes already have that value
            continue;
        }
        if(count > countOne) { // setting the max count
            countTwo = countOne;
            countOne = count;
            modeTwo = modeOne;
            modeOne = value;
        }
        else if(count > countTwo) { // setting second highest count
            countTwo = count;
            modeTwo = value;
        }
    } // end for
    if(countOne == 1) { // if all the modes are just one
        return Double.NaN;
    }
    if(countOne == countTwo) { // if there are two of the same modes
        return Double.NaN;
    }
    else {
        return modeOne;
    }
} //end MODE
我期望“NaN”,但它返回4。但是,它适用于以下情况:

double[] data = {-5.3, 2.5, 88.9, 0, 0.0, 28, 16.5, 88.9, 109.5, -90, 88.9};
Stat stat1 = new Stat(data);
System.out.println("stat1 mode = " + stat1.mode());

预期输出为88.9,程序正确输出。

因为我有心情接受一个小挑战,所以我确实编写了自己的解决方案,使用映射来计算各个值

然后检索可用的最高计数,并再次迭代映射以确定多个条目是否具有相同的最高计数,如果是,则返回NaN

public static double calculateMode(double[] numbers) {
    Map<Double, Integer> lookupMap = new TreeMap<>();

    for (double number : numbers) {
        if (lookupMap.get(number) != null) {
            lookupMap.put(number, lookupMap.get(number) + 1);
        } else {
            lookupMap.put(number, 1);
        }
    }

    int max = -1;
    double maxKey = Double.NaN;
    for (Entry<Double, Integer> entry : lookupMap.entrySet()) {
        if (entry.getValue() > max) {
            max = entry.getValue();
            maxKey = entry.getKey();
        }
    }

    int foundMax = 0;

    for (Entry<Double, Integer> entry : lookupMap.entrySet()) {
        if (entry.getValue() == max) {
            foundMax++;
        }
    }

    if (foundMax > 1) {
        return Double.NaN;
    }

    return maxKey;

}
产出:

Expected NaN - and was: NaN
Expected 88.90 - and was: 88.9

没有
收藏
等。。。纯硬编程:)

公共双模式(双[]数据)
{
if(data.length==1)
返回数据[0];
双温;
double[]fr=新的double[data.length];//存储频率
int=-1;
对于(int i=0;i
因此,我也感到了挑战,并在不使用
集合的情况下找到了解决方案。
这不是一个很好的解决方案,但似乎有效:

public class TestMode
{
  private static class NumberFrequency
  {
    double number;
    int    frequency;
  }

  public static double calculateMode(double[] numbers)
  {
    // Maybe array empty
    if ((numbers == null) || (numbers.length == 0))
      return Double.NaN;

    // Initialize array with frequencies
    NumberFrequency[] array;
    int               size = 0;
    array = new NumberFrequency[numbers.length];

    // Loop over numbers determining frequencies
    for (double number : numbers)
    {
      // Maybe encountered before
      int index;
      for (index = 0; index < size; index++)
      {
        if (array[index].number == number)
          break;
      }

      // Update array
      NumberFrequency elm;
      if (index == size)
      {
        elm = new NumberFrequency();
        elm.number = number;
        elm.frequency = 0;
        array[index] = elm;
        size++;
      }
      else
        elm = array[index];
      elm.frequency += 1;

    } // for all numbers

    // Initialize element with highest frequency
    int index_highest;
    int highest_freq;
    int nr_occurs;
    index_highest = 0;
    highest_freq = array[0].frequency;
    nr_occurs = 1;

    // Search 'better' element
    int counter;
    for (counter = 1; counter < size; counter++)
    {
      if (array[counter].frequency > highest_freq)
      {
        index_highest = counter;
        highest_freq = array[counter].frequency;
        nr_occurs = 1;
      }
      else if (array[counter].frequency == highest_freq)
        nr_occurs++;
    }

    // Return result
    if (nr_occurs == 1)
      return array[index_highest].number;
    else
      return Double.NaN;

  } // calculateMode

  public static void main(String[] args)
  {
    double[] data = {1, 2, 2, 3, 3, 4};
    double[] data2 = {-5.3, 2.5, 88.9, 0, 0.0, 28, 16.5, 88.9, 109.5, -90, 88.9};
    System.out.println("Expected NaN - and was: " + calculateMode(data));
    System.out.println("Expected 88.90 - and was: " + calculateMode(data2));  }

} // class TestMode
公共类测试模式
{
专用静态类号频率
{
双数;
整数频率;
}
公共静态双计算器模式(双[]个数字)
{
//也许数组是空的
if((numbers==null)| |(numbers.length==0))
返回Double.NaN;
//使用频率初始化阵列
NumberFrequency[]阵列;
int size=0;
数组=新的NumberFrequency[numbers.length];
//环路数决定频率
用于(双倍数字:数字)
{
//可能以前遇到过
整数指数;
对于(索引=0;索引最高频率)
{
指数=计数器;
最高频率=阵列[计数器]。频率;
nr_=1;
}
else if(数组[计数器]。频率==最高频率)
nr_++;
}
//返回结果
如果(nr_发生==1)
返回数组[index_highest].number;
其他的
返回Double.NaN;
}//计算模式
公共静态void main(字符串[]args)
{
双[]数据={1,2,2,3,3,4};
双[]数据2={-5.3,2.5,88.9,0,0.0,28,16.5,88.9,109.5,-90,88.9};
System.out.println(“预期的NaN-和was:+calculateMode(数据));
System.out.println(“预期为88.90-was:+calculateMode(data2));}
}//类TestMode

添加一个备选方案,因为我也感到了挑战:

总体思路是在上面给出的示例之前生成一个频率阵列

 [1.0, 2.0, 2.0, 3.0, 3.0]
 [1,    2,   2,   2,   2]  
指示相同索引的元素在输入中的次数,然后在频率数组中查找最大值,最后检查具有相同频率的所有值是否相等

public static double mode(double [] data) {  
   if(data == null || data.length < 1){
       return Double.NaN;
   }      
   int [] freq = new int [data.length]; 
   for(int i = 0; i<data.length; i++){
        for(int j = 0; j<data.length; j++){
            if(data[i]==data[j]){
                freq[i]++;
            }
        }
    }
    int max = 0;
    double mode = data[0];
    for(int i = 0; i<freq.length; i++){
        if(freq[i]>max){
            max = freq[i];
            mode = data[i];
        }
    }
    for(int i = 0; i<freq.length; i++){
        if(freq[i] == max){
            if(mode != data[i]){
               return Double.NaN;
            }
        }
    }
    return mode;
} 
公共静态双模式(双[]数据){
if(data==null | | data.length<1){
返回Double.NaN;
}      
int[]freq=新的int[data.length];

对于(inti=0;i,这里是一个使用流式API的方法。但是,我采用了模式的定义,它是一个集合而不是一个数字

import org.junit.Test;

import java.util.Arrays;
import java.util.Map;
import java.util.OptionalLong;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

public class ModeTest {

    private <T extends Number> Set<T> modes(T... input) {
        return modes(Arrays.stream(input));
    }

    /**
     * Calculate the modes of a numeric stream.  The modes are the values that occurs most often. If no number in the
     * stream is repeated, then all the numbers in the stream are modes.
     *
     * @param input stream of numbers
     * @param <T>   number type
     * @return modes.
     */
    private <T extends Number> Set<T> modes(Stream<T> input) {

        // transform the input to a map containing the counted entries
        final Set<Map.Entry<T, Long>> countedEntries = input
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet();

        // Figure out the max value
        final OptionalLong max = countedEntries
            .parallelStream()
            .mapToLong(Map.Entry::getValue)
            .max();

        // Handle the case where the stream was empty
        if (max.isEmpty()) {
            return Set.of();
        }

        return countedEntries
            .parallelStream()
            .filter(e -> e.getValue() == max.getAsLong())
            .map(Map.Entry::getKey)
            .collect(Collectors.toSet());

    }

    @Test
    public void oneMode() {
        final Double[] input = new Double[]{1.0, 1.1, 1.2, 2.0, 2.0, 3.0};
        assertEquals(modes(input), Set.of(2.0));
    }

    @Test
    public void multipleModes() {
        final Stream<Double> input = Stream.of(1.0, 1.1, 1.2, 2.0, 2.0, 3.0, 3.0);
        assertEquals(modes(input), Set.of(2.0, 3.0));
    }

    @Test
    public void allSingles() {
        final Stream<Double> input = Stream.of(1.0, 1.1, 1.2, 2.0, 3.0);
        assertEquals(modes(input), Set.of(1.0, 1.1, 1.2, 2.0, 3.0));
    }

    @Test
    public void largeRandomSet() {
        Integer[] randoms = new Integer[204800];
        for (int i = randoms.length - 1; i >= 0; --i) {
            randoms[i] = ThreadLocalRandom.current().nextInt(200);
        }
        assertFalse(modes(randoms).isEmpty());
    }

    @Test
    public void emptyStream() {
        final Stream<Double> input = Stream.of();
        assertEquals(modes(input), Set.of());
    }
}
import org.junit.Test;
导入java.util.array;
导入java.util.Map;
导入java.util.OptionalLong;
导入java.util.Set;
导入java.util.concurrent.ThreadLocalRandom;
导入java.util.function.function;
导入java.util.stream.collector;
导入java.util.stream.stream;
导入静态org.junit.Assert.assertEquals;
导入静态org.junit.Assert.assertFalse;
公共类模式测试{
专用设置模式(T…输入){
返回模式(数组、流(输入));
}
/**
*计算数字流的模式。模式是最常出现的值。如果
*流被重复,那么流中的所有数字都是模式。
*
*@param数字输入流
*@param编号类型
*@返回模式。
*/
专用设置模式(流输入){
//将输入转换为包含计数项的映射
最终设置countedEntries=输入
 [1.0, 2.0, 2.0, 3.0, 3.0]
 [1,    2,   2,   2,   2]  
public static double mode(double [] data) {  
   if(data == null || data.length < 1){
       return Double.NaN;
   }      
   int [] freq = new int [data.length]; 
   for(int i = 0; i<data.length; i++){
        for(int j = 0; j<data.length; j++){
            if(data[i]==data[j]){
                freq[i]++;
            }
        }
    }
    int max = 0;
    double mode = data[0];
    for(int i = 0; i<freq.length; i++){
        if(freq[i]>max){
            max = freq[i];
            mode = data[i];
        }
    }
    for(int i = 0; i<freq.length; i++){
        if(freq[i] == max){
            if(mode != data[i]){
               return Double.NaN;
            }
        }
    }
    return mode;
} 
import org.junit.Test;

import java.util.Arrays;
import java.util.Map;
import java.util.OptionalLong;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

public class ModeTest {

    private <T extends Number> Set<T> modes(T... input) {
        return modes(Arrays.stream(input));
    }

    /**
     * Calculate the modes of a numeric stream.  The modes are the values that occurs most often. If no number in the
     * stream is repeated, then all the numbers in the stream are modes.
     *
     * @param input stream of numbers
     * @param <T>   number type
     * @return modes.
     */
    private <T extends Number> Set<T> modes(Stream<T> input) {

        // transform the input to a map containing the counted entries
        final Set<Map.Entry<T, Long>> countedEntries = input
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet();

        // Figure out the max value
        final OptionalLong max = countedEntries
            .parallelStream()
            .mapToLong(Map.Entry::getValue)
            .max();

        // Handle the case where the stream was empty
        if (max.isEmpty()) {
            return Set.of();
        }

        return countedEntries
            .parallelStream()
            .filter(e -> e.getValue() == max.getAsLong())
            .map(Map.Entry::getKey)
            .collect(Collectors.toSet());

    }

    @Test
    public void oneMode() {
        final Double[] input = new Double[]{1.0, 1.1, 1.2, 2.0, 2.0, 3.0};
        assertEquals(modes(input), Set.of(2.0));
    }

    @Test
    public void multipleModes() {
        final Stream<Double> input = Stream.of(1.0, 1.1, 1.2, 2.0, 2.0, 3.0, 3.0);
        assertEquals(modes(input), Set.of(2.0, 3.0));
    }

    @Test
    public void allSingles() {
        final Stream<Double> input = Stream.of(1.0, 1.1, 1.2, 2.0, 3.0);
        assertEquals(modes(input), Set.of(1.0, 1.1, 1.2, 2.0, 3.0));
    }

    @Test
    public void largeRandomSet() {
        Integer[] randoms = new Integer[204800];
        for (int i = randoms.length - 1; i >= 0; --i) {
            randoms[i] = ThreadLocalRandom.current().nextInt(200);
        }
        assertFalse(modes(randoms).isEmpty());
    }

    @Test
    public void emptyStream() {
        final Stream<Double> input = Stream.of();
        assertEquals(modes(input), Set.of());
    }
}