Cleaning my code

Pages: 12
@Rechard3
why don't you try looking for those discussions before posting your question?
Like it or not, you are out of line.

The same questions get posted and asked over and over and over (and over). That's part of life on a forum like this. Whether you like it or not you'll have to get used to it.

The fact is that you told the OP not to post. Don't do that.

It is appropriate to direct OP to related posts, as was your apparent attempt. I don't doubt your good intentions.

But as you know, programmers are pretty exacting about language.


@Redeyery
how long have you been programming?
Years.

That doesn't necessarily mean anything though.


My algorithm deals with really large integers by simply avoiding converting them into machine integers. It just messes with their string representation. (Though, come to think of it, I do convert the individual digits into integer indices into their word forms...)

Your algorithm is essentially the same as mine. Mine just adds a bit of trickery and jumbles in things like "and" and "fourty-seven"s if the caller wants them.


Don't go to PMs unless you feel that fellow classmates will be cheating off of you. (But if you think they are, just let your professor know. He'll spot them anyway, and you'll be in the clear.)

Hope this helps.
closed account (1v5E3TCk)
@Rechard3

I am not the poster of that topic.
@Duoas:
It is appropriate to direct OP to related posts, as was your apparent attempt. I don't doubt your good intentions.


you're right my friend, it was really my bad, i think i should've pointed OP to one of the older posts in a clear and straightforward way.
I've put several hours into the original code and so far I have this. It's quite messy and doesn't work very well, yet. I'm only posting this half baked because I'm working on some different programs for now. Sooner or later I'll finish it with fresh eyes.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <iostream>
#include <string>

using namespace std;

string ones[10] =
{
    "zero ",       "one ",        "two ",        "three ",      "four ",
    "five ",       "six ",        "seven ",      "eight ",      "nine "
};

string teens[10] =
{
    "ten ",        "eleven ",     "twelve ",     "thirteen ",   "fourteen ",
    "fifteen ",    "sixteen ",    "seventeen ",  "eighteen ",   "nineteen "
};

string tens[8] =
{
    "twenty ",     "thirty ",     "fourty ",     "fifty ",      "sixty ",
    "seventy ",    "eighty ",     "ninety "
};

string magnitude[10] =
{
    "hundred ",    "thousand ",   "million ",    "billion ",    "trillion ",
    "quadrillion ","quintillion ","sextillion ", "septillion ", "octillion "
};

int threeDigitChunk
(
    int number,     string ones[],      string teens[],
    string tens[],  int reverseNumber,  string magnitude[]
)
{
    if ( number < 10 )
    {
        cout << ones[number];
    }
    else if ( number > 9 && number < 20 )
    {
        cout << teens[number % 10];
    }
    else if ( number > 19 && number < 100)
    {
        cout << tens[(number / 10) - 2];
        if ( (number % 10) != 0 )
        {
            cout << ones[number % 10];
        }
    }
    else if ( number > 99 && number < 1000 )
    {
        int reverseNumber[3];

        for ( int i = 0; i < 3; i++ )
        {
            reverseNumber[i] = (number % 10);
            number = (number / 10);
        }
        cout << ones[reverseNumber[2]];
        cout << magnitude[0];
        if ( reverseNumber[1] > 1 )
        {
            cout << tens[reverseNumber[1] - 2];
        }
        if ( reverseNumber[1] < 2 && reverseNumber[1] != 0 )
        {
            cout << teens[reverseNumber[0]];
        }
        else if ( reverseNumber[0] != 0 )
        {
            cout << ones[reverseNumber[0]];
        }
    }
    else
    {
        cout << "Derp";
    }
}

int main()
{
    while ( true )
    {
        unsigned long long number;
        unsigned long long reverseNumber;
        cout << "Enter number: ";
        cin >> number;

        unsigned long long power_value = 1000;
        int power_index = 1;
        while ((number / power_value) != 0)
        {
            power_value *= 1000;
            power_index += 1;
        }
        power_value /= 1000;
        power_index -= 1;

        int tempNumber = 0;

        tempNumber = (number / power_value);
        threeDigitChunk( tempNumber, ones, teens, tens, reverseNumber, magnitude );

        if ( power_index != 0 )
        {
            cout << magnitude[power_index];

            tempNumber = (number % power_value) / ( power_value / 1000 );
            threeDigitChunk( tempNumber, ones, teens, tens, reverseNumber, magnitude );

            if ( power_index > 1 )
            {
            cout << magnitude[power_index - 1];

            power_value /= 1000;

            number %= power_value;
            threeDigitChunk( number, ones, teens, tens, reverseNumber, magnitude );
            }
        }
        cout << endl;
    }
}



Again, thank you guys!
Like I've said in an earlier post, your else if conditions are redundant. When you get to line 40 you don't need to check if the number is greater than 9, since that would have been dealt with at line 36. Same for line 44, you already checked by that time if the number is at least 19, and at line 52.
Notice that your threeDigitChunk() function handles more than three digits...

I haven't had a chance to look too closely; I'll give it a better look tomorrow.
closed account (Dy7SLyTq)
line 101 and 103 can be condensed to one line, and i havent read the whole thread, but have switches been visited for the threedigitchunk() function?
ats15
Thanks again. Forgot to change it.

Duoas
I don't really see what you mean. But I suppose I will understand when you elaborate.

[edit]
Maybe you're referring to the amount of parameters. I guess the name of the function refers to what is done from a higher abstraction. Maybe better if the name was more literal or the function required less parameters.

DTSCode
Good call, thanks. Switches have been suggested. But to be honest. I haven't learned what switches are yet.
Last edited on
check this for switch statement:
http://www.cplusplus.com/doc/tutorial/control/

scroll down the page, it's the last one.
Oh, okay. I remember reading about those. Why would I use switch/case instead of if/else statements?
in your program, you're comparing a variable against constants. (birler(), onlar(),...etc.)
a switch gives a clearer idea about your intention, maybe shortens your code a bit.
i don't actually get what did DTSCode mean in his latest comment, threeDigitChunk() doesn't require switches, maybe a demonstration on his algorithm would enlighten us.
closed account (1v5E3TCk)
@Rechard3

I think you are cınfused. birler(), onlar()...etc. are in my code. It is not Redeyery's code. And I understand why you are recommending switch case statement.
A demonstration would be nice. I've sharpened the program since with help from everyone's advice. The threeDigitChunk() is less messy now. Also it doesn't output unnecessary zero's or magnitudes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
#include <string>

using namespace std;

string ones[10] =
{
    "zero ",       "one ",        "two ",        "three ",      "four ",
    "five ",       "six ",        "seven ",      "eight ",      "nine "
};

string teens[10] =
{
    "ten ",        "eleven ",     "twelve ",     "thirteen ",   "fourteen ",
    "fifteen ",    "sixteen ",    "seventeen ",  "eighteen ",   "nineteen "
};

string tens[8] =
{
    "twenty ",     "thirty ",     "fourty ",     "fifty ",      "sixty ",
    "seventy ",    "eighty ",     "ninety "
};

string magnitude[10] =
{
    "hundred ",    "thousand ",   "million ",    "billion ",    "trillion ",
    "quadrillion ","quintillion ","sextillion ", "septillion ", "octillion "
};

//This function takes a given number and reverses it
//in order to retrieve the appropriate words(including "hundred")
//for each power of 1000.
int threeDigitChunk
(
    int number,     string ones[],      string teens[],
    string tens[],  int reverseNumber,  string magnitude[]
)
{
    if ( number < 1000 )
    {
        int reverseNumber[3];

        for ( int i = 0; i < 3; i++ )
        {
            reverseNumber[i] = (number % 10);
            number = (number / 10);
        }
        if ( reverseNumber[2] != 0 )
        {
            cout << ones[reverseNumber[2]];
            cout << magnitude[0];
        }
        if ( reverseNumber[1] > 1 )
        {
            cout << tens[reverseNumber[1] - 2];
        }
        if ( reverseNumber[1] < 2 && reverseNumber[1] != 0 )
        {
            cout << teens[reverseNumber[0]];
        }
        else if ( reverseNumber[0] != 0 )
        {
            cout << ones[reverseNumber[0]];
        }
        else if ( reverseNumber[0] == 0 && reverseNumber[1] == 0 && reverseNumber[2] == 0 )
        {
            cout << ones[reverseNumber[0]];
        }
    }
    else
    {
        cout << "Derp";
    }
}

int main()
{
    cout << "This program will translate a number entered in digits to the equivalent\nin English." << endl << endl;

    while ( true )
    {
        unsigned long long number;
        unsigned long long reverseNumber;
        cout << "Enter number: ";
        cin >> number;

//Find the magnitude and corresponding index of the input number.
        unsigned long long power_value = 1000;
        int power_index = 1;
        while ((number / power_value) != 0)
        {
            power_value *= 1000;
            power_index += 1;
        }
        power_value /= 1000;
        power_index -= 1;

//Isolate each power of 1000 and retrieve magnitude if appropriate.
        int tempNumber = (number / power_value);
        threeDigitChunk( tempNumber, ones, teens, tens, reverseNumber, magnitude );

        if ( power_index != 0 )
        {
            cout << magnitude[power_index];
            tempNumber = (number % power_value) / ( power_value / 1000 );

            if ( tempNumber != 0 )
            {
            threeDigitChunk( tempNumber, ones, teens, tens, reverseNumber, magnitude );
            }

            if ( power_index > 1 && tempNumber != 0 )
            {
            cout << magnitude[power_index - 1];
            }

            if ( power_index > 1 )
            {
                power_value /= 1000;

                number %= power_value;
                threeDigitChunk( number, ones, teens, tens, reverseNumber, magnitude );
            }
        }
        cout << endl;
    }
}


Still working on:

-numbers beyond 999,999,999

-appropriate use of hyphens

-not accepting non-numeric inputs(causes inf. loop)

closed account (Dy7SLyTq)
i didnt say it required switches i meant that had anyone talked about it because at a cursory glance it would seem to make it cleaner
@senhor
I think you are cınfused. birler(), onlar()...etc. are in my code. It is not Redeyery's code. And I understand why you are recommending switch case statement.


i'm really sorry mate, i'm a bit sleepy, tired, whatever you know about frustration.
i'm really really sorry. i'll pay attention next time, thx for your patience with me.
Your code seems to be getting more convoluted each time.

I shouldn't have, but I played with it to fix the errors. Feel free to ignore it.

Notes
(1) Globals are OK here.

(2) tens[] is no longer skewed to have only 8 members -- this makes lookup much more direct

(3) threeDigitChunk()'s comment says what it does, and it does what it says. Notice that once the number is split into digits, it only uses that information (since 'number' was destroyed by splitting it). This is more like your earlier attempt.

Forget stuff > 999. That goes elsewhere.

(4) "hundreds" is not a power of 1000, therefore it is handled specially in threeDigitChunk() and not in the magnitude[] array.

(5) The gotcha with unsigned integers is that if you try to input a signed integer then cin will not barf properly, and your program will hang. This is, IMHO, an design flaw in the C++ libraries, but we have to live with it. Input validation is not as easy as people think (or hope).

My solution is pretty simple:

(6) Now accepts negative inputs. And outputs on zero.

(7) A do...while loop best fits your method of breaking the number down into groups of three digits.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <iostream>
#include <string>

using namespace std;

string ones[10] =
{
    "zero ",       "one ",        "two ",        "three ",      "four ",
    "five ",       "six ",        "seven ",      "eight ",      "nine "
};

string teens[10] =
{
    "ten ",        "eleven ",     "twelve ",     "thirteen ",   "fourteen ",
    "fifteen ",    "sixteen ",    "seventeen ",  "eighteen ",   "nineteen "
};

string tens[10] =
{
    "",            "",            "twenty ",     "thirty ",     "fourty ",
    "fifty ",      "sixty ",      "seventy ",    "eighty ",     "ninety "
};

string magnitude[10] =
{
    "",            "thousand ",   "million ",    "billion ",    "trillion ",
    "quadrillion ","quintillion ","sextillion ", "septillion ", "octillion "
};

//This function takes a given number and PRINTS the words for the THREE LEAST-
//significant digits to standard output.
//Examples:
//     1  -->  "one"                        101  -->  "one hundred one"
//    12  -->  "twelve"                     470  -->  "four hundred seventy"
//   123  -->  "one hundred twenty three"
//  1234  -->  "two hundred thirty four"
void threeDigitChunk
(
    int number
)
{
    //First, split the number into individual digits
    int digits[3];
    for ( int i = 0; i < 3; i++ )
    {
        digits[i] = (number % 10);
        number = (number / 10);
    }

    //Hundred's place    
    if (digits[2] != 0)
    {
        cout << ones[digits[2]] << "hundred ";
    }

    //Teens
    if (digits[1] == 1)
    {
        cout << teens[digits[0]];
    }
    else
    {
        //Ten's place
        if (digits[1] != 0)
        {
            cout << tens[digits[1]];
        }
        
        //One's place
        if (digits[0] != 0)
        {
            cout << ones[digits[0]];
        }
    }
}

int main()
{
    cout << "This program will translate a number entered in digits to the equivalent\nin English." << endl << endl;

    while ( true )
    {
        /*unsigned*/ long long number;  // There is a 'gotcha' when handling cin with unsigned values... don't do it.
        cout << "Enter number: ";
        cin >> number;
        if (!cin)
        {
            cin.clear();
            cin.ignore( 10000, '\n' );
            cout << "That was not a valid number. Try again.\n";
            continue;
        }

        //Zero        
        if ( number == 0 )
        {
            cout << "zero\n";
            continue;
        }

        //Negative numbers
        if ( number < 0 )
        {
            cout << "negative ";
            number = -number;
        }

//Find the magnitude and corresponding index of the input number.
        unsigned long long power_value = 1000;
        int power_index = 1;
        while ( (number / power_value) != 0 )
        {
            power_value *= 1000;
            power_index += 1;
        }
        power_value /= 1000;
        power_index -= 1;
        
//Isolate each power of 1000 and retrieve magnitude if appropriate.
        do 
        {
            int tempNumber = (number / power_value);

            if ( tempNumber != 0 )
            {
                threeDigitChunk( tempNumber );

                if ( (tempNumber != 0) && (power_index > 0) )
                {
                    cout << magnitude[power_index];
                }
            }

            power_value /= 1000;
            power_index -= 1;
        }
        while (power_index >= 0);
        
        cout << endl;
    }
}

Anyway...
Nice. looks good. Here's my latest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//To do:
//translate decimal numbers (http://www.basic-mathematics.com/writing-decimals-in-words.html)
//use the word "and" to indicate decimal location

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

using namespace std;

string ones[10] =
{
    "zero ",       "one ",        "two ",        "three ",      "four ",
    "five ",       "six ",        "seven ",      "eight ",      "nine "
};

string teens[10] =
{
    "ten ",        "eleven ",     "twelve ",     "thirteen ",   "fourteen ",
    "fifteen ",    "sixteen ",    "seventeen ",  "eighteen ",   "nineteen "
};

string tens[8] =
{
    "twenty",      "thirty",      "fourty",      "fifty",       "sixty",
    "seventy",     "eighty",      "ninety"
};

string magnitude[10] =
{
    "hundred ",    "thousand ",   "million ",    "billion ",    "trillion ",
    "quadrillion ","quintillion ","sextillion ", "septillion ", "octillion "
};

//This function takes a given number and reverses it
//in order to retrieve the appropriate words(including "hundred")
//for each power of 1000.
int threeDigitChunk
(
    int number,     string ones[],      string teens[],
    string tens[],  int reverseNumber,  string magnitude[]
)
{
    if ( number < 1000 )
    {
        int reverseNumber[3];

        for ( int i = 0; i < 3; i++ )
        {
            reverseNumber[i] = (number % 10);
            number = (number / 10);
        }

        if ( reverseNumber[2] != 0 )
        {
            cout << ones[reverseNumber[2]];
            cout << magnitude[0];
        }

//Check if hyphen is needed
        if ( reverseNumber[1] > 1 && reverseNumber[0] == 0 )
        {
            cout << tens[reverseNumber[1] - 2] << ' ';
        }
        else if ( reverseNumber[1] > 1 && reverseNumber[0] != 0 )
        {
            cout << tens[reverseNumber[1] - 2] << '-';
        }

        if ( reverseNumber[1] < 2 && reverseNumber[1] != 0 )
        {
            cout << teens[reverseNumber[0]];
        }
        else if ( reverseNumber[0] != 0 )
        {
            cout << ones[reverseNumber[0]];
        }
        else if ( reverseNumber[0] == 0 && reverseNumber[1] == 0 && reverseNumber[2] == 0 )
        {
            cout << ones[reverseNumber[0]];
        }
    }
    else
    {
        cout << "Derp";
    }
}

int main()
{
    cout << "This program will translate a number entered in digits to the equivalent" << endl;
    cout << "in English. Commas may be used." << endl << endl;

    while ( true )
    {
        string commaCheck;
        unsigned long long number;
        unsigned long long reverseNumber;
        cout << "Enter number: ";
        cin >> commaCheck;
        commaCheck.erase( remove( commaCheck.begin(), commaCheck.end(), ',' ), commaCheck.end() );
        number = atoi( commaCheck.c_str() );
        cout << endl;

//Find the magnitude and corresponding index of the input number.
        unsigned long long power_value = 1000;
        int power_index = 1;
        while ((number / power_value) != 0)
        {
            power_value *= 1000;
            power_index += 1;
        }
        power_value /= 1000;
        power_index -= 1;

//Isolate each power of 1000 and retrieve magnitude if appropriate.
        int tempNumber = (number / power_value);
        threeDigitChunk( tempNumber, ones, teens, tens, reverseNumber, magnitude );

        if ( power_index != 0 )
        {
            cout << magnitude[power_index] << endl;
            for ( int i = 1; i <= power_index; i++ )
            {
                tempNumber = (number % power_value) / ( power_value / 1000 );

                if ( tempNumber != 0 )
                {
                threeDigitChunk( tempNumber, ones, teens, tens, reverseNumber, magnitude );
                }

                if ( power_index > i && tempNumber != 0 )
                {
                cout << magnitude[power_index - i] << endl;
                }

                power_value /= 1000;
            }
            number %= power_value;
            if ( power_index > 1 && number != 0 )
            {
                threeDigitChunk( number, ones, teens, tens, reverseNumber, magnitude );
            }
        }
        cout << endl << endl;
    }
}


I really like the way you changed it to be more intuitive though.

[edit]
What is a 'gotcha'?
Last edited on
Topic archived. No new replies allowed.
Pages: 12