我必须找到数组的模式。我有点尴尬地承认我已经坚持了一天。我想我已经考虑了一下-我的方法越来越长。我一直遇到的真正问题是,当没有一个模式(两个数字以相同的频率出现)时,我需要返回Double.NaN。
这是我尝试过的:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
if(data.length != 0){
double maxValue = -1;
int maxCount = 0;
for(int i = 0; i < data.length; i++) {
int count = 0;
for(int j = 0; j < data.length; j++) {
if(data[j] == data[i]) {
count++;
}
}
if(count > maxCount) {
maxValue = (int) data[i];
maxCount = count;
}
}
return maxValue;
}else{
return Double.NaN;
}
这实际上返回了模式,但是不能处理两种模式。这是我最近的尝试,但只完成了一半:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
public void mode(){
int[] frequency = new int[data.length];
double[] vals = new double[data.length];
for(int i = 0; i < data.length; i++){
frequency[i] = occursNumberOfTimes(data[i]);
}
boolean uniform = false;
for(int g = 0; g < frequency.length && !uniform; g++){
if(frequency[0] != frequency[g]){
uniform = false;
}
int[] arr = new int[frequency.length-1];
for(int j = 1; j < frequency.length; j++){
if(frequency[j] > frequency[j-1]){
int mod = 0;
for(int k = 0; k < arr.length; k++){
if(k == j){
mod += 1;
arr[k] = frequency[k + mod];
}else{
arr[k] = frequency[k + mod];
}
}
}
}
frequency = arr;
}
}
private int occursNumberOfTimes(double value){
int count = 0;
for(int i = 0; i < data.length; i++){
if(data[i] == value){
count++;
}
}
return count;
}
我在第二次尝试中迷路了,我只是无法弄清如何处理多种模式。我已经写出了自己的想法,但我只是不知道该怎么做。 我无法使用Arrays类中的任何内容,这就是我迷路的原因。
答案 0 :(得分:1)
它必须高效吗?如果没有:
double maxValue = -1.0d;
int maxCount = 0;
for (int i = 0; i < data.length; ++i) {
int currentValue = data[i];
int currentCount = 1;
for (int j = i + 1; j < data.length; ++j) {
if (Math.abs(data[j] - currentValue) < epsilon) {
++currentCount;
}
}
if (currentCount > maxCount) {
maxCount = currentCount;
maxValue = currentValue;
} else if (currentCount == maxCount) {
maxValue = Double.NaN;
}
}
System.out.println("mode: " + maxValue);
答案 1 :(得分:0)
您可以按照注释中的建议跟踪两个最常见的元素,但是另一种方法是保留一个布尔标志,该布尔标志指示当前最常见的元素是否唯一。然后:
e
,请按当前方式获取其计数。e
,并将“唯一”标志设置为true
。false
。最后,如果“唯一”为true
,则返回模式,否则返回NaN
。
答案 2 :(得分:0)
这是我漫长而愚蠢的解决方案。有用!这是获取模式的一种非常round回的方式,但我很高兴它能起作用。我使用了从一些评论中得到的建议,并以不同的方式看待它。几个小时令人沮丧,但这是:
public double mode2(){
if(data.length != 0){
int[] counts = new int[data.length];
double[] vals = new double[data.length];
for(int l = 0; l < data.length; l++){
counts[l] = 1;
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((data[i] == data[j]) && (i != j)){
vals[i] = data[i];
counts[i] += 1;
}
}
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((vals[i] == vals[j]) && (i != j)){
vals[i] = 0;
counts[i] = 0;
}
}
}
int counter = 0;
for(int k = 0; k < data.length; k++){
if(counts[k] != 0){
counts[counter] = counts[k];
vals[counter] = vals[k];
counter++;
}
}
int[] compactCounts = new int[counter];
double[] compactVals = new double[counter];
for(int k = 0; k < counter; k++){
if(counts[k] != 0){
compactCounts[k] = counts[k];
compactVals[k] = vals[k];
}else{
break;
}
}
for(int g = 1; g < compactVals.length; g++){
if(compactCounts[g] > compactCounts[g-1]){
compactCounts[g-1] = 0;
compactVals[g-1] = 0;
}
}
for(int g = 0; g < compactVals.length-1; g++){
if(compactCounts[g] > compactCounts[g+1]){
compactCounts[g+1] = 0;
compactVals[g+1] = 0;
}
}
int counterTwo = 0;
for(int k = 0; k < compactCounts.length; k++){
if(compactCounts[k] != 0){
compactCounts[counterTwo] = compactCounts[k];
compactVals[counterTwo] = vals[k];
counterTwo++;
}
}
int[] compactCountsTwo = new int[counterTwo];
double[] compactValsTwo = new double[counterTwo];
for(int k = 0; k < counterTwo; k++){
if(counts[k] != 0){
compactCountsTwo[k] = compactCounts[k];
compactValsTwo[k] = compactVals[k];
}else{
break;
}
}
//now populated compactTwos
//We're now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
//now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
if(compactValsTwo.length > 1){
return Double.NaN;
}else{
return compactValsTwo[0];
}
}else{
System.out.println("ISSUE");
return Double.NaN;
}
}
public double[] doubleTruncator(double[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
double[] b = new double[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
public int[] intTruncator(int[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
int[] b = new int[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
非常感谢所有提供帮助的人。我知道这不是很好(肯定不如@Perdi Estaquel的回答),但是我很高兴能够做到这一点。