С++ сравнивает два числа по их цифрам

Я хочу создать функцию, которая возвращает true всякий раз, когда два введенных числа состоят из одних и тех же цифр (без замены).

Например, 543 и 435 должны возвращать истину, 10001 и 11000 должны возвращать истину, а 111222 и 122222 должны возвращать ложь.

Я что-то читал о битовых масках, но не совсем понял, не могли бы вы мне помочь?


person placeholder    schedule 18.10.2018    source источник
comment
Вы можете подсчитать, сколько раз каждая цифра встречается в числах, или вы можете попробовать отсортировать цифры, а затем сравнить значения.   -  person François Andrieux    schedule 18.10.2018
comment
Если вы используете x % 10, это дает вам нижнюю цифру. Если вы используете x / 10, он удаляет нижнюю цифру. Затем вы можете подсчитать или отсортировать цифры в каждом числе и сравнить.   -  person Martin York    schedule 18.10.2018
comment
Преобразуйте числа в std::string и используйте std::map‹char,int› или просто массив int[10];   -  person drescherjm    schedule 18.10.2018
comment
Я кое-что читал о битовых масках, но не совсем понял Это не вариант использования битовых масок. Они используются совсем для других целей. Что вы пытались? Можно разбить число на цифры, поставить их на std::map, а затем сравнить карты.   -  person Algirdas Preidžius    schedule 18.10.2018
comment
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что не было предпринято попыток решить проблему. Так что, если не писать ответ, который не поможет будущему пользователю, мы не можем сделать ничего, кроме комментария.   -  person Martin York    schedule 18.10.2018
comment
Хорошо, у меня уже есть идея, как это сделать. Спасибо!   -  person placeholder    schedule 18.10.2018


Ответы (2)


Я думаю, что самый простой способ справиться с этим - использовать ведра. Создайте std::vector длины 10 (по одному для каждой цифры), а затем увеличивайте индекс всякий раз, когда вы сталкиваетесь с соответствующей цифрой. Закончите сравнением векторов:

bool compare_digits(int x, int y) {
    std::vector<int> x_vec(10), y_vec(10);
    while(x != 0) { //!= instead of > so that we can handle negatives
        x_vec.at(x%10)++; //increment whatever digit is in the 1's place
        x /= 10; //chop off the 1's place digit
    }

    while(y != 0) { //repeat for y
        y_vec.at(y%10)++;
        y /= 10;
    }

    //check if they had the same digits
    return (x_vec == y_vec);
}
person scohe001    schedule 18.10.2018
comment
Я не думаю, что необходимо использовать проверку привязки для операции по модулю. И если вы не хотите создавать отдельную функцию, просто используйте лямбду, повторение кода является источником проблем. - person Slava; 18.10.2018
comment
@Слава Я предполагаю, что когда вы говорите о проверке границ, вы ссылаетесь на мое использование .at() вместо оператора нижнего индекса? Я не думаю, что это действительно повлияет на время выполнения здесь, и, вероятно, это хорошая привычка для начинающего программиста на C++, поэтому я не думаю, что изменю ее. Что ты говоришь, что я должен лямбда? - person scohe001; 18.10.2018
comment
это наверное хорошая привычка я так не думаю, это противоречит одному из основных принципов C++ я не должен платить за то, чем не пользуюсь. И для лямбда я имею в виду дублирующийся код преобразования int в вектор - person Slava; 18.10.2018
comment
@Слава, это страховка. Можете использовать, можете нет. И вы не узнаете, нужно ли вам его использовать, пока оно вам действительно не понадобится. А к тому времени уже слишком поздно. Я бы предпочел сделать все мои индексы .at() за мизерную цену времени выполнения за один раз, когда это сэкономит мне 5 часов отладки. - person scohe001; 18.10.2018

Два числа a состоят из одинаковых цифр, если количество (количество вхождений) каждой цифры одинаково. Вот некоторый код для общей базы (параметр шаблона)

template<int base=10>
bool compare_digits(int x, int y)
{
    // 0 exclude trivial cases
    if(x > base*y || y > base*x)
        return false;
    // 1 count occurrences of digits in x
    int count[base]={0};
    for(; x; x/=base)
        ++ count[x%base];
    // 2 subtract counts of digits in y, if result < 0: return false
    for(; y; y/=base)
        if(--count[y%base] < 0)
            return false;
    // 3 check that count[]==0
    for(int i=0; i!=base; ++i)
        if(count[i]) return false;
    return true;
}
person Walter    schedule 06.11.2018