检查数字中个别数字的出现是否相同

时间:2017-05-09 06:00:25

标签: c++ find-occurrences

  

我们需要检查一个数字中单个数字的出现是否相同。例如,对于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没有用。另外,您会建议一些优化代码的好方法吗?

3 个答案:

答案 0 :(得分:1)

试试这个:

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;
}

答案 1 :(得分:1)

我认为你正在努力实现这一目标(或者我严重误解了这个经常发生的问题)。

假设是要求是指定的:给定非零正值,如果所有数字以相等的频率出现,则数字是合格的,包括1(例如:1122,2222,1234全部符合条件,因为没有数字有更高的数字频率比任何其他)。

算法很简单:

  1. 任何小于10的值的快速返回;一位数字立即合格。
  2. 构建模数残差的计数器数组。
  3. 查找数组中的第一个非零值
  4. 从那时起,找到与(4)中的值不匹配的第一个非零值。如果到达序列的末尾而没有发现这种差异,则原始编号中的所有数字必须具有相同的计数。
  5. 在所有复杂性中,对数基数为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 :(得分:0)

在检查所有重复计数是否相同时,如果计数不匹配,您可以直接返回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;