c++algorithmmathequation-solving

I convert ASCII words into numbers but am stuck trying to decode them. How to convert 1=a, 2=b, 28=ab etc? (psudeocode okay)


So I thought I'd teach myself C++ but I appear to have no problems with the language but I am frankly stupid.

So my idea was this. If I say a=1, b=2, z=26, aa=27 etc, I can map words to numbers, use a boolean in a hash table (bit masked of course) and have an O(1) spell checker. So writing that is no problem at all. My algorithm to do it, looks like this:

int pos;
word_key_t char_key;
word_key_t key = 0;
const char *raw = word.c_str();

cout << "Entering getKey loop with " << raw << endl;
for (pos = 0; raw[pos] != '\0'; pos++) {
    if (raw[pos] >= 'A' && raw[pos] <= 'Z') {
        char_key = raw[pos] - 'A';
    } else if (raw[pos] >= 'a' && raw[pos] <= 'z') {
        char_key = raw[pos] - 'a';
    } else {
        throw new runtime_error("Unrecognised Character");
    }

    key += (char_key + 1) * (pow(CHARS_IN_ALPHABET, pos));
}

cout << "word: " << raw << " ,score: " << key << endl;
return key;

It appears to work,

a=1 b=2 ab=53 ac=79.

I believe this is correct.

However, I'm having problems trying to decode it. This is my best attempt and it isn't working. I believe I need to be using pow(26,position) and decrementing from the end of the string but I'm just struggling to achieve this. This is some workable standalone code that does the wrong thing:

#include <iostream>
#include <inttypes.h>
#include <string.h>
 
typedef uint32_t word_key_t;
const int CHARS_IN_ALPHABET = 26;
const int BUFFER_SIZE = 255; //ignore this for now.
 
using namespace std;
 
string reverseKey(const word_key_t key); //broken algo
 
int main(int argc, char** argv) {
        reverseKey(53); // 53 = ab
        return 0;
}
 
//disassemble a word_key_t into it's original string. returns lowercase only
string reverseKey(const word_key_t key)
{
   
  char chr, buffer[BUFFER_SIZE];
  word_key_t keyc = key, isolated, pos = BUFFER_SIZE;
 
  cout << "key: " << keyc << endl;
  
  while (keyc != 0) {
      isolated = (keyc - 1) % ((word_key_t)CHARS_IN_ALPHABET + 1);
      cout << "key: " << keyc << ", isolated: " << isolated << endl;
      chr = (char)'a' + isolated - 1;
      cout << "isolated character: " << chr << endl;
      keyc = (keyc - isolated) / CHARS_IN_ALPHABET;
      cout << "new key: " << keyc << endl;
      pos++;
  }
 
  string s("test");
  return s;
 
}

If someone could nudge me toward the correct psudeocode for solving this I'd be really grateful. I have kind of gone a bit crazy and lost the plot with the solution. I just can't see it. Something is telling me to 2logX / 2log26 and I think I just need some smarter eyes on it. Then I can get back to learning C++.


Solution

  • Some editing later. I did misunderstand the generation of the key values. I think the generation of the letters from the key would be:

    while ( key )
       {
       int char_key = key % 26;
       char c = 'a' + (char)( char_key - 1 );
       key /= CHARS_IN_ALPHABET;      
       }
    

    Although I still don't think the original calculation of the key is correct. I still believe the key computation should be:

    key = CHARS_IN_ALPHABET * key + char_key + 1;
    

    Process the raw[] array in reverse order to avoid extracting them in reverse order.