0

Given a range of numbers between a and b, I need to find all numbers that have repeating digits. They don't have to be consecutive repeating digits- for example 121 would count as one of these numbers. I already coded the input of the vector list itself - I just don't know how to analyze the digits of each individual item in that vector.

#include <iostream> #include <vector> using namespace std; int main(){ //variables int a, b, i = 0; // a & b inputs, i for iterating //entering number range cout << "Enter the first number" << endl; cin >> a; cout << "Enter the second number" << endl; cin >> b; //making a vector to contain numbers between a and b vector<int> listofnums((b-a)+1); int initialvalue = a; while (i <= (b-a)) { listofnums[i] = initialvalue; initialvalue++; i++; } //printing the completed vector for ( const auto &item : listofnums ){ std::cout << item << ' '; } std::cout << '\n'; //analyzing the digits of each item in the vector //code for finding repeating digits here return 0; } 
2
  • Use a counting table and modulo div loop, similar to what you would do when converting bases. Commented Feb 2, 2020 at 19:16
  • Convert the numbers to strings. Easier to access the digits (as an array of characters). Commented Feb 2, 2020 at 20:55

3 Answers 3

1

You can get the value of the lowest (least significant) digit of a decimal number by taking the remainder after dividing it by 10; in C++ this is readily accomplished using the modulo operator (%). Thus, given a integer variable, a, with a value of 123, the statement int b = a % 10; will assign 3 to b.

Now, by running a loop in which we sequentially divide the 'test' number by 10 (until it reaches zero), we can get the values for each digit. If we keep an array of bool values, setting each one to true when we find a given digit, we can quickly detect a repeated digit.

Thus, this function will do the job:

bool HasRepeatDigit(int x) { bool hasDigit[10] = {false, false, false, false, false, false, false, false, false, false}; while (x > 0) { int digit = x % 10; if (hasDigit[digit]) return true; // We already have this digit! hasDigit[digit] = true; // Flag the digit we just found x /= 10; // Divide by 10, to move onto the next digit } return false; // If we get here, there is no repeat digit! } 

You can then call this function on each of your 'test' numbers in a second loop, adding those numbers that have repeated digits to a new vector:

vector<int> withRepeats; for (auto i : listofnums) { // Tests "i" for every element in listofnums if (HasRepeatDigit(i)) withRepeats.push_back(i); // Append this to the new vector } 

Feel free to ask for further explanation and/or clarification.

As an aside, you can reduce the code that fills your listofnums vector using the std::iota function (defined in the <numeric> header):

#include <numeric> //... std::iota(begin(listofnums), end(listofnums), a); 
Sign up to request clarification or add additional context in comments.

2 Comments

Would I have to put that within another loop to implement it for each value of my vector? (I'm sorry if these are simple questions - this is my second week of c++ class and the jump between the last assignment and this one is huge)
@SaraMillan You can test the numbers after you've added them to your first vector, as shown, or you could do it all in one loop - by testing each number before you add it to the 'answer' vector.
1

Here you are.

#include <iostream> #include <bitset> #include <tuple> #include <vector> #include <algorithm> bool duplicated_digits( int value ) { const int Base = 10; std::bitset<Base> b; bool is_duplicate = false; do { int digit = value % Base; if ( digit < 0 ) digit = -digit; b.flip( digit ); is_duplicate = not b.test( digit ); } while ( not is_duplicate && ( value /= Base ) != 0 ); return is_duplicate; } int main() { int a = 0, b = 0; std::cout << "Enter the first number: "; std::cin >> a; std::cout << "Enter the second number: "; std::cin >> b; std::tie( a, b ) = std::minmax( { a, b } ); std::vector<int> v; int current_value = a; do { if ( duplicated_digits( current_value ) ) v.push_back( current_value ); } while ( current_value++ != b ); if ( not v.empty() ) { std::cout << "There are the following numbers with duplicated digits " "in the range [ " << a << ", " << b << " ]\n"; for ( const auto &item : v ) { std::cout << item << ' '; } std::cout << '\n'; } else { std::cout << "There are no numbers with duplicated digits in the range [ " << a << ", " << b << " ]\n"; } return 0; } 

The program output might look for example the following way

Enter the first number: 50 Enter the second number: -50 There are the following numbers with duplicated digits in the range [ -50, 50 ] -44 -33 -22 -11 11 22 33 44 

Or another example of possible program output

Enter the first number: -100 Enter the second number: -130 There are the following numbers with duplicated digits in the range [ -130, -100 ] -122 -121 -119 -118 -117 -116 -115 -114 -113 -112 -111 -110 -101 -100 

Comments

0

There are one million solutions. Everybody can do, what he wants

The standard approach in C++ for these types of problem is to use a std::map as a counter. A std::map has an index operator. The index operator returns a reference to a value, if the key isexisting. If the key is not existing, it will create a new entry and then return a reference to the default initialized value.

We then increment the reference.

Before that, we convert the integer to a string and then work on the chararcters(digits). Counting is then as easy as:

for (const char& digit : numberAsString) counter[digit]++; 

We put all the operations into a function and can then use this in C++ algorithms.

Please see:

#include <iostream> #include <vector> #include <string> #include <map> #include <algorithm> #include <iterator> bool check(const int& i) { // Convert int to string std::string numberAsString{ std::to_string(i) }; // We will use a map as counter std::map<char, size_t> counter{}; // Count the digits for (const char& digit : numberAsString) counter[digit]++; // Search for a digit count > 1 bool result{}; for (const auto& [digit, count] : counter) if (count > 1) { result = true; break; }; return result; } using namespace std; int main() { //variables int a, b, i = 0; // a & b inputs, i for iterating //entering number range cout << "Enter the first number" << endl; cin >> a; cout << "Enter the second number" << endl; cin >> b; //making a vector to contain numbers between a and b vector<int> listofnums((b - a) + 1); int initialvalue = a; while (i <= (b - a)) { listofnums[i] = initialvalue; initialvalue++; i++; } //printing the completed vector for (const auto& item : listofnums) { std::cout << item << ' '; } cout << '\n'; //analyzing the digits of each item in the vector //code for finding repeating digits here // Example 1 // print out all values in the vector having this property cout << "\n\n Result:\n"; copy_if(listofnums.begin(), listofnums.end(), ostream_iterator<int>(cout,"\n"), check); // Example 2 // copy all thos values to a new vector vector<int> result; copy_if(listofnums.begin(), listofnums.end(), back_inserter(result), check); return 0; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.