Steps for Deciphering the message
- remove 3 at end of the string
- replace ASCII values at even places(number clusters) with corresponding characters value.
- replace * with spacing " ".
- reverse the string
- swap case of string- lowercase to upper case and vice versa.
Sample input: ?85O89*69R65*87O104*33I1043
Require output: Hi! How are you?
This is the whole method that I have written.
public String deciphering(String ciphered) {
StringBuilder a = new StringBuilder(ciphered);
StringBuilder b = a.deleteCharAt(a.length()-1);
char[] ch = new char[b.length()];
StringBuilder c = new StringBuilder();
for (int i = 0; i < b.length(); i ) {
ch[i] = b.charAt(i);
}
for (int i = 0; i < ch.length; i ) {
if(!Character.isDigit(ch[i]))
{
c.append(ch[i]);
}else
{
String temp = new String();
while(Character.isDigit(ch[i]) &&(i<b.length())){
temp = temp ch[i];
i ;
}
int number = Integer.parseInt(temp);
char p = (char)number;
c.append(p);
}
}
String d = c.toString();
String e = d.replace('*', ' ');
StringBuffer f = new StringBuffer(e);
StringBuffer g = f.reverse();
for (int i = 0; i < g.length(); i ) {
if (Character.isLowerCase(g.charAt(i))){
char x = Character.toUpperCase(g.charAt(i));
g.setCharAt(i, x);
} else if (Character.isUpperCase(g.charAt(i))) {
char x = Character.toLowerCase(g.charAt(i));
g.setCharAt(i, x);
}
}
return g.toString();
}
CodePudding user response:
It may be better to split the input string into parts with non-digit delimiters and keep the delimiters using the following regular expression (using look-ahead and look-behind as described here) after removing the last character:
str.substring(0, str.length() - 1).split("(?<=\\D)|(?=\\D)")
Then Stream API may be used to convert each string into a separate character and insert these characters into prepared StringBuilder
to implement reverse order in the result:
public static String decipher(String str) {
StringBuilder sb = new StringBuilder(str.length());
Arrays.stream(
str.substring(0, str.length() - 1).split("(?<=\\D)|(?=\\D)")
)
.map(p -> p.matches("\\d ") ? (char) Integer.parseInt(p): p.charAt(0))
.map(c -> c == '*' ? ' '
: Character.isLowerCase(c) ? Character.toUpperCase(c)
: Character.isUpperCase(c) ? Character.toLowerCase(c)
: c
)
.forEach(c -> sb.insert(0, c));
return sb.toString();
}
Test:
System.out.println(decipher("?85O89*69R65*87O104*33I1043"));
Output:
Hi! How are you?
CodePudding user response:
You are incrementing i twice past the last digit of a chunk - when you exit your inner loop i is indexing the first non-digit character, then when you reach the end of the for loop body, the for loop is incrementing i again.