简体   繁体   中英

finding out the divisors of a number

What is the most optimized approach of finding out the number of divisors of a number,such that the divisors have at least the digit 3 in it?

eg 21=1,3,7,21

therefore only one divisor has the digit 3 in it.

eg 62=1,2,31,62

therefore only one divisor has the digit 3 in it and ie 31

EDIT-i realized that the best way to do this woulds be to find out all the factors of a number and check for the factors containing the digit 3.

the best way to find out the factors :

Getting Factors of a Number

What is the best way to get all the divisors of a number?

Here is an expansion on my take. It first checks if there is a possible factor in the list div3 . If not, it adds candidates up to number /2, skipping values that already could be factored according to this list, so '37' and '43' get added, but not '36' or '39'.

The above part should be considered "setup". If you know the input constraints (a maximum input value), you can calculate the vector div3 once, then store it inside the program.

If the list div3 is up to date, the input should be factored into one of these numbers. If it can't then none of its factors contain a '3'. If it can , this shows the remainder, which can be factored further using conventional methods.

I consider this "optimized" because the constraint "any factor should contain a '3'" is checked first. Only if any valid factor is found, you need to calculate all the others.

My first program using <vector> and its ilk, so be gentle in your comments :-)

(Edit) I now notice the factor checking loop goes over the entire div3 vector. Of course, it only needs to go up to number/2 . Left as an exercise to the reader.

(Additional edit) find3 is here a reverse iterator. For some reason that seemed appropriate, but I can't recall why I thought so :) If checking up to and including number/2 , you need to change it to a regular forward iterator.

#include <iostream>
#include <vector>

using namespace std;

int contains_3 (int value)
{
    while (value && (value % 10) != 3)
        value /= 10;
    return value;
}

int main (int argc, char **argv)
{
    int number, found_flag, last_div3, adjust, adjust_digit;
    vector<int> div3;
    vector<int>::reverse_iterator find3;
    vector<int>::iterator it;

    // a little seeding
    div3.push_back(3);
    div3.push_back(13);
    div3.push_back(23);

    if (argc != 2)
        return -1;

    number = atoi (argv[1]);
    found_flag = 0;

    // do we need to expand div3?
    last_div3 = div3.back();

    while (last_div3 * 2 < number)
    {
    //  if this number contains a '3' in any other place than the last,
    //  simply increment it
        if ((last_div3 % 10) != 9 && contains_3(last_div3/10))
        {
            last_div3++;
        } else
        {
            // no? then simply pick the next multiple of 10 and add 3
            last_div3 /= 10;
            last_div3++;
            last_div3 *= 10;
            if (!contains_3(last_div3))
                last_div3 += 3;
        }
    //  check if it should be in the list
        for (it = div3.begin() ; it != div3.end() && (last_div3 % *it); ++it) ;
        if (it == div3.end())
        {
            div3.push_back(last_div3);
        }
    }

    cout << "list is now: ";
    for (it = div3.begin() ; it != div3.end(); ++it)
        cout << ' ' << *it;
    cout << endl;

    for (find3 = div3.rbegin(); !found_flag && find3 != div3.rend(); find3++)
    {
        if (!(number % *find3))
        {
            cout << "candidate: " << *find3 << ", remaining to sieve: " << number/(*find3) << endl;

            found_flag++;
        }
    }

    if (!found_flag)
        cout << "None found" << endl;

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM