1

我必须从一个 int 数组中找到最不常见的数字,我已经编写了代码,但它不能正常工作,

这是我的逻辑,1. 对数组进行排序 2. 更新最小公共计数器 3. 获取是否都是唯一的

和下面的代码,

static int min_loc ; //minimum value location 
static int min_cnt ;
int all_uniqFlag = true;

void leastCommon(int data[],int n)
{
   int rcount = 0; //Repeated number counter
   int mcount = n; // minimum repetetion counter;

   // The array is already sorted we need to only find the least common value. 
   for(int i = 0 ; i < n-1 ; i++)
   {  
      //Case A : 1 1 2 2 2 3 3 3 3 4 5 5 5 5 : result should be 4 
      //Case B : 1 2 3 4 5 6 7 (All unique number and common values so all values should be printed
      //                        and ) 
      //Case C : 1 1 2 2 3 3 4 4 (all numbers have same frequency so need to display all )
      cout << "data[i] : " << data[i] << " data[i+1] : " << data[i+1] <<  "i = " << i << endl;
      if(data[i] != data[i+1])
      {
         //mcount = 0;
         //min_loc = i; 
         //return;
      }
      if(data[i] == data[i+1])
      {
        all_uniqFlag = false;
        rcount++;
      }
      else if(rcount < mcount)
      {
         mcount = rcount;
         min_loc = i ;//data[i];
      }
   } 
   min_cnt = mcount;   
}

如评论中所述,只有案例 B 有效,案例 A 和 C 无效,您能帮我解决问题吗?

4

3 回答 3

1

您可以map为此使用 a:

#include <string>
#include <map>
#include <iostream>

typedef std::map<int, int> Counter;

void leastCommon(int data[],int n) {
    Counter counter;
    int min = n;
    for (int i = 0; i < n; i++)
        counter[data[i]]++;
    for (Counter::iterator it = counter.begin(); it != counter.end(); it++) {
        if (min > it->second) min = it->second;
    }   
    for (int i = 0; i < n; i++) {
        if (counter[data[i]] == min) {
            std::cout << data[i] << std::endl;
            counter[data[i]]++;
        }   
    }   
}

int main() {
    int data[] = {1, 1,3,4,4,2,4,3,2};
    leastCommon(data, 9); 
    return 0;
}
于 2014-04-24T02:55:52.950 回答
1
  • 浏览列表
  • 将列表中的每个元素与out数组中的最后一个元素进行比较
  • 如果元素匹配,则将其计数增加 1
  • 如果元素不匹配,则将新元素添加到out 数组中并递增index1

扫描完成后,out阵列将包含所有不同的元素out[][0]及其频率out[][1]

  • 扫描频率列表 ( out[][1]) 以找到最低频率
  • 最后再次扫描元素列表out[][0]并打印频率与最低频率匹配的元素

.

#include<stdio.h>
#include<stdlib.h>
#define N 8
int main()
{
    //int data[N]={1,2,3,4,5,6,7};
    int data[N]={1,1,2,2,3,3,4,4};
    //int data[N]={1,1,2,2,2,3,3,3,3,4,5,5,5,5};
    int out[N][2];
    int i=0,index=0;
    for(i=0;i<N;i++)
    {
        out[i][0]=0; 
        out[i][1]=0; 
    }
    out[0][0] = data[0];
    out[0][1]=1;
    for(i=1;i<N;i++)
    {
        if(data[i] != out[index][0])
        {
            index++;
            out[index][0] = data[i];
            out[index][1] = 1;
        }
        else
        {
            out[index][1]++;
        }
    }

    int min=65536;
    for(i=0;i<N;i++)
    {
        if(out[i][1] == 0)
        {
            break;
        }
        if(out[i][1] < min)
        {
            min = out[i][1];
        }
    }
    for(i=0;i<N;i++)
    {
        if(out[i][1] == min)
        {
            printf("%d\t",out[i][0]);
        }
    }
    printf("\n");
}
于 2014-04-24T02:58:32.140 回答
1

方法是——

  • 从排序后的数组中选择第一个元素,当它的连续元素相同时,将它们存储在 output[] 中,直到循环中断
  • 将元素的频率存储在 leastFrequency 中
  • 选择下一个元素,检查其连续元素并将它们存储在相同的输出[]中,直到循环中断
  • 用 minimumFrequency 检查这个频率
    • 如果相同,什么也不做(让这些添加到输出[]中)
    • 如果小于,则清除 output[] 并存储相同编号的元素。次
    • 如果更多,则在迭代此元素之前将有效输出 [] 长度更改为以前的长度
  • 类似地迭代所有不同的元素,最后从 output[] 中获得从 0 到有效长度的结果

    void leastCommon(int data[], int len) {
    
    if ( len > 0) {
        int output[] = new int[len];
        int outlen = 0; // stores the size of useful-output array
        int leastFrequency = len; // stores the lowest frequency of elements
    
        int i=0;
        int now = data[i];
        while (i < len) {
            int num = now;
            int count = 0;
            do {
                output[outlen] = now;
                outlen++;
                count++;
    
                if((++i == len)){
                    break;
                }
                now = data[i];
            } while (num == now);   // while now and next are same it adds them to output[] 
    
            if (i - count == 0) { // avoids copy of same values to output[] for 1st iteration
                leastFrequency = count;
            } else if (count < leastFrequency) {  // if count for the element is less than the current minimum then re-creates the output[]
                leastFrequency = count;
                output = new int[len];
                outlen = 0;
                for (; outlen < leastFrequency; outlen++) {    
                    output[outlen] = num;   // populates the output[] with lower frequent element, to its count 
                }
            } else if (count > leastFrequency) {
                outlen -= count;    // marks outlen to its same frequent numbers, i.e., discarding higher frequency values from output[]
            }
        }
        //for(int j = 0; j < outlen; j++) {
        // print output[] to console
        //}
      }
    }
    

请提出改进​​建议。

于 2014-04-24T18:14:31.257 回答