【问题标题】:Check whether occurrence of individual digit in a number is same or not检查数字中单个数字的出现是否相同
【发布时间】:2017-05-09 06:00:25
【问题描述】:

我们需要检查一个数字中单个数字的出现是否相同。例如对于 2244(2 出现 2 次,4 出现 2 次)。因此,两个数字的出现是相同的。

//This will return true if occurrence of individual digit in
//a number is same else false

bool stable(int no)
{
    vector<int> v1;
    int k , count = 1;
    int arr[10];
    //Initializing all arr[] -> 0
    for(int k = 0 ; k < 10 ;k++)
    {
        arr[k] = 0;
    }
    while(no != 0)
    {
        k=no%10;
        arr[k]++;
        no=no/10;
    }
    for(int i = 0 ; i < 10 ; i++)
    {
        if(arr[i] != 0)
        {
            v1.push_back(arr[i]);  //storing count of individual digits
        }
    }
    vector<int>::iterator it , it2;
    for(it = v1.begin()+1 ,it2 = v1.begin(); it != v1.end() ; it++,it2++)
    {
        if(*it == *it2) //if all the values are same return true else false
        {
            count++;
        }
    }
    if(count == v1.size()) return true;
        return false; 
}

但此代码不适用于 2222,1111,444。另外,您能推荐一些优化代码的好方法吗?

【问题讨论】:

  • 您的代码为 2222 返回 true,因为 2222 是稳定的(2 是唯一出现 4 的数字),您的代码似乎是正确的。
  • Shubh,您能解释一下如何代码不适用于这些数字吗?有没有调试过?
  • Thanx @RajeevSingh ,实际上在我的机器上执行此操作我设置了 count = 0 那就是我遇到了一个错误。

标签: c++ find-occurrences


【解决方案1】:

我认为您让这件事变得比需要的更难(或者我严重误解了这个问题,这种情况经常发生)。

假设是指定的要求:给定一个非零的正值,如果所有数字以相同的频率出现,包括 1,则一个数字是合格的(例如:1122、2222、1234 都是合格的,因为没有数字更高频率高于任何其他)。

算法很简单:

  1. 任何小于 10 的值快速返回;单个数字立即被限定。
  2. 构建模数残差的计数器数组。
  3. 在数组中查找第一个非零值
  4. 从那时起,找到第一个与 (4) 中的值不匹配的非零值。如果您到达序列的末尾而没有发现这样的差异,则原始数字中的所有数字必须具有相同的计数。

总之,复杂度是输入数字的以 10 为底的对数加上恒定大小数组(10 个元素)的单遍扫描。

示例代码

#include <algorithm>
#include <iterator>

bool stable(unsigned value)
{
    if (value < 10) // single digit only, including zero
        return true;

    unsigned ar[10]={0};
    do { ++ar[value%10]; } 
    while (value /= 10);

    auto it = std::find_if(std::begin(ar), std::end(ar),
                            [](auto n) { return n != 0; });
    return std::find_if(std::next(it), std::end(ar),
                        [it](auto n){ return n && (n != *it);}) == std::end(ar);
}

您始终可以通过保留最大位数并在最终为 1 时不使用查找操作来进一步实现这一点(例如:1234、102938 就是这样的例子)。我将把它作为一个练习留给您进行基准测试,以确定是否有任何性能优势。老实说,我怀疑会有。

【讨论】:

    【解决方案2】:

    试试这个:

    bool stable(int no)
    {
        std::vector<int> v1;
    
        while (no != 0){
            v1.push_back(no%10);
            no /= 10;
        }
    
        std::sort(v1.begin(), v1.end()); //SORTING DIGITS IN ASCENDING ORDER
    
        std::vector<int> index = {0};  //BUILDING VEC WITH INDEXES WHERE CHANGES HAPPEN
        for (unsigned int i = 0; i < v1.size()-1; ++i){
            if (v1[i] != v1[i+1])
                index.push_back(i+1);
        }
        //EDGE CASE WHEN ONLY 1 DIGIT APPEARS (e.g. 555)
        if (index.size() == 1)
            return true;
    
        //CHECKING THAT ALL INDEXES ARE EQUALLY SEPARATED
        int diff = index[1] - index[0];
        for (unsigned int i = 1; i < index.size()-1; ++i){
            if (index[i+1] - index[i] != diff)
                return false;
        }
        return true;
    }
    

    【讨论】:

      【解决方案3】:

      在检查所有重复计数是否相同时,如果计数不匹配,您可以直接返回false,无需进一步检查。如果向量只包含一个计数,例如2222, 1111,它将返回true

      vector<int>::iterator it , it2;
      for(it = v1.begin()+1 ,it2 = v1.begin(); it != v1.end() ; it++,it2++)
      {
          if(*it != *it2) //if two values are not same return false
          {
              return false;
          }
      }
      return true; 
      

      【讨论】:

        猜你喜欢
        • 2021-06-21
        • 1970-01-01
        • 1970-01-01
        • 2018-01-15
        • 1970-01-01
        • 1970-01-01
        • 2021-07-22
        • 1970-01-01
        • 2013-08-16
        相关资源
        最近更新 更多