Home > Software design >  Comparing digits in number
Comparing digits in number

Time:11-02

Consistently comparing digits symmetrically to its middle digit. If first number is bigger than the last , first is wining and I have to display it else I display last and that keep until I reach middle digit(this is if I have odd number of digits), if digit don't have anything to be compared with it wins automatically.

For example number is 13257 the answer is 7 5 2.

Another one 583241 the answer is 5 8 3. For now I am only trying to catch when number of digits is odd. And got stuck.. This is my code. The problem is that this code don't display any numbers, but it compares them in the if statement(I checked while debugging).

#include <iostream>
using namespace std;
int countDigit(int n) {
    int count = 0;
    while (n != 0) {
        count  ;
        n /= 10;
    }
    return count;
}
int main() {
    int n;
    cin >> n;
    int middle;
    int count = countDigit(n);
    
    if (count % 2 == 0) {
        cout<<"No mid digit exsist!!";
    }
    else {
        int lastDigit = n % 10;

        middle = (count   1) / 2;

        for (int i = 0; i < middle; i  ) {

            for (int j = lastDigit; j<middle; j--) {
                if (i > j) {
                    cout << i <<' ';
                }
                else {
                    cout << j;
                }
            }
        }
    }

    return 0;
}

CodePudding user response:

An easier approach towards this, in my opinion, would be using strings. You can check the size of the string. If there are even number of characters, you can just compare the first half characters, with the last half. If there are odd numbers, then do the same just print the middle character.

Here's what I'd do for odd number of digits:

string n;
cin>>n;
int i,j;
for(i=0,j=n.size()-1;i<n.size()/2,j>=(n.size() 1)/2;i  ,j--)
{
    if(n[i]>n[j]) cout<<n[i]<<" ";
    else cout<<n[j]<<" ";
}
cout<<n[n.size()/2]<<endl;

CodePudding user response:

You are trying to do something confusing with nested for-cycles. This is obviously wrong, because there is nothing “quadratic” (with respect to the number of digits) in the entire task. Also, your code doesn’t seem to contain anything that would determine the highest-order digit.

I would suggest that you start with something very simple: string’ify the number and then iterate over the digits in the string. This is obviously neither elegant nor particularly fast, but it will be a working solution to start with and you can improve it later.

BTW, the sooner you get out of the bad habit of using namespace std; the better. It is an antipattern, please avoid it.

Side note: There is no need to treat odd and even numbers of digits differently. Just let the algorithm compare the middle digit (if it exists) against itself and select it; no big deal. It is a tiny efficiency drawback in exchange for a big code simplicity benefit.

#include <cstdint>
#include <iostream>
#include <string>

using std::size_t;
using std::uint64_t;

uint64_t extract_digits(uint64_t source) {
  const std::string digits{std::to_string(source)};
  auto i = digits.begin();
  auto j = digits.rbegin();
  const auto iend = i   (digits.size()   1) / 2;
  uint64_t result{0};
  for (; i < iend;   i,   j) {
    result *= 10;
    result  = (*i > *j ? *i : *j) - '0';
  }
  return result;
}


int main() {
  uint64_t n;
  std::cin >> n;
  std::cout << extract_digits(n) << std::endl;
}

If the task disallows the use of strings and arrays, you could try using pure arithmetics by constructing a “digit-inverted” version of the number and then iterating over both numbers using division and modulo. This will (still) have obvious limitations that stem from the data type size, some numbers cannot be inverted properly etc. (Use GNU MP for unlimited integers.)

#include <iostream>

using std::size_t;
using std::uint64_t;

uint64_t extract_digits(uint64_t source) {
  uint64_t inverted{0};
  size_t count{0};
  for (uint64_t div = source; div; div /= 10) {
    inverted *= 10;
    inverted  = div % 10;
      count;
  }
  count  = 1;
  count /= 2;
  uint64_t result{0};
  if (count) for(;;) {
    const uint64_t a{source % 10}, b{inverted % 10};
    result *= 10;
    result  = a > b ? a : b;
    if (!--count) break;
    source /= 10;
    inverted /= 10;
  }
  return result;
}


int main() {
  uint64_t n;
  std::cin >> n;
  std::cout << extract_digits(n) << std::endl;
}

Last but not least, I would strongly suggest that you ask questions after you have something buildable and runnable. Having homework solved by someone else defeats the homework’s purpose.

CodePudding user response:

We analyze the requirements and then come up with a design.

If we have a number, consisting of digits, we want to compare "left" values with "right" values. So, start somehow at the left and the right index of digits in a number.

Look at this number:   123456789
Index:                 012345678
Length: 9

in C and C indices start with 0.

So, what will we do?

  1. Compare index 0 with index 8
  2. Compare index 1 with index 7
  3. Compare index 2 with index 6
  4. Compare index 3 with index 5
  5. Compare index 4 with index 4

So, the index from the left is running up and the index from the right is running down.

We continue as long as the left index is less than or equal the right index. All this can be done in a for or while loop.

It does not matter, wether the number of digits is odd or even.

Of course we also do need functions that return the length of a number and a digit of the number at a given position. But I see that you know already how to write these functions. So, I will not explain it further here.

I show you 3 different examples.

  1. Ultra simple and very verbose. Very inefficient, because we do not have arrays.
  2. Still simple, but more compressed. Very inefficient, because we do not have arrays.
  3. C solution, not allowed in your case

  1. Verbose
#include <iostream>

// Get the length of a number
unsigned int length(unsigned long long number) {

    unsigned int length = 0;
    while (number != 0) {
        number /= 10;
          length;
    }
    return length;
}
// Get a digit at a given index of a number
unsigned int digitAt(unsigned int index, unsigned long long number) {
    index = length(number) - index - 1;
    unsigned int result = 0;
    unsigned int count = 0;

    while ((number != 0) && (count <= index)) {
        result = number % 10;
        number /= 10;
          count;
    }
    return result;
}
// Test
int main() {
    unsigned long long number;
    if (std::cin >> number) {

        unsigned int indexLeft = 0;
        unsigned int indexRight = length(number) - 1;

        while (indexLeft <= indexRight) {

            if (digitAt(indexLeft, number) > digitAt(indexRight, number)) {
                std::cout << digitAt(indexLeft, number);
            }
            else {
                std::cout << digitAt(indexRight, number);
            }
              indexLeft;
            --indexRight;
        }
    }
}


Compressed

#include <iostream>

// Get the length of a number
size_t length(unsigned long long number) {
    size_t length{};
    for (; number; number /= 10)   length;
    return length;
}
// Get a digit at a given index of a number
unsigned int digitAt(size_t index, unsigned long long number) {
    index = length(number) - index - 1;
    unsigned int result{}, count{};
    for (; number and count <= index;   count, number /= 10)
        result = number % 10;
    return result;
}
// Test
int main() {
    if (unsigned long long number; std::cin >> number) {

        // Iterate from left and right at the same time
        for (size_t indexLeft{}, indexRight{ length(number) - 1 }; indexLeft <= indexRight;   indexLeft, --indexRight)
            std::cout << ((digitAt(indexLeft,number) > digitAt(indexRight, number)) ? digitAt(indexLeft, number) : digitAt(indexRight, number));
    }
}

More modern C

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>

int main() {

    if (std::string numberAsString{}; std::getline(std::cin, numberAsString) and not numberAsString.empty() and
        std::all_of(numberAsString.begin(), numberAsString.end(), std::isdigit)) {

        for (size_t indexLeft{}, indexRight{ numberAsString.length() - 1 }; indexLeft <= indexRight;   indexLeft, --indexRight) 
            std::cout << ((numberAsString[indexLeft] > numberAsString[indexRight]) ? numberAsString[indexLeft] : numberAsString[indexRight]);
    }
}
  • Related