-3

I need to change the order of the symbol display but without recursion and a second cycle.

the sow code is displayed but I need to get the wos

int test = 119111115; // wos

for (; test > 0; test /= 1000) {
        std::cout << (char)(test % 1000);
}
    
// > sow

do not use a string or anything related to it.

  • The end length of your c-string would be `ceil(log10(test))/3 + 1`, so that can be known ahead of time. From there, you could simply have a "divisor" you multiply by 1000 each loop iteration, as well as an index you decrement each loop, the inserting the characters into the array in reverse. (To clarify, `log10` of a number would give you 1 for 10, 2 for 100, 3 for 1000, 3.xxx for 1001-9999, etc. You can use this to get the number of digits in a number, keep in mind the edge cases listed above! I didn't handle it). After all that, you'll have your finished c-string – Rogue Aug 24 '20 at 06:23

2 Answers2

0
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

int main() {
    // your code goes here
    int test = 119111115; // wos

    for (; test > 0;) {
        string temp = std::to_string(test);

        // Get first three characters and convert it to ASCII char
        std::cout << (char) stoi(temp.substr(0, 3));

        if (temp.size() > 3 )
            // Remove first three characters
            test = stoi(temp.erase(0,3));
        else
            test = 0;
    }

    return 0;
}

Output:

wos

If you want to get rid of to_string, you can

#include <algorithm>
#include <string>
#include <cmath>
#include <iostream>
using namespace std;


unsigned int number_of_int( unsigned int n )
{
    unsigned int number_of_digits = 0;

    do {
         ++number_of_digits; 
         n /= 10;
    } while (n);

    return number_of_digits;
}

int main() {
    // your code goes here
    int test = 119111115; // wos

    for (; test > 0;) {
        // int length = to_string(test).length();
        // int length = number_of_int(test);
        int length =  test == 0 ? 1 : log10(std::abs(test)) + 1;
        int first3 = test / pow(10, length-3);

        std::cout << (char) first3;
        if (length > 3)
            // Remove first three characters
            test = test % (unsigned long)pow(10, length-3);
        else
            test = 0;
    }

    return 0;
}
Ynjxsjmh
  • 28,441
  • 6
  • 34
  • 52
0

Picking out thousands groupings from an int to display the ASCII value of is a rather strange task. You have "sow" handled fine. You need to basically do the same thing in reverse for "wos". While there a many, many ways to handle the arithmetic, following on your form of and limiting the algorithm to one-loop and using a lookup-table for the divisor, you could do something similar to:

    int test = 119111115,
        thous[] = { 1, 1000, 1000000, 1000000000 };
    
    for (int i = sizeof test - 1; i >= 0; i--) {
        int div = thous[i],
            result = test / div;
        if (result)
            std::cout << (char)result;
        test -= result * div;
    }
    std::cout << '\n';

Which just uses div as the divisor and loops 3, 2, 1, and 0 as the exponent to divide test by. It tests the result and if it is non-zero then outputs the ASCII value of that grouping and then eliminates that value from test.

Both "sow" and "wos" put together could be written:

#include <iostream>

int main (void) {
    
    int test = 119111115,
        thous[] = { 1, 1000, 1000000, 1000000000 };
    
    /* sow */
    for (; test > 0; test /= 1000)
        std::cout << (char)(test % 1000);
    std::cout << '\n';
    
    test = 119111115; // wos
    
    /* wos */
    for (int i = sizeof test - 1; i >= 0; i--) {
        int div = thous[i],
            result = test / div;
        if (result)
            std::cout << (char)result;
        test -= result * div;
    }
    std::cout << '\n';
}

Example Use/Output

$ ./bin/sow
sow
wos

This is just one way to do it. Let me know if you have questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • ARRGH -- you are right! (you could cheat and use a function. I'll play with it a bit more. – David C. Rankin Aug 24 '20 at 07:15
  • I like your version, trying to understand how it works, it seems you have an extra iteration of the cycle due to the number `1000000000` perhaps this is unnecessary – Don Allocine Aug 24 '20 at 07:44
  • `for (int i = sizeof test - 2; i >= 0; i--) {` – Don Allocine Aug 24 '20 at 07:56
  • Yes, to make it general, we iterate over all 4 potential groups. When there are no values that would translate into characters for that group the division `div` will be greater than `test` making `result == 0` and that grouping is simply skipped. – David C. Rankin Aug 24 '20 at 08:57
  • @DonAllocine This will still fail if `int` is 16-bit or 64-bit for example. And if you assume that an `int` is always 32-bit then you don't need a loop at all, just a couple of `if` will suffice. – dxiv Aug 24 '20 at 16:26
  • @dxiv - no, it will work for 16-bit or 64-bit, the issue is the thousand groupings must hold an ASCII value. That's why I opened with doing it that way is kind of weird. Take `int test = 65122` for example, A 16-bit value. (`"Az"` and `"zA"`) That's why this is more a coding exercise rather than the implementation of some bit of code that will be generally useful outside the exercise. – David C. Rankin Aug 24 '20 at 17:18
  • @DavidC.Rankin If `int` is 64-bit the maximum `test` value is `9,223,372,036,854,775,807`. The code can be fixed by making `thous` twice as large, but you still have to hardcode a maximum size. – dxiv Aug 24 '20 at 17:55
  • 1
    Yes, of course, there will be hardcoding of a max size. Whenever you do wonky things, you are not going to be able to write purist code to accomplish it. I'm not disagreeing with you are all. – David C. Rankin Aug 24 '20 at 18:59