Epic Systems Interview Question
Software Engineer / DevelopersCountry: United States
Interview Type: Written Test
Does your code handling something likes "2*", "2*3" ?
I am getting ERROR:
ERROR : Invalid Input Character!
Input Keys = 2*3, Output Text = NULL
Oops..I did not handle *, I handled 0-9 and #. Sorry for missing that out.
Update: I have updated the above codepad link to the code that handles '*' as well. Again, thanks for pointing out '*' issue.
In practice, depending on how long the interval between two presses is, "222" can be interpreted as "AB" or "BA". To be more specific,
"2 (long pause) 22" is interpreted as "AB", but
"22 (long pause) 2" is interpreted as "BA"
I assume that long pause is not considered in this question and thus this code works, right?
import java.util.Scanner;
public class SMSproblem {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("Enter a set of numbers may containing '#' and '*':");
String input = in.nextLine();
System.out.println("Convert result:");
number2string(input);
}
private static String[] pattern = {"+0", "1", "ABC2", "DEF3", "GHI4", "JKL5", "MON6", "PQRS7", "TUV8", "WXYZ9", " *"};
private static void number2string(String input){
char current;
String result = new String();
int count = 0;
int patternID;
result = "";
current = input.charAt(0);
count = 1;
for (int i=1; i<input.length(); i++){
if (current == '#')
count = 0;
if (count == 0){
current = input.charAt(i);
count++;
continue;
}
else if (current!=input.charAt(i)){
if (current=='*')
patternID = 10;
else
patternID = Integer.parseInt(current+"");
result = result + pattern[patternID].charAt((count-1) % pattern[patternID].length());
current = input.charAt(i);
count = 1;
}
else{
count++;
current = input.charAt(i);
}
}
if (current=='#')
return;
if (current=='*')
patternID = 10;
else
patternID = Integer.parseInt(current+"");
result = result + pattern[patternID].charAt((count-1) % pattern[patternID].length());
System.out.println(result);
}
}
public class KeyBoard {
public static void main(String[] args){
String text1 = "223";
String text2 = "44556";
String text3 = "77#7766";
KeyBoard k = new KeyBoard();
k.decode(text1);
System.out.println();
k.decode(text2);
System.out.println();
k.decode(text3);
System.out.println();
}
public void decode(String str){
for(int i =0; i < str.length();i++){
int count = 1;int j;
for (j = i+1; j < str.length(); j++){
if (str.charAt(i) == str.charAt(j)){
count++;
}
else break;
}
char t;
if (str.charAt(i) != '#') {
t = getChar(str.charAt(i), count);
System.out.print(t);
}
i = j - 1;
}
}
/**
* returns the char for a given num and count
* @param num
* @param count
* @return
*/
public char getChar(char num, int count){
switch (num){
case '2':
//System.out.println("It is a 2");
if (count % 3 == 1) return 'A';
if (count % 3 == 2) return 'B';
if (count % 3 == 0) return 'C';
break;
case '3':
if (count % 3 == 1) return 'D';
if (count % 3 == 2) return 'E';
if (count % 3 == 0) return 'F';
break;
case '4':
if (count % 3 == 1) return 'G';
if (count % 3 == 2) return 'H';
if (count % 3 == 0) return 'I';
break;
case '5':
if (count % 3 == 1) return 'J';
if (count % 3 == 2) return 'K';
if (count % 3 == 0) return 'L';
break;
case '6':
if (count % 3 == 1) return 'M';
if (count % 3 == 2) return 'N';
if (count % 3 == 0) return 'O';
break;
case '7':
if (count % 4 == 1) return 'P';
if (count % 4 == 2) return 'Q';
if (count % 4 == 3) return 'R';
if (count % 4 == 0) return 'S';
break;
case '8':
if (count % 3 == 1) return 'S';
if (count % 3 == 2) return 'T';
if (count % 3 == 0) return 'U';
break;
case '9':
if (count % 4 == 1) return 'W';
if (count % 4 == 2) return 'X';
if (count % 4 == 3) return 'Y';
if (count % 4 == 0) return 'Z';
break;
}
return '0';
}
}
make a prefix tree
each leaf will have the corresponding character
for 2 =a
22 =b
222 =c
make a trie of 2, 22 ,222
and so on make trie of 3,33,333 .... 9,99,999
onc we made trie , we can easily decode the given sequence.
#include <stdio.h>
#include <stdlib.h>
char key[12][5] = {{},{},{'a','b','c','2',' '},{'d','e','f','3',' '},{'g','h','i','4',' '},{'j','k','l','5',' '},{'m','n','o','6',' '},{'p','q','r','s','7'},{'t','u','v','8',' '},{'w','x','y','z','9'},{' ',' ',' ',' ',' '},{}};
void sms(char* str)
{
int i=0,j=0,count =0;
char op[100] = {0};
while(str[i])
{
printf("%c %c %d\n",str[i],str[i+1],count);
if(str[i]==str[i+1])
{
count++;
}
else
{
if(str[i]=='#')
{
}
else if(str[i]=='*')
{
op[j] = ' ';
j++;
}
else
{
int idx = (int)str[i]-'0';
if(idx==7 || idx == 9)
{
op[j] = key[idx][count%5];
j++;
}
else if(idx!=0 && idx!=1)
{
op[j] = key[idx][count%4];
j++;
}
}
count = 0;
}
i++;
}
printf("output: %s\n",op);
}
int main()
{
char *s = "203";
sms(s);
return 0;
}
Can you please comment on this program ?
for AA we should type A#A
and 2222 is 2 and not A, because the order is Ab B, C and then the number itself which is 2. Only after this the wrap around starts.
public static String numToTextChanger(String input) {
String output = "";
char preNumber = 0;
int prequency = 0;
if (input.length() == 0) {
return output;
} else {
for (int i = 0; i < input.length(); i++) {
char currentNum = input.charAt(i);
if (i == 0) {
preNumber = currentNum;
prequency = 0;
} else {
if (currentNum == preNumber) {
++prequency;
} else {
if (preNumber == '*') {
for (int j = 0; j < prequency + 1; ++j) {
output += " ";
}
} else if (preNumber == '#') {
output += "";
} else {
int index = Integer.parseInt(Character.toString(preNumber));
int length = numToText.elementAt(index).length;
output += numToText.elementAt(index)[prequency % length];
}
preNumber = currentNum;
prequency = 0;
}
}
if (i == input.length() - 1) {
if (currentNum == '*') {
for (int j = 0; j < prequency + 1; ++j) {
output += " ";
}
} else if (currentNum == '#') {
output += "";
} else {
int index = Integer.parseInt(Character.toString(currentNum));
int length = numToText.elementAt(index).length;
output += numToText.elementAt(index)[prequency % length];
}
}
}
}
return output;
}
This program works all cases. please comment
//step 1. start from left .
//step 2. if it is a # or end of the input string or a new integer , just decode the previous integer.if the pre integer repeated and more than the length of the corresponding code string from the 'codes' string array, then print the number itself.
//step 3.if the previous intger same as present one, and if the repeated more than the length of total charecters in that group, just start again from beginning (cycle must wrap around)
//step 4. else simply continue the loop and index incremented
public static void Decrypt(String input)
{
if (input == " " || input == "#")
{
Console.WriteLine(" nothing to decrypt ");
return;
}
String[] codes = { "", null, "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ" };
char pre = ' ';
int index = -1, i = 0; char inputCh = ' ';
while (input.Length + 1 > i)
{
if (input.Length > i)
{
inputCh = input[i];
}
else
{
inputCh = ' ';
}
//printing the decoded charecter first if it an end(three different end points are there).
if (inputCh == '#' || inputCh == ' ' || pre != ' ' && pre != inputCh)
{
if (index >= 0 && codes[input[i - 1] - '0'].Length > index)
{
Console.Write(codes[input[i - 1] - '0'][index]);
}
else if(pre != ' ')
Console.Write(pre);
//adjusting for '#'. (# breaks the cycle)
if(inputCh == '#')
index = -1;
else index = 0;
pre = ' ';
}
//(cycle must wrap around)
else if (codes[input[i] - '0'].Length <= index )
{
index = 0;
pre = inputCh;
}
else
{
index++;
pre = inputCh;
}
i++;
}
}
string KeyStrokeParser(const string& keys) throw(std::runtime_error)
{
static const string mappings[] = {
"", "ABC2", "DEF3", "GHI4", "JKL5", "MON6", "PQRS7", "TUV8", "WXYZ9" };
size_t len = keys.size();
string ret = "";
char first_char = '1';
char curr_char;
bool need_recalc = false;
int rott_index = 0;
for (size_t i = 0; i < len; ++i) {
if ((keys[i] <= '1' || keys[i] > '9')
&& (keys[i] != '*') && (keys[i] != '#')) {
throw std::runtime_error("parser error");
}
curr_char = keys[i];
if (first_char != curr_char) {
first_char = curr_char;
need_recalc = true;
rott_index = -1;
} else {
need_recalc = false;
}
if (curr_char == '#') {
first_char = curr_char;
need_recalc = true;
rott_index = -1;
} else if (curr_char == '*') {
ret += " ";
} else {
int map_index = curr_char - '0' - 1;
++rott_index;
if (need_recalc) {
ret += mappings[map_index][0];
} else {
ret[ret.size() - 1] = mappings[map_index][rott_index % mappings[map_index].size()];
}
}
}
return ret;
}
const char map[9][6] = {"\0","ABC2","DEF3","GHI4","JKL5","MNO6","PQRS7","TUV8","WXYZ9"} ;
char findNext(char ch){
for(int i=0; i < 9 ; ++i){
for(int j = 0; j < 6 ; ++j){
if (map[i][j] == ch){
if(map[i][j+1] == '\0')
return map[i][0];
else
return map[i][j+1];
}
}
}
}
int main(int argc, char **argv){
const char *numC = argv[1] ;
char out[100] ;
int outIndex = 0 ;
char prev = '\0' ;
char temp ;
int i = 0 ;
while(numC[i] != '\0'){
if(numC[i] == '1'){
}
else if(numC[i] == '#'){
prev = '\0' ;
}
else if(numC[i] == '*'){
prev = '\0' ;
out[outIndex] = ' ';
++outIndex;
}
else{
if(i!=0){
if( prev == numC[i] ){
out[outIndex - 1] = findNext(out[outIndex - 1]) ;
}
else{
temp = numC[i] ;
out[outIndex] = map[temp-1 - '0'][0];
prev = numC[i] ;
++outIndex;
}
}
else{
temp = numC[i] ;
out[outIndex] = map[atoi(&temp)-1][0];
prev = numC[i] ;
++outIndex ;
}
}
++i;
}
out[outIndex] = '\0' ;
printf("%s\n", out);
}
#include <iostream>
#include <string>
#include <set>
using namespace std;
string patterns[] = {"","","ABC2","DEF3","GHI4","JKL5","MNO6","PQRS7","TUV8","WXYZ9"};
string showSMS(string inputString)
{
string resultString = "";
int crtNumber, crtIndex;
for(int i = 0; i < inputString.length(); ++ i )
{
if(inputString[i] == '#')
continue;
else if(inputString[i] == '*')
{
resultString.push_back(' ');
continue;
}
crtNumber = inputString[i] - '0';
crtIndex = 0;
++i;
while( i < inputString.length() && inputString[i] - '0' == crtNumber)
{
crtIndex ++;
i++;
}
crtIndex %= patterns[crtNumber].length();
resultString.push_back(patterns[crtNumber][crtIndex]);
i--;
}
return resultString;
}
int main()
{
cout<<showSMS("2222#222*22333444")<<endl;
}
Works fine, i fail to understand, can you throw some light how you approached this problem !
Thanks
/*
epic-systems-interview-questions 18 Answers
SMS Problem
1 - NULL, 2 - ABC, 3 - DEF, 4 - GHI, 5 - JKL, 6 - MNO, 7 - PQRS, 8 - TUV, 9 - WXYZ, * - <Space>, # - <Break>
We must convert the numbers to text.
Eg
I/P - O/P
22 - B
23 - AD
223 - BD
22#2 - BA (# breaks the cycle)
3#33 - DE
2222 - 2
2222#2 - 2A
22222 - A (cycle must wrap around)
222222 - B
*/
#include<iostream>
void textToNumber(char str[],int l);
using namespace std;
int main()
{
char str[100];
cout<<"Enter String: ";
cin>>str;
int l=0;
for(;str[l]!='\0';l++);
textToNumber(str,l);
}
void textToNumber(char str[],int l)
{
int j=0;
for(int i=1;i<=l;i++)
{
if(str[i]!=str[j])
{
switch(str[j])
{
case '1':
for(int k=0;k<(i-j);k++)
cout<<"NULL";
break;
case '2':
switch(((i-j)%3))
{
case 1: cout<<"A";
break;
case 2: cout<<"B";
break;
case 0: cout<<"C";
break;
}
break;
case '3':
switch(((i-j)%3))
{
case 1: cout<<"D";
break;
case 2: cout<<"E";
break;
case 0: cout<<"F";
break;
}
break;
case '4':
switch(((i-j)%3))
{
case 1: cout<<"G";
break;
case 2: cout<<"H";
break;
case 0: cout<<"I";
break;
}
break;
case '5':
switch(((i-j)%3))
{
case 1:cout<<"J";
break;
case 2:cout<<"K";
break;
case 0: cout<<"L";
break;
}
break;
case '6':
switch(((i-j)%3))
{
case 1: cout<<"M";
break;
case 2: cout<<"N";
break;
case 0: cout<<"O";
break;
}
break;
case '7':
switch(((i-j)%4))
{
case 1: cout<<"P";
break;
case 2: cout<<"Q";
break;
case 3: cout<<"R";
break;
case 0: cout<<"S";
break;
}
break;
case '8':
switch(((i-j)%3))
{
case 0: cout<<"T";
break;
case 1: cout<<"U";
break;
case 2: cout<<"V";
break;
}
break;
case '9':
switch(((i-j)%4))
{
case 0: cout<<"W";
break;
case 1: cout<<"X";
break;
case 2: cout<<"Y";
break;
case 3: cout<<"Z";
break;
}
break;
case '*':
for(int k=0;k<(i-j);k++)for(int k=0;k<(i-j);k++)
cout<<" ";
break;
cout<<" ";
break;
}
while(str[i]=='#')
{
i++;
}
j=i;
}
}
}
take that!
public class PhoneKeyPadIO {
static final private char[][] keyMap = new char[10][4];
static final private char[] numCharInPad = {3,3,3,3,3,4,3,4};
public PhoneKeyPadIO(){initKeyMap();}
private void initKeyMap(){
keyMap[0] = new char[] {'a','b','c'}; //2
keyMap[1] = new char[] {'d','e','f'};
keyMap[2] = new char[] {'g','h','i'};
keyMap[3] = new char[] {'j','k','l'};
keyMap[4] = new char[] {'m','n','o'};
keyMap[5] = new char[] {'p','q','r','s'};
keyMap[6] = new char[] {'t','u','v'};
keyMap[7] = new char[] {'w' ,'x', 'y','z'};//9
}
public String convert(String inStr){
String outStr="";
inStr += '#';
int inLen = inStr.length();
char buff = inStr.charAt(0);
char currChar;
int count = 0;
int index = 0;
for (int i=1; i<inLen; ++i){
currChar = inStr.charAt(i);
if (currChar != buff){
if (buff != '*' && buff != '#'){
index = buff - 48 -2;
outStr += keyMap[index][count%numCharInPad[buff-48-2]];
}
count=0;
buff = currChar;
} else {
++count;
}
if (currChar == '*'){
outStr += ' ';
}
}
return outStr;
}
}
import java.util.Scanner;
/*
* I need to have the mapping
* I need to have to check for 1, *,#
* I need to keep the count for how many times the no is repeated in a sequence
* I need to also keep track of rollover
* using a modulous operator
*/
public class KeyPad {
String keypad[]={" "," ","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};
String msg_convertor(String src){
StringBuilder msg=new StringBuilder();
int startindex,count,count_hash;
startindex=0;
count=0;
count_hash=0;
if(src==null)return null;
for(int i=0;i<src.length();i++){
if(src.charAt(i)=='#')continue;
else if(src.charAt(i)==' '){
msg.append(" ");
continue;
}else if(src.charAt(i)=='1')
continue;
else{
startindex=i;
System.out.println("startindex="+startindex);
break;
}
}
for(int i=startindex;i<src.length()-1;i++){
System.out.println("index="+i);
if(src.charAt(i)=='1')continue;
else if(src.charAt(i)==' '){
msg.append(" ");
count=0;
continue;
}else if(src.charAt(i)=='#'){
int index=i-1;
if(count>0){
while(index>0&&src.charAt(index)=='#'){
index=index-1;
}
msg.append(keypad[src.charAt(index)-'0'].charAt((count)%3));
}
count=0;
continue;
}else if(src.charAt(i)!=src.charAt(i+1)){
System.out.println(src.charAt(i)-'0');
System.out.println("count="+count);
msg.append(keypad[src.charAt(i)-'0'].charAt((count)%3));
count=0;
}else{
count++;
}
}
if(src.charAt(src.length()-1)=='1');
else if(src.charAt(src.length()-1)=='*')
msg.append(" ");
else if(src.charAt(src.length()-1)=='#'){
int index=src.length()-2;
if(count>0){
while(index>0&&src.charAt(index)=='#'){
index=index-1;
}
msg.append(keypad[src.charAt(index)-'0'].charAt((count)%3));
}
}
else
msg.append(keypad[src.charAt(src.length()-1)-'0'].charAt((count)%3));
return msg.toString();
}
public static void main(String[] args) {
System.out.println("Enter the no");
Scanner sc=new Scanner(System.in);
String str=sc.next();
KeyPad obj=new KeyPad();
String msg=obj.msg_convertor(str);
System.out.println(msg);
}
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
main()
{
char string[100];
char *keypad[]={"",NULL, "ABC2", "DEF3", "GHI4", "JKL5", "MON6", "PQRS7", "TUV8", "WXYZ9" };
printf("Enter the string\n");
scanf("%s",string);
char *ptr = string;
char sp=' ';
while(*ptr)
{
while(*ptr=='*')
{
printf("%c",sp);
ptr++;
}
while(*ptr =='#')
ptr++;
char *p = keypad[*ptr-'0'];
char*p1=p;
ptr++;
while(*ptr==*(ptr-1))
{
ptr++;
p++;
if(!*p)
p=p1;
}
printf("%c",*p);
}
printf("\n");
}
Well, this works fine as well!!
#include<iostream>
#include<string>
using namespace std;
string pattern[]={"","1","abc2","def3","ghi4","jkl5","mno6","pqrs7","tuv8","wxyz9"};
//string star=" ";
//string hash="#";
int main()
{
string keystroke;
cout<<"enter keystroke:";
cin>>keystroke;
int length=keystroke.length();
int i=0,j,cnt;
for(i=0;i<length-1;i++)
{
cnt=1;
if(keystroke[i]=='#')continue;
if (keystroke[i]=='*')
{cout<<" ";continue;}
j=keystroke[i]-'0';
while((keystroke[i]==keystroke[i+1])&&(i<length-1))
{
cnt++;i++;
}
if(cnt>pattern[j].length())cnt%=pattern[j].length();
if(cnt!=0)cout<<pattern[j][cnt-1];
else cout<<pattern[j][cnt];
// if(i==length-1)break;
}
if(i!=length)
cout<<pattern[keystroke[i]-'0'][0];
}
import java.io.*;
import java.util.*;
import java.lang.*;
public class sms1 {
public static void main (String[] args) {
String a = "24760956028796*#49680#865948*4796";
translate(a);
}
//check the whole string, set a start int to move to find substrings, then translate and store in StringBuffer
static void translate(String str) {
int len = str.length();
char[] instr = str.toCharArray();
StringBuffer result = new StringBuffer();
int start = 0;
for (int i=0; i<len-1; i++) {
if (instr[i] != instr[i+1]) {
find(str.substring(start, i+1), result);
start = i + 1;
}
}
//last one
find(str.substring(start, len), result);
System.out.println(result.toString());
}
//translate method: *: " "; #: ""(nothing); 1:nothing (don put in map, otherwise error will occur)
static void find(String str, StringBuffer out) {
HashMap<Character, String> map = new HashMap<Character, String>();
map.put('2', "ABC");
map.put('3', "DEF");
map.put('4', "GHI");
map.put('5', "JKL");
map.put('6', "MNO");
map.put('7', "PQRS");
map.put('8', "TUV");
map.put('9', "WXYZ");
if (str.equals("*")) out.append(" ");
if(str.equals("#") || str.equals("1")) out.append("");
if(map.containsKey(str.charAt(0))) {
int count = (str.length()-1)%map.get(str.charAt(0)).length();
out.append(map.get(str.charAt(0)).charAt(count));
}
}
}
public class twotwo{
private static String[] SMSText={null,"ABC","DEF","GHI","JKL","MON","PQRS","TUV","WXYZ","*","#"};
public static void main(String[] args)
{
String digits="2222233#33";
System.out.println(convertNumbertoText(digits));
}
public static String convertNumbertoText(String numbers)
{
char[] number=numbers.toCharArray();
StringBuffer sb=new StringBuffer();
int count =1;
char last =number[0];
for(int i=1;i<number.length;i++)
{
if(number[i]!=last || i==number.length-1){
if(number[i]==last)
count++;
int index= count%(SMSText[last-48].length()+1);
if(index==0)
sb.append(last);
else
{
sb.append(SMSText[last-48].charAt(index-1));
}
if(number[i]=='#'&&i!=number.length-1)
{
last=number[i+1];
count=0;
}else{
last=number[i];
count =1;
}
}else{
count++;
}
}
return sb.toString();
}
}
Here is a C implementation of the problem
#include <stdio.h>
int main()
{
char pattern[][6] = {"+0", "1", "ABC2", "DEF3", "GHI4", "JKL5", "MON6", "PQRS7", "TUV8", "WXYZ9", " *"};
int len[] = {2,1,4,4,4,4,4,5,4,5,2};
char in[] = "2#244335222#223444";
int patternId;
int count = 1;
char c = in[0];
int i =1;
char result[100];
int cnt = 0;
while(in[i])
{
if (c == '#')
{
count = 1;
c = in[i];
i++;
continue;
}
if (c == in[i])
{
count++;
i++;
}
else if (c != in[i])
{
if (c == '*')
patternId = 10;
else
patternId = c - '0';
result[cnt++] = pattern[patternId][(count - 1)%len[patternId]];
result[cnt]='\0';
//printf("\n%s %d", result, patternId);
c = in[i];
i++;
count = 1;
}
}
if (c == '#')
return;
else if (c == '*')
patternId = 10;
else
patternId = c - '0';
result[cnt++] = pattern[patternId][(count - 1)%len[patternId]];
result[cnt]='\0';
//result[cnt] = '\0';
printf("\n%s", result);
}
import java.util.*;
class LinkNode
{
public char letter;
public LinkNode next;
public LinkNode(char a)
{
letter = a;
next = null;
}
}
public class Solution
{
public static void main(String[] args)
{
List<LinkNode> keyParser = new ArrayList<LinkNode>();
keyParser.add(new LinkNode(' '));
keyParser.add(new LinkNode(' '));
LinkNode temp = new LinkNode('A');
temp.next = new LinkNode('B');
temp.next.next = new LinkNode('C');
temp.next.next.next = new LinkNode('2');
temp.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('D');
temp.next = new LinkNode('E');
temp.next.next = new LinkNode('F');
temp.next.next.next = new LinkNode('3');
temp.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('G');
temp.next = new LinkNode('H');
temp.next.next = new LinkNode('I');
temp.next.next.next = new LinkNode('4');
temp.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('J');
temp.next = new LinkNode('K');
temp.next.next = new LinkNode('L');
temp.next.next.next = new LinkNode('5');
temp.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('M');
temp.next = new LinkNode('O');
temp.next.next = new LinkNode('N');
temp.next.next.next = new LinkNode('6');
temp.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('P');
temp.next = new LinkNode('Q');
temp.next.next = new LinkNode('R');
temp.next.next.next = new LinkNode('S');
temp.next.next.next.next = new LinkNode('7');
temp.next.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('T');
temp.next = new LinkNode('U');
temp.next.next = new LinkNode('V');
temp.next.next.next = new LinkNode('8');
temp.next.next.next.next = temp;
keyParser.add(temp);
temp = new LinkNode('W');
temp.next = new LinkNode('X');
temp.next.next = new LinkNode('Y');
temp.next.next.next = new LinkNode('Z');
temp.next.next.next.next = new LinkNode('9');
temp.next.next.next.next.next = temp;
keyParser.add(temp);
PrintParsedText("22", keyParser); // B
PrintParsedText("23", keyParser); // AD
PrintParsedText("223", keyParser); // BD
PrintParsedText("22#2", keyParser); // BA (# breaks the cycle)
PrintParsedText("3#33", keyParser); // DE
PrintParsedText("2222", keyParser); // 2
PrintParsedText("2222#2", keyParser); // 2A
PrintParsedText("22222", keyParser); // A (cycle must wrap around)
PrintParsedText("222222", keyParser); // B
PrintParsedText("#33#44#", keyParser); // EH
PrintParsedText("#44#444", keyParser); // HI
PrintParsedText("#4*222#", keyParser); // G C
PrintParsedText("33*222*4", keyParser); // E C G
}
public static void PrintParsedText(String str, List<LinkNode> keyParser)
{
char[] code = str.toCharArray();
String toPrint = "";
StringBuilder sb = new StringBuilder(toPrint);
int curr = 0;
LinkNode temp = keyParser.get(curr);
for(int ii = 0; ii < code.length; ii++)
{
if(code[ii] == '*')
{
sb.append(curr>0?temp.letter:"");
curr = 0;
sb.append(" ");
continue;
}
if(code[ii] == '#')
{
sb.append(curr>0?temp.letter:"");
curr = 0;
}
else
{
if(curr != code[ii]-'0')
{
sb.append(curr>0?temp.letter:"");
curr = code[ii] - '0';
temp = keyParser.get(curr);
}
else
{
temp = temp.next;
}
}
}
sb.append(curr>0?temp.letter:"");
System.out.println(sb.toString());
}
}
Here is a working code in C++. I have considered if there is a 1 in input we will print 1 and if there is a 0 in input we will print 0. We can remove these assumptions though.
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
char *arr[10], str[100], ch;
int i, ct=0, val[10];
arr[0]=new char [2];
arr[1]=new char [2];
arr[2]=new char [5];
arr[3]=new char [5];
arr[4]=new char [5];
arr[5]=new char [5];
arr[6]=new char [5];
arr[7]=new char [6];
arr[8]=new char [5];
arr[9]=new char [6];
arr[0][0]='0';
arr[1][0]='1';
arr[2]="ABC2";
arr[3]="DEF3";
arr[4]="GHI4";
arr[5]="JKL5";
arr[6]="MON6";
arr[7]="PQRS7";
arr[8]="TUV8";
arr[9]="WXYZ9";
val[0]=1;
val[1]=1;
val[2]=4;
val[3]=4;
val[4]=4;
val[5]=4;
val[6]=4;
val[7]=5;
val[8]=4;
val[9]=5;
cin>>str;
ch=str[0];
for (i=0; i<strlen(str); i++)
{
if (str[i]=='*')
{
if (ct%val[(int)(ch-48)]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1];
}
else if(arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][val[(int)(ch-48)]-1];
}
ch=str[i+1];
ct=0;
cout<<" ";
}
else if(str[i]=='#')
{
if (ct%val[(int)(ch-48)]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1];
}
else if(arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][val[(int)(ch-48)]-1];
}
ch=str[i+1];
ct=0;
}
else if(str[i]=='0')
{
if (ct%val[(int)(ch-48)]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1];
}
else if(arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][val[(int)(ch-48)]-1];
}
ch=str[i+1];
ct=0;
cout<<"0";
}
else if(str[i]=='1')
{
if (ct%val[(int)(ch-48)]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1];
}
else if(arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][val[(int)(ch-48)]-1];
}
ch=str[i+1];
ct=0;
cout<<"1";
}
else if(str[i]==ch)
{
ct++;
}
else if(str[i]!=ch)
{
if (arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1] !=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][(ct%sizeof(arr[(int)(ch-48)]))-1];
}
ct=1;
ch=str[i];
}
}
if (ct%val[(int)(ch-48)]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1];
}
else if(arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=0 && arr[(int)(ch-48)][(ct%val[(int)(ch-48)])-1]!=1)
{
cout<<arr[(int)(ch-48)][val[(int)(ch-48)]-1];
}
return 0;
}
python
import sys
import math
def main():
SMS('2*3')
def SMS(a):
i = 0
count = 0
dic = {'1' : '\0'+'1', '2' : 'ABC2', '3' : 'DEF3', '4' : 'GHI4', '5' : 'JKL5', '6' : 'MON6', '7' : 'PQRS7', '8' : 'TUV8', '9' : 'WXYZ9', '*' : ' '}
#print dic
n = len(a)
while(i<n):
j = i
while(j+1<n and a[j+1]==a[j]):
count = count + 1
j = j+1
if a[j]=='#':
count = 0
i = j+1
else:
count = count % len(dic[a[j]])
print dic[a[j]][count]
count = 0
i = j+1
if __name__ == '__main__':
main()
public static char[][] keypad = {{' ',' ',' '},
{' ',' ',' ',1},
{'A','B','C','2',},
{'D','E','F','3'},
{'G','H','I','4'},
{'J','K','L','5'},
{'M','N','O','6'},
{'P','Q','R','S',7,},
{'T','U','V','8'},
{'W','X','Y','Z','9'}};
static int cnt=0;
public static void possibleCombinations(String input)
{
String result="";
int count=0;
char c = '#';
if(input.length()>1)
{
for(int i=1;i<input.length();i++)
{
char p =input.charAt(i-1);
c =input.charAt(i);
if(p!=c && p!='#')
{
int idx= p-'0';
char t[] = keypad[idx];
result=result+String.valueOf(t[count]);
count=0;
}
else if(p==c)
{
count=(count+1)%(keypad[p-'0'].length);
}
}
}
if(c!='#' && c!=' ')
{
int idx= c-'0';
char t[] = keypad[idx];
result=result+String.valueOf(t[count]);
}
System.out.println(result);
}
public static void main(String...args){
possibleCombinations("22#222");
}
package Epic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SMSProblem {
public static Map<Character, String> map = new HashMap<Character, String>();
public static void main(String[] args) {
// TODO Auto-generated method stub
map.put('1', null);
map.put('2', "ABC");
map.put('3', "DEF");
map.put('4', "GHI");
map.put('5', "JKL");
map.put('6', "MON");
map.put('7', "PQRS");
map.put('8', "TUV");
map.put('9', "WXYZ");
map.put('*', "Space");
map.put('#', "Break");
List<String> list = new ArrayList<String>();
list.add("22");
list.add("23");
list.add("223");
list.add("22#2");
list.add("3#33");
list.add("2222");
list.add("2222#2");
list.add("22222");
list.add("222222");
for(String s:list){
getSMSOutput(s);
System.out.println();
}
}
public static void getSMSOutput(String input){
int count=0;
boolean flag = false;
for(int i = 0; i < input.length()-1; i++){
count = 1;
String temp = map.get(input.charAt(i));
if(temp==null)
continue;
else if(temp.equals("Space"))
System.out.print(" ");
else if(temp.equals("Break")){//For the last digit if different from second last
if(i==input.length()-2)
flag = true;
continue;
}
else{
while(i < input.length()-1){
if(input.charAt(i)==input.charAt(i+1)){//Count over no of same consequtive digits
count++;
i++;
}
else{
if(i == input.length()-2)//For the last digit if different from second last
flag = true;
break;
}
}
print(input.charAt(i), temp, count);//Send for print
}
}
if(flag){//For the last digit, if it is different from secondlast
String temp = map.get(input.charAt(input.length()-1));
if(temp!=null || !temp.equals("Break")){
if(temp.equals("Space"))
System.out.print(" ");
else
print(input.charAt(input.length()-1), temp, 1);
}
}
}
public static void print(char c, String alphabets, int count){
int len = alphabets.length();//No while loop needed as if it is more than len+1, we start count from 1 again
int temp = count%(len+1);
if(temp==0){
System.out.print(c);
}
else
System.out.print(alphabets.charAt(temp-1));
}
}
Prefix trie is very brilliant though a little overkill. We will not have any case like 3343 as one character. Thus I feel prefix trie is not ideal here. Especially when you have case like 333333, 444444.
My code is not neat. Thus I will not present it here. Playable version @
ideone.com/CeIqWK
A map structure is used. Multiple key press on the same char is taken care off by modulo operation. The question itself never mentioned pressing 1 and pressing 0. As suggested by other fellow CCers, it is handled as numeric inputs.
public static void decode(String str) {
int count = 0;
String[] pattern = {"", "1", "ABC2", "DEF3", "GHI4", "JKL5", "MON6", "PQRS7", "TUV8", "WXYZ9"};
for (int i = 1; i < str.length(); i++) {
if(str.charAt(i-1) == '1') {
System.out.print('1');
} else if(str.charAt(i-1) == '*') {
System.out.print(' ');
}else if (str.charAt(i) == str.charAt(i-1)) {
count++;
if (i == str.length() - 1) {
int num = str.charAt(i-1) - '0';
System.out.print(pattern[num].charAt((count+1)%(pattern[num].length())));
}
} else {
if(str.charAt(i-1) != '#') {
int num = str.charAt(i-1) - '0';
System.out.print(pattern[num].charAt(count%(pattern[num].length())));
count = 0;
if (i == str.length() - 1) {
num = str.charAt(i) - '0';
System.out.print(pattern[num].charAt(0));
}
}
}
}
}
<pre lang="" line="1" title="CodeMonkey97872" class="run-this">public static String getSMSText(String str)
- marcind November 25, 2011{
String patterns[]={"10", "ABC2", "DEF3", "GHI4", "JKL5", "MON6",
"PQRS7", "TUV8", "WXYZ9", " *","#"};
int possitions[]={2,4,4,4,4,4,5,4,5,2,1};
StringBuilder ParsedString = new StringBuilder();
Character c = str.charAt(0);
int counter=0;
int index = 0;
int possition = 0;
for(int i=1;i<str.length();i++)
{
//System.out.println(c);
if(str.charAt(i) == c)
{
counter++;
}
else
{
if(c!='#')
{
if(c=='*') index=9;
else index = ((int)c-48)-1;
possition = counter%possitions[index];
char toAdd = patterns[index].charAt(possition);
if(toAdd!='0')
ParsedString.append(toAdd);
c=str.charAt(i);
counter=0;
}else
{
c=str.charAt(i);
}
}
}
if(c!='#')
{
if(c=='*') index=9;
else
index = ((int)str.charAt(str.length()-1)-48)-1;
possition = counter%possitions[index];
ParsedString.append(patterns[index].charAt(possition));
}
return ParsedString.toString();
}</pre><pre title="CodeMonkey97872" input="yes">
</pre>