0

So let's say we have the following case: for ”12323465723” possible answers would be ”abcbcdfegbc” (1 2 3 2 3 4 6 5 7 2 3), ”awwdfegw” (1 23 23 4 6 5 7 23), ”lcwdefgw” (12 3 23 4 6 5 7 23), in this case, the user will input numbers from 1 to 26, not divided by any space and the program itself will suggest 3 ways of interpreting the numbers, getting the most of the combinations from 1 to 26 these being the values from a to z

As you can see this is edited, as this is the last part of the problem, Thank you all who have helped me this far, I've managed to solve half of my problem, only the above mentioned one is left.

SOLVED -> Thank you

Edward
  • 53
  • 1
  • 9
  • 2
    Welcome Edward :-) I'd really like to help, but I do not understand what your program is supposed to do. How to distinguish 12 from being 1 followed by 2 (i.e. AB) or 12 (i.e. letter L) ? Does it need to count occurrences, or transpose the numbers into letters ? – Christophe Mar 16 '19 at 17:42
  • Hello guys, drescherjm the comment I've added was done after I tried writing the code to solve the question, but I couldn't do it, so I started looking up for no solutions, which I wasn't able to find, that's why I asked the question. @Christophe it needs to transpose the numbers into letters, sorry for not being clear in my initial question. Thank you – Edward Mar 16 '19 at 18:18
  • ***it needs to transpose the numbers into letters*** The problem is this is ambiguous as several mentioned. – drescherjm Mar 16 '19 at 19:15
  • Hello, @drescherjm so I've solved half of it, now I'm stuck at this: so let's say we have the following case: for ”12323465723” possible answers would be ”abcbcdfegbc” (1 2 3 2 3 4 6 5 7 2 3), ”awwdfegw” (1 23 23 4 6 5 7 23), ”lcwdefgw” (12 3 23 4 6 5 7 23), in this case, the user will input numbers from 1 to 26, not divided by any space and the program itself will suggest 3 ways of interpreting the numbers, getting the most of the combinations from 1 to 26 these being the values from a to z – Edward Mar 16 '19 at 19:17
  • I can't help now because I am leaving soon. Anyways please edit your question to add this explanation. I think I finally understand the question but (for a good question at StackOverflow) a reader should not have to read the comments from the question and the answers to understand what the problem is. – drescherjm Mar 16 '19 at 19:19
  • 1
    @drescherjm thank you, I've edited it – Edward Mar 16 '19 at 19:29
  • This sounds like https://en.wikipedia.org/wiki/Dynamic_programming, except the answer is all of the complete strings. – Neil Mar 16 '19 at 21:33
  • 1
    I agree with @NeilEdelman, this problem is a good candidate for recursion. – drescherjm Mar 17 '19 at 02:06

4 Answers4

2

This involves a decision between 0 to 2 outcomes at each step. The base cases are there are no more characters or none of them can be used. In the latter case, we backtrack to output the entire tree. We store the word in memory like dynamic programming. This naturally leads to a recursive algorithm.

#include <stdlib.h> /* EXIT */
#include <stdio.h> /* (f)printf */
#include <errno.h> /* errno */
#include <string.h> /* strlen */

static char word[2000];
static size_t count;

static void recurse(const char *const str) {

    /* Base case when it hits the end of the string. */
    if(*str == '\0') { printf("%.*s\n", (int)count, word); return; }

    /* Bad input. */
    if(*str < '0' || *str > '9') { errno = ERANGE; return; }

    /* Zero is not a valid start; backtrack without output. */
    if(*str == '0') return;

    /* Recurse with one digit. */
    word[count++] = *str - '0' + 'a' - 1;
    recurse(str + 1);
    count--;

    /* Maybe recurse with two digits. */
    if((*str != '1' && *str != '2')
        || (*str == '1' && (str[1] < '0' || str[1] > '9'))
        || (*str == '2' && (str[1] < '0' || str[1] > '6'))) return;
    word[count++] = (str[0] - '0') * 10 + str[1] - '0' + 'a' - 1;
    recurse(str + 2);
    count--;
}

int main(int argc, char **argv) {
    if(argc != 2)
        return fprintf(stderr, "Usage: a.out <number>\n"), EXIT_FAILURE;
    if(strlen(argv[1]) > sizeof word)
        return fprintf(stderr, "Too long.\n"), EXIT_FAILURE;
    recurse(argv[1]);
    return errno ? (perror("numbers"), EXIT_FAILURE) : EXIT_SUCCESS;
}

When run on your original input, ./a.out 12323465723, it gives,

abcbcdfegbc
abcbcdfegw
abcwdfegbc
abcwdfegw
awbcdfegbc
awbcdfegw
awwdfegbc
awwdfegw
lcbcdfegbc
lcbcdfegw
lcwdfegbc
lcwdfegw

(I think you have made a transposition in lcwdefgw.)

Neil
  • 1,767
  • 2
  • 16
  • 22
  • 1
    Hello @Neil Edelman, thank you for your help, I've adapted the code to mine and was able to finish it, although had to switch to C from C++ – Edward Mar 17 '19 at 10:05
0

If you want to count the occurencs of "ab" then this will do it:

int main()
{
    char line[150];
    int grup = 0;

    cout << "Enter a line of string: ";
    cin.getline(line, 150);
    for (int i = 0; line[i] != '\0'; ++i)
    {
        if (line[i] == 'a' && line[i+1] == 'b')
        {
            ++grup;
        }
    }

    cout << "Occurences of ab: " << grup << endl;

    return 0;
}

If you want to convert an int to an ASCII-value you can do that using this code:

// Output ASCII-values
int nr;
do {
cout << "\nEnter a number: ";
cin >> nr;
nr += 96; // + 96 because the ASCII-values of lower case letters start after 96
cout << (char) nr;
} while (nr > 96 && nr < 123);

Here I use the C style of casting values to keep things simple. Also bear in mind ASCII-values: ASCII Table

Hope this helps.

DavisR5
  • 65
  • 10
  • 2
    But how can you distinguish `"12"` interpreted as `"ab"` instead of `"l"`? While this is somewhat likely what the OP wanted, the question itself remains extremely unclear and first one should clarify *what* is the actual question. – Fureeish Mar 16 '19 at 17:44
  • Hello DavisR5, thank you for the suggestion, indeed it solved my issue of finding the "ab" occurrences in my code. What I actually need more is that when the user inputs a string of numbers "213456754" it outputs the letters "bacdefged". And this is what I don't know how to do. Thank you and hope it's clearer now – Edward Mar 16 '19 at 18:15
  • @Edward I edited my post to loop the input until you enter a number higher than 26 or lower than 1. I chose this solution because one can not differ between the outputs; i.e. 'A','B' and 'L' for the input 12. You could indicate differences between your input by using spaces for example. As of now you can just input numbers then press enter and get the result according to its ASCII-value. – DavisR5 Mar 16 '19 at 18:33
  • @DavisR5 I've edited the initial problem, thank you for your help so far – Edward Mar 16 '19 at 19:30
0

According to ASCII table we know that from 65 to 90 it A to Z. so below is the simple logic to achieve what you're trying.

int main(){
int n;
cin>>n;
n=n+64;
char a=(char) n;
if (a>=64 && a<=90)
    cout<<a;
else cout<<"Error";
return 0;
}
Talha
  • 524
  • 1
  • 6
  • 22
  • 1
    Sir, I see that you are new on StackOverflow. Please pay attention to tags under the questions. This is `C++` question, not a `Java` one. – Fureeish Mar 16 '19 at 17:50
  • oh I see well I was trying to help with logic. I should edit it too c++ now. Thanks – Talha Mar 16 '19 at 17:53
  • How does this answer the question? How does this handle the ambiguity regarding distinguishing `"12"` as either `"ab"` or `"l"`? Lastly, this does only the mapping part, nothing on searching. My downvote remains. – Fureeish Mar 16 '19 at 18:09
  • Thank you Talha for the answer and suggestion, I'll give it a try – Edward Mar 16 '19 at 18:16
  • @Fureeish I've edited my initial request, as I've solved half of my problem, hope it's much more clear now – Edward Mar 16 '19 at 19:31
0

This could be an interesting problem and you probably tagged it wrong, There's nothing specific to C++ here, but more on algorithm.

First of all the "decode" method that you described from numerical to alphabetical strings is ambiguious. Eg., 135 could be interpreted as either "ace" or "me". Is this simply an oversight or the intended question?

Suppose the ambiguity is just an oversight, and the user will enter numbers properly separated by say a white space (eg., either "1 3 5" or "13 5"). Let nstr be the numerical string, astr be the alphabetical string to count, then you would

  1. Set i=0, cnt=0.
  2. Read the next integer k from nstr (like in this answer).
  3. Decode k into character ch
    1. If ch == astr[i], increment i
    2. If i == astr.length(), set i=0 and increment cnt
  4. Repeat from 2 until reaching the end of nstr.

On the other hand, suppose the ambiguous decode is intended (the numerical string is supposed to have multiple ways to be decoded), further clarification is needed in order to write a solution. For example, how many k's are there in "1111"? Is it 1 or 2, given "1111" can be decoded either as aka or kk, or maybe even 3, if the counting of k doesn't care about how the entire "1111" is decoded?

Edy
  • 462
  • 3
  • 9
  • Hello @Edy, so let's say we have the following case: for ”12323465723” possible answers would be ”abcbcdfegbc” (1 2 3 2 3 4 6 5 7 2 3), ”awwdfegw” (1 23 23 4 6 5 7 23), ”lcwdefgw” (12 3 23 4 6 5 7 23), in this case, the user will input numbers from 1 to 26, not divided by any space and the program itself will suggest 3 ways of interpreting the numbers, getting the most of the combinations from 1 to 26 these being the values from a to z – Edward Mar 16 '19 at 18:43
  • 2
    @Edward Note that in your example there are much more than 3 ways -- any "`12`" or "`23`" can be independently broken into single character. Now, the real problem is actually not finding the no. occurrence of a substring, but to enumerate all possible representations. To do so, you would start from `"1 2 3 2 3 4 6 5 7 2 3"`, first enumerate all possible 2-digit cases, then try putting these cases together combinatorially. – Edy Mar 16 '19 at 19:02