2

This was taken off LeetCode but basically given a string composed of a few unique characters that each have an associated integer value, I need to quickly process the total integer value of the string. I thought enums would be useful since you know what is going to compose your strings.

The enum is the types of characters that can be in my string (can see that it's limited). If a character with a smaller value is before a character with a bigger value, like IV, then I subtract the preceding character's value from the one after it. Otherwise you add. The code is my attempt, but I can't get enums to work with my algorithm...

std::string s = "III";
int sum = 0;

enum {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000};

// O(n) iteration.
for (int i = 0; i < s.length(); i++) {
  // Must subtract.
  if (s[i] < s[i+1]) {
    sum += s[i+1] - s[i];
  }
  // Add.
  else {
    sum += s[i];
  }
}

std::cout << "sum is: " << sum;

My questions then are 1) Is using enum with a string possible? 2) I know it's possible to do with a unordered_map but I think enums is much quicker.

5
  • 3) its much faster with simpler switch/case Commented May 11, 2018 at 3:57
  • Have you benchmark the performance to claim that...? Commented May 11, 2018 at 3:59
  • @IlyaBursov You mean using switch statements with enums? Commented May 11, 2018 at 5:09
  • @user202729 I didn't benchmark this, just going off the for loop, n being string length. Commented May 11, 2018 at 5:09
  • @JessicaWang implement without enums first, add them later if you need Commented May 11, 2018 at 5:10

3 Answers 3

3

If you won't mind minor memory overhead, you can do something like this:

int table[256];
table['I']=1;
table['V']=5;
...

and then

sum += table[s[i]];

and so on. This approach is guaranteed to be O(1), which is basically the fastest solution you able to get. You can also use std::array instead of POD array, encapsulate all this in some class and add assertions, but this is the idea.

Sign up to request clarification or add additional context in comments.

Comments

1

2) I know it's possible to do with a unordered_map but I think enums is much quicker.

you're comparing oranges with apples.

first, enum is not a container. it's basically just like a list of known constants.

when you mean the access time of operator[]:

for unordered_map:

Unordered map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity.

for string it's also constant time access.

1) Is using enum with a string possible

No. An enum key is basically like an "alias" for the value. Note that each string is a sequence of characters:

V != "V"

Comments

1

It is not possible to convert a char or a string to an enum without some kind of mapping. Because the compiler replaces the enum with its underlying value during compilation. So you cannot dynamically access the enum with its name stored in a string.

You have to use either any one of map family or if else construct to achieve your need.

2 Comments

So it boils down to enum only representing integral types and chars and strings are not integral types... So weird question: Would my method have worked if I had passed in an array of enums (like a makeshift "string") to my for loop? Then it's just enum to enum mapping, which is OK.
@JessicaWang actually, char is integral type. It's value is your problem. 'I' equals 73 and 'X' equals 88, but you want 'I' to be equal 1 and 'X' to be equal 10, that's why mapping is required

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.