How can I compute the previous and next chars? - java

My goal is to return a string that is made up of characters that are 1 before and 1 after each character in the given string in the ASCII table.
For example, dog should return cenpfh.
public String encrypt(String s) {
if (s.length() == 1) {
String one = "";
one += (s.charAt(0)-1) + (s.charAt(0)+1);
return one;
} else { .. }
}
This is the code I have so far, and I have no idea how to continue. This doesn't even work for a single character, for example, "172" is returned for "V". Could anyone point me in the right direction? Really stumped right now.

If you have to use recursion, you can try something like that:
public static String encrypt(final String s) {
if (s.length() == 1) {
final char c = s.charAt(0);
return new String(new char[] {(char) (c - 1), (char) (c + 1)});
} else {
return encrypt(s.substring(0, 1)) + encrypt(s.substring(1));
}
}
the main idea here:
if input length is 1 symbol - we know what to do and just perform "encryption"
if input length is more than 1 symbol - we split string into "first symbol" and "rest of the string" and call itself on both parts

This is fairly tricky stuff for a beginner, but it's good stuff to encounter early and understand.
"" + 172
results in the string "172"
"" + 'V'
results in the string "V".
V and 172 are both represented internally as the same number, so what's the difference? The difference is that the compiler keeps track of the type of the value. 'V' has a type of char. 172 has a type of int.
When you perform an expression using a mixture of types, the compiler has to decide what the type of the result is. This will influence how that result is handled by routines such String concatenation.
As it happens when you subtract an int from a char, the type of the result is an int (the Java spec tells you this).
You can get around it by casting the type to something else.
(char) 172 is 'V'
(int) 'V' is 172.
So:
one += (char) (s.charAt(0)-1) + (char)(s.charAt(0)+1);
Recursion is a separate topic. Recursion works for handling sequences (a String is a sequence of characters) when you can do a chunk of work on a part of the sequence, leaving you with a new, shorter sequence, that you can do the same job on -- until finally you have the simplest case, which you simply return.
The simplest case, the one where the method returns without recursively calling itself, is called the terminating case. You need at least one terminating case, otherwise the recursive method will keep calling itself until Java runs out of memory for storing method states.
You have chosen your terminating case as being a one char string. I would instead pick a zero length string:
public void encrypt(String s) {
if("".equals(s)) {
return "";
} else {
// do something with a string that's guaranteed >1 char
}
Now you just have to work out how to replace that comment, by using up the guaranteed one char, and calling encrypt() to handle what's left.
public void encrypt(String s) {
if("".equals(s)) {
return "";
} else {
return encodeOneChar(s.charAt(0)) +
encrypt(x.substring(1));
}
}
That's it:
when called with an empty string, encode() returns an empty string.
when called with a non-empty string, encode processes the first char
and calls itself to deal with a string that's one shorter.
Some languages, like Haskell, make recursion easier to understand, by representing the cases as pattern matching statements.
encrypted "" == ""
encrypted s == encryptChar(head(s)) + encrypted(tail(s))
(that's not real Haskell, but it illustrates the pattern.)
Recursion isn't quite as easy to read in Java, but the pattern is still there. if(terminating case) { return answer for terminating case } else { calculate something, call self, return combined result }
I'll leave you to implement private String encodeOneChar(char c)
Note that recursion isn't a good solution to your actual task in Java -- except in the sense that your goal is to understand recursion.

There is no recursion needed. Just iterate over input chars and collect result in a StringBuilder:
public static String encrypt(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
sb.append((char)(c - 1)).append((char)(c + 1));
}
return sb.toString();
}
Note that explicit cast to char is required here, because s.charAt(i) - 1 evaluates to int and without cast is processed by overloaded append(int i) method.
Okay, recursion. Here I split input into 2 halves and process each by using the same encryptRecursively() method, then join results. Each part, when passed to the method, is again split into 2 parts, etc, until size becomes 0 or 1 (thus we get a very simple implementation of Divide and Conquer):
public static String encryptRecursively(String s) {
if (s.isEmpty())
return "";
else if (s.length() == 1) {
char c = s.charAt(0);
return new String(new char[] { (char)(c - 1), (char)(c + 1) });
} else {
int mid = s.length() / 2;
return encryptRecursively(s.substring(0, mid)) // process first half of input
+ encryptRecursively(s.substring(mid)); // second half
}
}

You don't need a recursion but a simple for-loop through all chars in the word. You get the value of char with s.charAt(...), but you have to convert it back to char for the desired resut. Append them to StringBuilder and return its String as the output of the method:
public static String encrypt(String s) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<s.length(); i++) {
char a = (char)(s.charAt(i)-1);
char b = (char)(s.charAt(i)+1);
sb.append(a).append(b);
}
return sb.toString();
}
Here is the recursion method as demanded:
public static String encrypt(String s) {
if (s.length() == 1) {
StringBuilder sb = new StringBuilder();
char a = (char)(s.charAt(0)-1);
char b = (char)(s.charAt(0)+1);
return sb.append(a).append(b).toString();
} else {
return encrypt(s.substring(0, 1)) + encrypt(s.substring(1, s.length()));
}

You can try this:
one += (char)(((int)s.charAt(0))-1);
one += (char)(((int)s.charAt(0))+1);
Input:
V
Output:
UW

Related

recursion moving char to the end of the string

i need to get a string and rearrange it with recursion by getting char and by that char i have to move that char everywhere on the string to the end
like "Hello world!" ,'l' => "Heo word!lll"
i have problems understading the recursion way of thinking
so i started with this:
public static String ChToLast (String str, char ch){
if(str.indexOf(ch)== -1){
return str;
}else{
if(str.indexOf(0) == ch){
return str;
}
}
thank you for your help :)
Recursion is the practise of reusing your method inside itself. In this case, I will provide a solution to explain what happens:
public static String chrToLast(String str, char ch) {
//This if statement details the end condition
if(str.length() < 1) {
return "";
}
String newString = str.substring(1); //Create new string without first character
if(str.indexOf(ch) == 0) { //This happens when your character is found
return chrToLast(newString, ch) + ch;
} else { //This happens with all other characters
return str.charAt(0) + chrToLast(newString, ch);
}
}
If you execute:
chrToLast("Hello, World!", 'l')
This will result in the desired result: Heo, Word!lll
Process
In general, this method works by checking which character is currently the first in the given string, and then deciding what to do. If the first character is the same as the one your looking for (l), it will then remove that character from the string and use chrToLast on that new string. But, it also adds the character it found to the end of the result by using + ch. It continues to do this until there are no more characters left, which is what the end condition is for.
The end condition
The end condition returns an empty string "" because that is what is called the base case of the algorithm. You can think of a recursive algorithm as something solving a problem by calling itself a number of times. By calling themselves, recursive algorithms move towards a base. In this particular case, it does that by subtracting one character off the string each time the method is executed. Once there are no characters left, it reaches the base case which is "", where the string is finally empty and no characters can be subtracted anymore. (Hence it returns nothing as it's final state)
I hope this answers your question. It's important to understand this concept, as it is very powerful. Try to study the code and comment if something's not clear.
Something that can also help is by executing this code in an IDE and using the debugger to walk through its execution. You can then see for yourself what the flow of the program is, and see the value of the variables in play.
If you use recursion, it will be pretty expensive call for the result you are expecting. Lot of movement of String or charArray elements, eitherway you do. I don't see its a wiser choice. I would do it this way, it will be of space complexity O(2n) & performance complexity O(n).
public class Solve {
public static void main(String[] args) {
System.out.println(ChToLast("Hello world!", 'l'));
}
public static String ChToLast(String str, char ch) {
char[] chars = str.toCharArray();
char[] modChars = new char[chars.length];
int i = 0;
for(char element : chars){
if(ch != element){
modChars[i++] = element;
}
}
Arrays.fill(modChars, i, chars.length , ch);
return new String(modChars);
}
}
If you use while loop and write a method to check if that string means perfect statement then that may work for you
Here you would need some help of NLP concept to check everytime if arranged chars are making any statement or are grammatically correct.
This will help

How to read first character of a String in C

Given a String "Hello" in C, how would a method look that returns the "H" in the String.
Then once I've determined how to do that, I'd like to take it a step further and remove the first character from the initial String so that the next time that I read it "Hello" becomes "ello", and when I call the read method again it will return the "e"?
I know how to do this in other languages, like Java but I'm not as proficient in C so I'm really struggling with this concept.
Here's how I would do this in java.
public class Program1 {
private String expression = "-(1+3)*4/6";
public String cut_string(String word)
{
String temp = word.substring(1, word.length());
return temp;
}
public char readToken()
{
if(expression.length() > 1)
{
char token = expression.charAt(0);
expression = cut_string(expression);
return token;
}else {
System.out.print("BROKEN AT READ TOKEN");
return ' ';
}
}
public String getExpression()
{
return expression;
}
public static void main(String [] args)
{
Program1 thing = new Program1();
System.out.println("The token was: " + thing.readToken()
+ "\n" + "The remaining String is: "
+ thing.getExpression());
System.out.println("The token was: " + thing.readToken()
+ "\n" + "The remaining String is: "
+ thing.getExpression());
System.out.println("The token was: " + thing.readToken()
+ "\n" + "The remaining String is: "
+ thing.getExpression());
}
}
The output would be as follows:
The token was: -
The remaining String is: (1+3)*4/6
The token was: (
The remaining String is: 1+3)*4/6
The token was: 1
The remaining String is: +3)*4/6
Coming from Java, you should bear in mind that a "string" in the Java sense is not a native concept to C. In C, you deal explicitly with arrays of characters instead of more abstract data types (unless you build them yourself). Think of them as similar to a char[] in Java.
Returning the first character of a string, then, is simply the same as returning the first element of the array that is the string:
char first_character(char *string) {
return(string[0]);
}
Changing the program's state, on the other hand, to "remove" the first character of the string, may be completely superfluous in C, depending on how you want to do it. You do, of course, have the option of actually modifying the string by moving all elements back one position, for instance like this:
void remove_first_char(char *string) {
int i;
for(i = 0; string[i] != 0; i++)
string[i] = string[i + 1];
}
(Note, however, that string literals are often allocated in read-only memory and cannot be modified.)
But, depending on your context, you could also quite simply modify the pointer that you might be using to just point to the second character instead.
I'd prefer to avoid global variables (especially in a case like this where it's being modified), but since you seem willing to put up with that, it can be pretty trivial:
char expr[] = "-(1+3)*4/6";
char *expression = expr;
char read_token() {
return *expression++;
}
int main() {
char ch;
while (ch=read_token()) {
printf("next token: %c\n", ch);
printf("The remaining string is: %s\n", expression);
}
}
To encapsulate things a little better, I'd consider something more like this though:
#include <stdio.h>
typedef struct {
char *expression;
} program1;
char read_token(program1 *p) {
return *p->expression++;
}
int main() {
program1 p = { "-(1+3)*4/6" };
char ch;
while (ch = read_token(&p)) {
printf("next token: %c\n", ch);
printf("The remaining string is: %s\n", p.expression);
}
}
At least in my opinion, avoiding globals (among other things) more than makes up for the extra length.
In C, strings are stored as an array of characters.
char myStr[] = "String";
You can access any character by using an array index
char myChar = myStr[0];
printf("%c\n", myChar);

How can I test if a String contains the characters of a particular string?

I have a String with value
String rest="bac";
I have another String with value
String str="baack";
If i use
str.contains(rest);
it returns false. But i want the output to be true. As "baack" contains all the letters from string rest
Is it possible to do so? With or without this method?
Unfortunately, there is no standard method doing this, as far as I know.
If what you want is to check that the second string contains at least once every character of the first string, then you can check each character one by one with the following test:
boolean result = true;
for (char c : test.toCharArray()) {
result &= str.indexOf(c) > -1;
}
return result;
Or alternatively:
for (char c : test.toCharArray()) {
if (str.indexOf(c) == -1) {
return false;
}
}
return true;
It might not be optimal, but it works and it is simple to read.
Since the order is not important, your question turns to be whether the first set of character contains the second set of character.
// Initial the sets
Set<char> bigSet = new HashSet<char>(Arrays.asList(str));
Set<char> smallSet = new HashSet<char>(Arrays.asList(rest));
for (char c : smallSet) {
if(!bigSet.contains(c)){
return false;
}
}
return true;
Here is another way to make sure all characters from one string are in the second string. It is a lengthy way but it is one of the very basic ways to work with characters from String in java. I know it is not optimal but it serves the purpose.
String rest="bac";
String str="baack";
char[] strChar = str.toCharArray();
char[] restChar = rest.toCharArray();
int count = 0;
for(int i=0;i<restChar.length;i++){
for(int j=0;j<strChar.length; j++){
if(restChar[i] == strChar[j]){
count++;
}
}
}
if(count>=restChar.length){
System.out.println("All the characters from: "+rest+" are in: "+str);
}

String index out of range: -1 error with loops

I checked old topics with this problem and couldn't fix it.
This method is meant to compare two strings, and if every letter/character of the first string is found in the second string (not necessarily vice versa), then the method should return "true" (even if the second string has extra letters).
My idea is to check the letter at every index of the first string, see if it's in the second string, and if it is, delete that letter in both strings. When the first string runs out of letters (length equals zero) then the boolean should return true.
I think my loops or substring reaches out of range at some point.
public boolean isFound(String first, String second) {
StringBuilder sb1 = new StringBuilder(first);
StringBuilder sb2 = new StringBuilder(second);
first.toCharArray();
second.toCharArray();
for (int i = 0; i < first.length(); i++) {
int k = (first.substring(i, i + 1)).indexOf(second, i);
if (sb1.length() > 0) {
sb1.deleteCharAt(k);
sb2.deleteCharAt(k);
}
}
if (sb1.length() == 0) {
return true;
} else {
return false;
}
}
Ex: "at" and "tack" should return true, "tree" and "ere" should return false.
EDIT
After reviewing the comments, my new code is now this. It always returns false, though even with "tree" and "tree".
public boolean isFound(String first, String second){
StringBuilder sb2 = new StringBuilder(second);
for(int i=0;i<first.length();i++){
int k = sb2.indexOf(first,i);
if (k==-1)
return false;
else sb2.deleteCharAt(k);
}
return true;
}
You have a number of problems in your code.
You only need one StringBuilder version, that of second
The calls to toCharArray() are superfluous
You should not search for each character of first in second but in the mutable version of it sb2.
You are using indexOf wrong. This method should be called on the StringBuilder object to search for the first argument, you have it swapped.
The pseudocode that you can use is
isSuperAnagram(String first, String second) {
sb = StringBuilder(second)
for all chars in first {
k = search index of current char of first in sb
if(k == -1) // char is not in sb
return false
else
remove char at index k from sb
}
return true
}
please review your algorithm and code/usage of APIs
` first.toCharArray();`
second.toCharArray();
wont convert first,second to array, this API would return a character array.
(first.substring(i,i+1)).indexOf(second,i); will search the whole substring2 in first.substring.
review the algo/code correct this accordingly.please take care of all the edge/corner cases.
ideal method will be to use a hashmap.(on cost of extra space)
There is simple logic you can implement it your code
for(int i=0;i<sb1.length;i++)
{
for(int j=0;j<sb2.length;j++)
{
if(sb1.[i]==sb2.[j])
{
count++;
break;
}
if(count>=sb1.length)
{
System.out.print("match");
}
}
}
if you want more condition then post it below my post i wrote for only your follow example
Ex: "at" and "tack" should return true, "tree" and "ere" should return false.

Recursive removal of characters in Java

As an exercise, the code block below intends to recursively go through a string and remove all the of the "x" characters. It does that, but I would like to keep track of the newStr without passing it as a parameter in the method. Is there anyway to move it into the method body?
Thanks!
public static String deathToX(String str, String newStr) {
//look for x char
if(str.substring(0, 1).equals("x")) {
//do nothing
} else {
//add non-x char to newStr
newStr += str.charAt(0);
}
if(str.length() == 1) {
return newStr;
}
return deathToX(str.substring(1), newStr);
}
public static void main(String[] args) {
System.out.println("Return: " + deathToX("xnoxmore", ""));
}
Well, you could change the code to:
public static String deathToX(String str)
{
// Termination case
if (str.length() == 0)
{
return str;
}
// Work out whether or not we want the first character
String prefix = str.startsWith("x") ? "" : str.substring(0, 1);
// Let the recursive call handle the rest of the string, and return
// the prefix (empty string or the first character) followed by the
// x-stripped remainder.
return prefix + deathToX(str.substring(1));
}
Is that the sort of thing you were thinking of?
Of course, this is a horribly inefficient way of doing string manipulation, but I assume you're more interested in the recursive nature of things.
I would like to keep track of the newStr without passing it as a parameter in the method.
Why? Passing the intermediary result into the function is often required in functional-style recursive programming. What I do is make a function that handles the bulk of the work and accepts the accumulator, and make a wrapper function that calls the previous one with the required starter value:
private static String deathToX0(String str, String newStr) {
// the original implementation
}
public static String deathToX(String str) {
return deathToX(str, "");
}
As an aside, you might not want to use a String for the intermediate result because of the copying involved. A StringBuilder would be faster.
The short answer is yes... with recursion typically on the way down the tree you work out the bit at each level in this case blank or the current character. So the return statement should call itself recursively then at the bottom of the tree the answer you wanted is reconstructed by adding together the sections at each level.
public static String deathToX(String str){
if (!str.isEmpty()){
return (str.substring(0, 1).equals("x") ? "" : str.substring(0, 1)) + deathToX(str.substring(1));
}else{
return "";
}
}
public static void main(String[] args){
System.out.println("Return: " + deathToX("xnoxmore"));
}
In the sample above I used the shorthand if format to put it all on one line but you could expand it out. You should be able to see that the recursive function recurses on the return statement and I put in a special case for the last level. If you were to split it and put this levels answer in a local variable e.g. tmp then you would use:
return tmp + deathToX(str.substring(1));
Remember recursion means that the current execution is only paused until the lower ones finish so you can happily store info to recover on your way back up. Hope this helps :)
public class solution {
// Return the changed string
public static String removeX(String input){
if(input.equals("") || input.equals("x"))
return "";
String returnStr="";
removeX(input.substring(1));
for(int i=0;i<input.length();i++)
{
if(input.charAt(i)=='x')
continue;
else
returnStr+=input.charAt(i);
}
return returnStr;
}
}
This is my approach. This code goes to the end of the string, if it gets X as last string, it returns ""(nothing), then it checks the whole substring for "x", if its present in the string, it will continue, else it will append rest character to that string and it goes on.
Finally returns the updated string.!
Hope this helps..!! well, this is my first contribution here :)

Categories

Resources