I want to write a code for reversing of string.
I know there are many methods for it. However, I want to try using Arrays. But I am having problem with the output.
Following is my code:
package practice_package;
public class Practice_Class {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1 = "Jeevan";
char[] a = s1.toCharArray();
String s2 = "satyasahithi";
char[] b = s2.toCharArray();
String rs1 = new String(reverse(a));
System.out.println("The reverse of '" + s1 + "' is: '" + rs1 + "'");
String rs2 = new String(reverse(b));
System.out.println("The reverse of '" + s2 + "' is: '" + rs2 + "'");
}
public static char[] reverse(char[] args) {
char[] r = args;
int i,j;
for(i=args.length-1,j=0; i>=0 && j<args.length; i--, j++) {
r[j]= args[i];
}
System.out.println(r);
return r;
}
}
And my output is:
navvan
The reverse of 'Jeevan' is: 'navvan'
ihtihaahithi
The reverse of 'satyasahithi' is: 'ihtihaahithi'
As you can see, only the first half of the string is being reversed while the second half remains as it is.
What's the wrong in the code. Can I initialize two variables at once in 'for' loop like that. Where am I missing the logic?
When you assign last to first, you lose the char, you should keep it in temporary and assign to other.
for(i=args.length-1,j=0; i>=0 && j<args.length/2; i--, j++) {
char t = r[j];
r[j]= r[i];
r[i] = t;
}
Use StringBuffer.reverse()
String s1 = "Jeevan";
StringBuffer a = new StringBuffer(s1);
System.out.println(a.reverse());
The logic inside your for loop. Lets consider the first iteration where i points to 5 (in case of string Jeevan) and j points to 0. When you say r[j]= args[i] J will be replaces with n and you lose the character J. This is the part where your logic went wrong. As a solution either you can take another array and store as given below
public static char[] reverse(char[] args) {
char[] r = new char[args.length];
int i,j;
for(i=args.length-1,j=0; i>=0 && j<args.length; i--, j++) {
r[j]= args[i];
}
System.out.println(r);
return r;
}
or as nr4bt suggested above.
Related
I have to compare two string arrays. If the any of the characters in myArray match a character in argArray then I need to swap the case of the character in myArray. I'm almost there but am getting extra output.
This is what I have so far -
public class Main {
public static void main(String[] args) {
Main ob = new Main();
ob.reverse("bcdxyz#3210.");
}
public String reverse(String arg) {
String reverseCap = "";
String myStr = "abc, XYZ; 123.";
char[] argArray = arg.toCharArray();
char[] myArray = myStr.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++){
if (myArray[i] == argArray[j] && Character.isLowerCase(myArray[i])){
reverseCap += Character.toUpperCase(myArray[i]);
} else if (myArray[i] == argArray[j] && Character.isUpperCase(myArray[i])){
reverseCap += Character.toLowerCase(myArray[i]);
} else {
reverseCap += myArray[i];
}
}
}
System.out.println(reverseCap);
return null;
}
I want reverseCap to be "aBC, xyz, 123." but am getting the following -
"aaaaaaaaaaaaBbbbbbbbbbbbcCcccccccccc,,,,,,,,,,,, XXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZZZZZ;;;;;;;;;;;; 111111111111222222222222333333333333............
".
I've been staring at this for hours so I figured it was time to ask for help before I pluck my eyes out.
Marce noted the problem of adding characters to reverseCap on every iteration. Here is a solution that solves that problem and performs the case changes in place. Checking for a match first and then changing the case simplifies the logic a bit. Note myArray[i] needs to be lowercased before checking against arg[i] because the former may be an uppercase character; this is not needed for argArray[j] because those characters are assumed to be all lowercase. Finally, once the inner loop has matched, further iterations of it are no longer needed.
public class Main {
public static void main(String[] args) {
Main ob = new Main();
String testStr = "abc, XYZ; 123.";
String testArg = "bcdxyz#3210.";
System.out.println(testStr + " using " + testArg + " =>");
System.out.println(ob.reverse(testStr, testArg));
}
public String reverse(String myStr, String myArg) {
char[] myArray = myStr.toCharArray();
char[] argArray = myArg.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++) {
if (Character.toLowerCase(myArray[i]) == argArray[j]) {
if (Character.isLowerCase(myArray[i])) {
myArray[i] = Character.toUpperCase(myArray[i]);
} else if (Character.isUpperCase(myArray[i])) {
myArray[i] = Character.toLowerCase(myArray[i]);
}
break;
}
}
}
return String.valueOf(myArray);
}
}
With this part
} else {
reverseCap += myArray[i];
}
you're adding a character to reverseCap with every iteration, regardless if the characters match or not.
In your specific example, you could just leave that out, since every character in myStr also appears in arg, but if you want to add characters to reverseCap, even if they don't appear in arg, you'll need a way of checking if you already added a character to reverseCap.
Change
String reverseCap = "";
to
char[] reverseCap = new char[myStr.length()];
and then for each occurrence of
reverseCap +=
change that to read
reverseCap[i] =
Finally, convert reverseCap to a String:
String result = String.valueOf(reverseCap);
You are currently returning null. Consider returning result, and moving the System.out.println(...) into the main() method.
Update:
I think a better way to approach this is to use a lookup map containing upper/lower case pairs and their inverse to get the replacement character. The nested for loops are a bit gnarly.
/**
* Example: for the string "bcdxyz#3210."
* the lookup map is
* {B=b, b=B, C=c, c=C, D=d, d=D, X=x, x=X, Y=y, y=Y, Z=z, z=Z}
* <p>
* Using a map to get the inverse of a character is faster than repetitively
* looping through the string.
* </p>
* #param arg
* #return
*/
public String reverse2(String arg) {
Map<Character, Character> inverseLookup = createInverseLookupMap(arg);
String myStr = "abc, XYZ; 123.";
String result = myStr.chars()
.mapToObj(ch -> Character.toString(inverseLookup.getOrDefault(ch, (char) ch)))
.collect(Collectors.joining());
return result;
}
private Map<Character, Character> createInverseLookupMap(String arg) {
Map<Character, Character> lookupMap = arg.chars()
.filter(ch -> Character.isLetter(ch))
.mapToObj(this::getPairs)
.flatMap(List::stream)
.collect(Collectors.toMap(Pair::key, Pair::value));
System.out.println(lookupMap);
return lookupMap;
}
private List<Pair> getPairs(int ch) {
char upperVariant = (char) Character.toUpperCase(ch);
return List.of(
new Pair(upperVariant, Character.toLowerCase(upperVariant)),
new Pair(Character.toLowerCase(upperVariant), upperVariant));
}
static record Pair(Character key, Character value) {
}
But if one is not used to the Java streaming API, this might look a bit gnarly too.
So I'm supposed to write a method to print the elements of an array. This is how I did it:
public static void join(String phrase[])
{
for (int i = 0; i < phrase.length; i++)
{
System.out.print(phrase[i] + " ");
}
}
This code works, but the prof says we must return a String with this method, and I don't know how to do it this way. I tried:
public static String join(String phrase[])
{
for (int i = 0; i < phrase.length; i++)
{
String sentence = System.out.print(phrase[i] + " ");
return sentence;
}
}
Error: incompatible types: void cannot be converted to java.lang.String
I know I cannot use .print because the method is not void. But then, how do I print?
Any ideas? This is a beginner Java class, so I don't know any other way.
This would also work:
public static String join(String phrase[])
{
String sentence = "";
for (int i = 0; i < phrase.length; i++)
{
sentence += phrase[i] + " ";
}
return sentence;
}
Here is what I'm doing:
1) Creating an empty string outside the for loop that will be used to hold all the values of the array
2) Adding each element of array (with a space after) to the string with sentence += phrase[i] + " ";
3) Once the for loop adds all the elements to the string, return it!
System.out.println return void
You can't assign void to a String variable. You simply want to assign the concatenated value, not print it.
String sentence = phrase[i] + " "
You declare sentence each iteration
You need to concatenate each cells, so declare a variable before the loop and append the String in the loop
String sentence = "";
for (int i = 0; i < phrase.length; i++){
sentence += phrase[i] + " "; //same as sentence = sentence + phrase[i] + " ";
return sentence;
}
You return a value inside the loop...
The loop will end at the return, so only the first value will be present in the String. Only return the value after it is fully done, after the loop.
String sentence = "";
for (int i = 0; i < phrase.length; i++){
sentence += phrase[i] + " ";
}
return sentence;
FYI: In the same issues, if the array is empty, no value are returned, so it will also be a problem since a method should return a String in every cases (or throw an exception`.
Shorter solution :
This loop can be done simply with String.join since Java 8
return String.join(" ", phrase);
Please do the following:
public static String join(String phrase[]){
StringBuilder str = new StringBuilder();
for(String s: phrase){
str.append(s);
}
System.out.println(str);
return str.toString();
}
Dont use += and add the values of the string array to another string as it will create a new object every time you add a new string to the preprocessed string. Instead use StringBuilder which is more memory efficient.
You can also do the following:
public static String join(String phrase[]){
String str = Arrays.toString(phrase);
System.out.println(str);
return str;
}
This will print each elements and return the entire result :
public static String printElements(String phrase[]) {
String result = "";
for (int i = 0; i < phrase.length; i++)
{
System.out.print(phrase[i] + " ");
result += phrase[i];
if( i != phrase.length - 1)
{
result += " ";
}
}
return result;
}
Alright so I've created an array of type int with size 10.
I've initialized it to random values between 1-100.
Now my task is to write a method named output which will take an int array as a parameter and displays all elements of the array in a column like this:
Output
arr[0] : 17
arr[1] : 42
etc etc, but when I do it in eclipse it says
i cannot be resolved to a variable,
so I was thinking of re-initializing it in my method, but wouldn't that give me a whole set of different numbers?
private int [] nums;
public UsingArrays(){
nums = new int [10];
for (int i = 0; i <nums.length; i++){
nums[i] = (int)(Math.random()*100)+1;
}
}
public String Output(){
String string;
string = "Arr[" + i + "]:" + nums[i];
return string;
}
}
i cannot be resolved to a variable
You forgot to surround the whole thing with a for loop that will be declaring & using that i variable :
public void Output(int[] array){
String string = "";
for(int i = 0; i < array.length; i++) {
string += "Arr[" + i + "]:" + array[i] + "\n"; // not recommended
}
System.out.println(string);
}
And in such cases, it would be better if you use a StringBuilder, so as to avoid creating new String instances at each iteration:
public void Output(int[] array){
StringBuilder sb = new StringBuilder();
for(int i = 0; i < array.length; i++) {
sb.append("Arr[" + i + "]:" + array[i] + "\n"); // Accumulate results
}
System.out.println(sb.toString()); // print final result
}
I do not know why you are trying to initialize int[] in a constructor and keep this array as a global variable when you said that 'method named output which will take an int array as a parameter'.
Here is a proper solution according to your requirements:
public static void main(String[] args) {
final int sizeOfArray = 10;
final int[] nums = new int[sizeOfArray];
//JAVA 7
for(int i = 0; i < sizeOfArray; i++){
nums[i] = (int)(Math.random() * 100) + 1;
}
//JAVA 8
IntStream.range(0,sizeOfArray)
.forEach(i -> nums[i] = (int)(Math.random() * 100) + 1);
output(nums);
}
private static void output(final int[] arrayToDisplay){
//JAVA 7
for(int i = 0; i < arrayToDisplay.length; i++){
System.out.printf("arr[%d] : %d \n",i,arrayToDisplay[i]);
}
//JAVA 8
IntStream.range(0,arrayToDisplay.length)
.forEach(i -> System.out.printf("arr[%d] : %d \n",i,arrayToDisplay[i]));
}
You should always make sure that all variables initialized and have an appropriate type assigned to them (at least in Java). If I were you, I would stick to Java 7 version of the code above
This problem won't be complied because there is not definition of what 'i' means in output method.
Another solution can be :
public String Output(){
StringBuffer sb = new StringBuffer();
int i=0;
while(i<nums.length){
sb.append("Arr[" + i + "]:" + nums[i]);
System.out.println(sb.toString());
sb.clear();
}
}
Thanks for taking your time to look at my question. This is one of the methods I created for decrypting a message. This isn't the entire code, believe me I have been trying for hours messing with the code, I didnt just hop on here and hope you guys would do it for me, I'm just asking a HOW to do something!
Just so you guys know, I can't really change much from what I currently have because I'm limited based on the assignment.
My problem: I need to make any character that is an "x" equal a SPACE or " ". Basically I'm trying to hardcode every "x" within the string to become a space because it's not printing what it should be.
What I currently have:
public static String decryption(String s, int n)
{
int originalChar, decryptedChar;
String message = "";
char c;
for(int i = 0; i < s.length(); ++i)
{
c = s.charAt(i);
decryptedChar = (int)c;
if(decryptedChar + n > 126)
originalChar = 32 + ((decryptedChar + n) - 113);
// Problem here
if(c.equals("x"))
originalChar.equals(" ");
else
originalChar = decryptedChar + n;
message = message + (char)originalChar;
}//end for loop
return message;
}//end method
I marked the problem area. If anyone can tell me how to do this properly so that I can make any "x" equal " " instead that would be awesome! Thanks for your time.
your problem is with:
originalChar.equals(" ");
equals() method is a method that checks equality - it returns true if originalChar equals " ", and what matters in your case- it does not alter originalChar in any way, just compares it to " ".
if you want to set originalChar to be " ", you need to do originalChar = " "
In any case, a much easier solution would be:
s = s.replace("x"," ");
one of the problems is with .equals. That is not meant to do a comparison on a character, only Strings.
Further more below you try to assign a String to a character with ""s, a character assignment needs ''.
I dont get the encryption part so much so I mocked up just a simple replacement code.
Bonus: you may want to ensure both x and X are replaced.
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "xxistheXbestxandxmorexxHehehe";
int n = 100;
String message = decryption(s, n);
System.out.println(message);
}
public static String decryption(String s, int n)
{
int originalChar, decryptedChar;
String message = "";
String ret = "";
char c;
for(int i = 0; i < s.length(); ++i)
{
c = s.charAt(i);
decryptedChar = (int)c;
if(decryptedChar + n > 126)
originalChar = 32 + ((decryptedChar + n) - 113);
// Problem here
if(c =='x')
{originalChar = ' ';
c = ' ';}
else
{originalChar = decryptedChar + n;
c = c;}
message = message + (char)originalChar;
ret += c;
}//end for loop
//return message;
return ret;
}//end method
Use the method replaceAll of the String class.
For example:
String a = "AxBxCxD";
String b = a.replaceAll("x"," ");
String b is what you want, that is "A B C D". You need b, because replaceAll does not change a.
If you want to change a, you can set it to b:
a = b;
That's all :)
Is it possible to reverse String in Java without using any of the temporary variables like String, Char[] or StringBuilder?
Only can use int, or int[].
String reverseMe = "reverse me!";
for (int i = 0; i < reverseMe.length(); i++) {
reverseMe = reverseMe.substring(1, reverseMe.length() - i)
+ reverseMe.substring(0, 1)
+ reverseMe.substring(reverseMe.length() - i, reverseMe.length());
}
System.out.println(reverseMe);
Output:
!em esrever
Just for the fun of it, of course using StringBuffer would be better, here I'm creating new Strings for each Iteration, the only difference is that I'm not introducing a new reference, and I've only an int counter.
The objects of the Java String class are immutable - their contents cannot be altered after being created.
You will need at least two temporary objects - one for the final result and one for the intermediate values - even if you do find a way to avoid using a local variable.
EDIT:
That said, since you can use int[] you may be able to cheat.
Since char can be assigned to int, you can use String.charAt() to create an int array with the character values in reverse order. Or you may be allowed to use String.toCharArray() to get a char array that will be copied over to your int[] temporary.
Then you use the variable that holds the reference to your original string (or the result variable, if you are allowed one) to start from an empty string (easily obtainable with a direct assignment or String.substring()) and use String.concat() to create the final result.
In no case, however, will you be able to swap the characters in-place as you would do in C/C++.
EDIT 2:
Here's my version which does not use StringBuffer/Builders internally:
int r[] = new int[s.length()];
int idx = r.length - 1;
for (int i : s.toCharArray()) {
r[idx--] = i;
}
s = s.substring(0, 0);
for (int i : r) {
s = s.concat(String.valueOf((char)i));
}
String s = "Hello World!";
for(int i = 0; i < s.length(); i++)
{
s = s.substring(1, s.length() - i) + s.charAt(0) + s.substring(s.length() - i);
}
System.out.println(s); // !dlroW olleH
No temporary variables! :)
One of many ways:
String str = "The quick brown fox jumps over the lazy dog";
int len = str.length();
for (int i = (len-1); i >= 0; --i)
str += str.charAt(i);
str = str.substring(len);
System.out.println(str);
public String reverseStr(String str) {
if (str.length() <= 1) {
return str;
}
return reverseStr(str.substring(1)) + str.charAt(0);
}
Because you can use an int, you can assign an int a char value:
String aString = "abc";
int intChar = aString.charAt(0);
You will have to convert from the int back to the char to assign it to aString.charAt(2).
I'm sure you can figure it out from there.
First append the string to itself in reverse manner. Then take the second half out of it.
public class RevString {
public static void main(String[] args) {
String s="string";
for(int i=s.length()-1;i>=0;i--){
s+=s.charAt(i);
}
s=s.substring(s.length()/2, s.length());
System.out.println(s);
}
}
Without using any collection,StringBulider, StringBuffer or temp array reverse the string. Simple and crisp:
public static void main(String[] args) {
String test = "Hello World";
String rev = "";
Pattern p = Pattern.compile("[\\w|\\W]");
Matcher m = p.matcher(test);
while (m.find()) {
rev = m.group()+rev;
}
System.out.println("Reverse==" + rev);
}
Output
Reverse==dlroW olleH
Hope it helps :)
public class Test {
static St`enter code here`ring reverseString(String str) {
for (int i = 0; i < str.length() / 2; i++) {
if (i == 0) {
str = str.charAt(str.length() - 1 - i) + str.substring(i + 1, str.length() - 1 - i) + str.charAt(i);
} else {
str = str.substring(0, i) + str.charAt(str.length() - 1 - i)
+ str.substring(i + 1, str.length() - 1 - i) + str.charAt(i)
+ str.substring(str.length() - i, str.length());
}
}
return str;
}
public static void main(String args[]) {
String s = "ABCDE";
System.out.println(Test.reverseString(s));
}
}
String str = "Welcome";
for(int i=0;i<str.length();){
System.out.print(str.charAt(str.length()-1));
str = str.substring(0,str.length()-1);
}
Except for loop variables.
You can use class java.lang.StringBuilder:
String reservedString = new StringBuilder(str).reserve().toString();