【问题标题】:Finding multiple modes in an array of integers with 1000 elements在具有 1000 个元素的整数数组中查找多种模式
【发布时间】:2014-01-16 14:07:40
【问题描述】:

所以我需要一种方法来在 1000 个元素的数组中找到模式,每个元素使用从 0 到 300 的 math.Random() 随机生成。

int[] nums = new int[1000];

    for(int counter = 0; counter < nums.length; counter++)
        nums[counter] = (int)(Math.random()*300);

int maxKey = 0;
    int maxCounts = 0;

    sortData(array);
    int[] counts = new int[301];

    for (int i = 0; i < array.length; i++)
    {
        counts[array[i]]++;
        if (maxCounts < counts[array[i]]) 
        {
            maxCounts = counts[array[i]];
            maxKey = array[i];
        }
    }

这是我目前的方法,它给了我出现次数最多的数字,但如果事实证明其他事情发生的次数相同,它只输出一个数字并忽略其余的数字。

我们不允许使用 ARRAYLIST 或 HASHMAP(老师禁止使用)

请帮助我了解如何修改此代码以生成包含随机数组中所有模式的数组输出。

谢谢你们!

编辑:

谢谢你们,我明白了:

private static String calcMode(int[] array)
{
    int[] counts = new int[array.length];
    for (int i = 0; i < array.length; i++) {
        counts[array[i]]++;
    }
    int max = counts[0];
    for (int counter = 1; counter < counts.length; counter++) {
        if (counts[counter] > max) {
            max = counts[counter];
        }
    }

    int[] modes = new int[array.length];

    int j = 0;
    for (int i = 0; i < counts.length; i++) {
        if (counts[i] == max)
            modes[j++] = array[i];
    }

    toString(modes);
    return "";
}

public static void toString(int[] array)
{
    System.out.print("{");
    for(int element: array)
    {
        if(element > 0)
            System.out.print(element + " ");
    }
    System.out.print("}");
}

【问题讨论】:

  • 模式是指在一组中出现次数最多的东西。例如,给定集合 {1,1,1,1,1,1,2,3},1 将是模式,因为它出现的次数最多。
  • 提示:你已经计算了maxCounts;现在编写第二个循环,通过counts
  • @ajb 这将如何工作?即使我运行了第二个循环,第三种模式呢?第四?
  • 老师有没有说过使用SET数据结构? TreeSet 可用于简洁的解决方案。
  • @user3200640 你有一个counts 数组,你有maxCounts。如果counts[i] 等于maxCounts,对于任何i,那么您已经找到了一种模式。您将能够通过这种方式找到所有这些。在我看来,您的原始代码走在了正确的轨道上;看起来您的第二次尝试只是不必要地使事情复杂化。

标签: java arrays integer mode


【解决方案1】:

看看这个,没有经过全面测试。但我认为它实现了@ajb 所说的:

private static int[] computeModes(int[] array)
{
    int[] counts = new int[array.length];
    for (int i = 0; i < array.length; i++) {
        counts[array[i]]++;
    }
    int max = counts[0];
    for (int counter = 1; counter < counts.length; counter++) {
        if (counts[counter] > max) {
            max = counts[counter];
        }
    }

    int[] modes = new int[array.length];

    int j = 0;
    for (int i = 0; i < counts.length; i++) {
        if (counts[i] == max)
            modes[j++] = array[i];
    }

    return modes;
}

这将返回带有模式的数组int[]。它将包含很多0s,因为结果数组(modes[])必须使用与传递的数组相同的长度进行初始化。因为每个元素都可能只出现一次。

main 方法中调用它时:

public static void main(String args[])
{
    int[] nums = new int[300];

    for (int counter = 0; counter < nums.length; counter++)
        nums[counter] = (int) (Math.random() * 300);

    int[] modes = computeModes(nums);
    for (int i : modes)
        if (i != 0) // Discard 0's
            System.out.println(i);
}

【讨论】:

  • 输出为[I@798fd984
  • 查看编辑,您必须打印数组中的每个元素,而不是数组。
  • 没关系,我只需要使用自定义的 toString() 方法,它就可以工作。我会更新OP。谢谢!
【解决方案2】:

您的第一种方法很有希望,您可以将其扩展如下:

for (int i = 0; i < array.length; i++)
{
    counts[array[i]]++;
    if (maxCounts < counts[array[i]]) 
    {
        maxCounts = counts[array[i]];
        maxKey = array[i];
    }
}

// Now counts holds the number of occurrences of any number x in counts[x]
// We want to find all modes: all x such that counts[x] == maxCounts

// First, we have to determine how many modes there are
int nModes = 0;

for (int i = 0; i < counts.length; i++)
{
    // increase nModes if counts[i] == maxCounts
}

// Now we can create an array that has an entry for every mode:
int[] result = new int[nModes];

// And then fill it with all modes, e.g:
int modeCounter = 0;
for (int i = 0; i < counts.length; i++)
{
    // if this is a mode, set result[modeCounter] = i and increase modeCounter  
}

return result;

【讨论】:

    【解决方案3】:

    这使用了一个数组列表 但我想我还是应该回答这个问题,这样也许你可以使用我的思考过程并自己删除数组列表的用法。那,这可以帮助其他观众。

    这是我想出来的。我对此并没有真正的解释,但我不妨分享一下我的进步:

    方法接收一个 int 数组,并返回没有重复 int 的数组:

    public static int[] noDups(int[] myArray) 
    { 
        // create an Integer list for adding the unique numbers to
        List<Integer> list = new ArrayList<Integer>();
    
        list.add(myArray[0]); // first number in array will always be first
        // number in list (loop starts at second number)
    
        for (int i = 1; i < myArray.length; i++)
        {
            // if number in array after current number in array is different
            if (myArray[i] != myArray[i - 1]) 
                list.add(myArray[i]); // add it to the list
        }
    
        int[] returnArr = new int[list.size()]; // create the final return array
        int count = 0;
    
        for (int x : list) // for every Integer in the list of unique numbers
        {
            returnArr[count] = list.get(count); // add the list value to the array
            count++; // move to the next element in the list and array
        }
    
        return returnArr; // return the ordered, unique array
    }
    

    寻找模式的方法:

    public static String findMode(int[] intSet)
    {
        Arrays.sort(intSet); // needs to be sorted
    
        int[] noDupSet = noDups(intSet);
        int[] modePositions = new int[noDupSet.length];
    
        String modes = "modes: no modes."; boolean isMode = false;
    
        int pos = 0;
        for (int i = 0; i < intSet.length-1; i++)
        {
            if (intSet[i] != intSet[i + 1]) {
                modePositions[pos]++;
                pos++;
            }
            else {
                modePositions[pos]++;
            }
        }
        modePositions[pos]++;
    
        for (int modeNum = 0; modeNum < modePositions.length; modeNum++)
        {
            if (modePositions[modeNum] > 1 && modePositions[modeNum] != intSet.length)
                isMode = true;
        }
    
        List<Integer> MODES = new ArrayList<Integer>();
    
        int maxModePos = 0;
        if (isMode) {
            for (int i = 0; i< modePositions.length;i++)
            {
                if (modePositions[maxModePos] < modePositions[i]) {
                    maxModePos = i;
                }
            }
    
            MODES.add(maxModePos);
            for (int i = 0; i < modePositions.length;i++)
            {
                if (modePositions[i] == modePositions[maxModePos] && i != maxModePos)
                    MODES.add(i);
            }
    
            // THIS LIMITS THERE TO BE ONLY TWO MODES
            // TAKE THIS IF STATEMENT OUT IF YOU WANT MORE         
            if (MODES.size() > 2) {
                modes = "modes: no modes.";
            }
            else {
                modes = "mode(s): ";
                for (int m : MODES)
                {
                    modes += noDupSet[m] + ", ";
                }
            }
        }
        return modes.substring(0,modes.length() - 2);
    }
    

    测试方法:

    public static void main(String args[]) 
    {
        int[] set = {4, 4, 5, 4, 3, 3, 3};
        int[] set2 = {4, 4, 5, 4, 3, 3};
        System.out.println(findMode(set)); // mode(s): 3, 4
        System.out.println(findMode(set2)); // mode(s): 4
    }
    

    【讨论】:

    • 相信我,如果她允许我们使用arrayList,我的生活会轻松很多。谢谢你的回答。
    【解决方案4】:

    在构造模式数组的最后部分存在逻辑错误。原始代码为modes[j++] = array[i];。相反,它应该是modes[j++] = i。换句话说,我们需要将该数字添加到出现次数等于最大出现次数的模式中

    【讨论】:

      猜你喜欢
      • 2011-11-27
      • 2023-03-09
      • 2019-12-06
      • 1970-01-01
      • 2014-09-16
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 1970-01-01
      相关资源
      最近更新 更多