Fireye
Fireye

Reputation: 59

Switch the first and last letters of a string

I am making a program that will switch the first and last letters of a string, but when I run it, it just replaces the last letter with the first and that's it.

public static String swap(String String3) {
    //finds first & last letter of string
    String firstLetter =  String3.substring(0, 1);
    String lastLetter = String3.substring(String3.length() - 1);
    String a = String3.replace(firstLetter, lastLetter); 
    String z = a.replace(lastLetter, firstLetter );
    return z;
public static void main(String[] args){
    System.out.print("Enter your swap string: ");
    Scanner scan = new Scanner(System.in);
    String String3 = scan.nextLine();
    System.out.println(swap(String3));
    }

Can anyone tell me what i'm doing wrong?

Upvotes: 0

Views: 2698

Answers (9)

Lucas Sousa
Lucas Sousa

Reputation: 352

Let's see the cause of the problem and take a look to my approach that solves it.

The Problem

Below I described a little debug in the code of your swap method in the comments:

//considering String3 is equals to something like "a---z"
public static String swap(String String3) {
    System.out.println(String3);

    //this stores "a" value
    String firstLetter = String3.substring(0, 1);
    System.out.println("first: " + firstLetter);

    //this stores "z" value
    String lastLetter = String3.substring(String3.length() - 1);
    System.out.println("last: " + lastLetter);

    /*
    this replaces in the String3 source the character which is
    equals to firstletter (= "a" value) for lastLetter (= "z" value)

    the String3 field, which is "a-z" is turned to "z-z"

    Then, the final value stored is "z-z" 
     */
    String a = String3.replace(firstLetter, lastLetter);
    System.out.println("a: " + a);

    /*
    this replaces in the String3 source the character which is
    equals to lastLetter (= "z" value) for firstLetter (= "a" value)

    the a field, which is "z-z" is turned to "a-a"

    Then, the final value stored is "a-a" 
     */
    String z = a.replace(lastLetter, firstLetter);
    System.out.println("z: " + z);

    /*
    by returning the field z you only will get the same character 
    at start and end.
     */
    return z;
}

Solving the problem

I'm suggesting solving this using a one-liner method that replaces the characters using substring() method. Take a look:

/*
 * This avoid creating new fields and uses only the passed parameter.
 * 
 * - First we set the FIRST character of the s value to the LAST
 * character of the parameter;
 * 
 * - Second we concatenate this with a substring from s, which goes
 * from second character to the "semi last" (last previous);
 * 
 * - Then we can add the FIRST character at the END.
 */
public static String swapFirstAndLast(String s) {
    return s.charAt(s.length() - 1) + s.substring(1, s.length() - 1) + s.charAt(0);
}

Upvotes: 1

Lothar
Lothar

Reputation: 5449

String.replace replaces all occurences of the first character by the second. That's not what you want. As an example let's assume the text abc. The first replace will lead to cbc and the second will lead to aba which is what you've seen. An input string abab will result to aaaa as result.

You need to create a new String to get the swap you want:

char first = text.charAt(0);
char last = text.charAt(text.length() - 1);
return last + text.substring(1, text.length() - 2) + last;

Alternatively you can use Regular Expressions:

text.replaceAll("^(.)(.*)(.)$", "$3$2$1");

I skipped the test if the length of the input text is long enough, so an input text a will lead to an error with the first solution. The second solution would still work, because the regex doesn't match and no replacement will take place.

Upvotes: 2

Oleksii Zghurskyi
Oleksii Zghurskyi

Reputation: 4365

The problem in your solution are these 2 lines:

    String a = str.replace(firstLetter, lastLetter); // 1
    String z = a.replace(lastLetter, firstLetter); // 2

String.replace(char oldChar, char newChar) returns a new string resulting from replacing all occurrences of oldChar in this string with newChar. So, when you create String a you replace all chars equal to firstLetter by char equal to lastLetter.

Let's analyze with string "abbbabbb" as an input:

  • after executing line 1, you'll will get "bbbbbbbb" - all a got replaced by b
  • after executing line 2 there will be no effect, because you're trying to replace letter by itself (in the example input b by b - hence no effect).

One working solution would be the following:

import java.util.Scanner;

class Answer {

  public static void main(String[] args){
    System.out.print("Enter your swap string: ");
    try (Scanner scan = new Scanner(System.in)) {
      String str = scan.nextLine();
      String swapped = new String(swap(str, 0, str.length() - 1));
      System.out.println(swapped);
    }
  }

  private static char[] swap(String str, int i, int j) { 
    char[] chars = str.toCharArray(); 
    char tmp = chars[i]; 
    chars[i] = chars[j]; 
    chars[j] = tmp; 
    return chars; 
  }
}

The benefit of this approach - it can be used to swap any 2 letters in the String.

Upvotes: 0

Ruslan
Ruslan

Reputation: 6290

There is also quite concise solution(but not such fast) with stream api. Convert input string to list of character, then use Collections.swap method and back to string again:

List<Character> list = String3.chars().mapToObj(c -> (char)c).collect(Collectors.toList());
Collections.swap(list, 0, list.size() - 1);
String result = list.stream().map(Object::toString).reduce((s1, s2) -> s1 + s2).orElse("");

Upvotes: 0

Ruslan
Ruslan

Reputation: 6290

After the first replace you have string with lastLetter at the first and the last position.

String a = String3.replace(firstLetter, lastLetter);    // LASTxxxxLAST

After the second replace you obviosly has firstLetter here

String z = a.replace(lastLetter, firstLetter );    // FIRSTxxxxFIRST

To avoid this try to swap first and second replace and use replaceAll with $ sign and replaceFirst for the second replacement

...
String z = String3.replaceAll(lastLetter + "$", firstLetter);
String a = z.replaceFirst(firstLetter, lastLetter);
return a;

Upvotes: 0

sachin1410
sachin1410

Reputation: 1

e.g. Using "abc" as input, If you debug your code you will find out the mistake - the string before last replace is "cbc" and you are replacing "c" with "a"....hence the result

    String firstLetter = String3.substring(0, 1);//a
    String lastLetter = String3.substring(String3.length() - 1);//c
    String a = String3.replace(firstLetter, lastLetter);//cbc
    String z = a.replace(lastLetter, firstLetter);//aba

Upvotes: 0

chris01
chris01

Reputation: 12321

String3 = String3.substring(String3.length() - 1) +    // last
          String3.substring(1,String3.length() - 2) + // middle
          String3.substring(0, 1);    // first

Upvotes: 0

ItsPete
ItsPete

Reputation: 2368

You replace the first letter with the last in a, so when you look for that letter in z there are no instances to replace. It also would replace any instance of the last letter in a.

One method would be to substring String3 & prepend/append the needed character.

public static String swap(String String3) {
   //finds first & last letter of string
   String firstLetter =  String3.substring(0, 1);
   String lastLetter = String3.substring(String3.length() - 1);

   String3 = firstLetter + String3.substring(1);
   String3 = String3.substring(0, String3.length() - 1) + lastLetter;
   return String3;
}

public static void main(String[] args){
   System.out.print("Enter your swap string: ");
   Scanner scan = new Scanner(System.in);
   String String3 = scan.nextLine();
   System.out.println(swap(String3));
}

Upvotes: 1

user9643348
user9643348

Reputation:

You replaced the First letter with the last, so now the First and the last are equal. Then you replaced the last with the First, which is equal to the last, so the First and the last are equal.

Upvotes: 0

Related Questions