简体   繁体   中英

How it could be optimized [C++]?

I was doing some C++ "homework" and I've made an exercise which says the following:

Input The input consists of a sequence of characters, which include exclusively lowercase letters, spaces and newlines.

[Table with letter-number values]

Output Your program must print the total value of the message, computed as the sum of the value of all its letters.

And I've done this::

#include<iostream>
using namespace std;

int main() {
    char v;
    int val = 0;
        while(cin >> v){
            if (v == 'a' or v == 'e') val += 1;
            if (v == 'o' or v == 's') val += 2;
            if (v == 'd' or v == 'i' or v == 'n' or v == 'r') val += 3;
            if (v == 'c' or v == 'l' or v == 't' or v == 'u') val += 4;
            if (v == 'm' or v == 'p') val += 5;
            if (v == 'k' or v == 'w') val += 7;
            if (v == 'b' or v == 'f' or v == 'g' or v == 'h') val += 6;
            if (v == 'j' or v == 'q' or v == 'v' or v == 'x' or v == 'y' or v == 'z') val += 6;
            }
        cout << val << endl;
        }

Example: INPUT: is a chinese wok OUTPUT: 42

(I end the While loop by pressing Ctrl+D, which is how the evaluation web does.)

Which is a pretty simple and working solution but... I was wandering if there's any way of doing this without a bunch of "if's". Gotta say, I can't include anything else than iostream . Thanks!

As another answer indicates, you can use a map. That's the most compact way of writing this algorithm, but it will not necessarily result in best performance.

There are two more ways that I can think of. A somewhat better way is with a switch statement, like this:

int get_increment( char v )
{
    switch( v )
    {
        case 'a': case 'e':
            return 1;
        case 'o': case 's':
            return 2;
        case 'd': case 'i': case 'n': case 'r':
            return 3;
        case 'c': case 'l': case 't': case 'u':
            return 4;
        case 'm': case 'p':
            return 5;
        case 'k': case 'b': case 'f': case 'g': case 'h':
            return 6;
        case 'w':
            return 7;
        case 'j': case 'q': case 'v': case 'x': case 'y': case 'z':
            return 6;
        default:
            return 0; //not a letter!
    }
}

but if you want the maximum performance, then a lookup table is the way to go. Here is how to initialize the lookup table:

int increments[256];
for( int i = 0;  i < 256;  i++ )
    increments[i] = 0;
for( char c = 'a';  c <= 'z';  c++ )
    increments[c] = get_increment( c );

and then here is how to use it:

val += increments[(unsigned char)v];

Note: the cast of v to unsigned char is not strictly speaking necessary, if v is only going to contain letters. But it will save your program from a crash if characters in your architecture are signed, (and they usually are,) and v happens to contain a negative value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM