Hartja February 2016

Java replace method problems

I am trying to do a project for my computer science class called "Encryption/Decryption"

The code goes as follows

import java.io.*; 
import java.util.*; 
import java.io.*; 
import java.util.*; 

public class Tester { 
public static void main(String args[]) { 
    Scanner kbReader = new Scanner(System.in); 
    System.out.print("Enter a sentence that is to be encrypted: "); 
    String sntnc = kbReader.nextLine(); 
    System.out.println("Original Sentence = " + sntnc); 

    Crypto myCryptObj = new Crypto(); 
    String encryptdSntnc = myCryptObj.encrypt(sntnc); 
    System.out.println("Encrypted sentence = " + encryptdSntnc); 

    String decryptdSntnc = myCryptObj.decrypt(encryptdSntnc); 
    System.out.println("Decrypted sentence = " + decryptdSntnc); 
  } 
} 

class Crypto { 
 public String encrypt(String sntnc) { 
    sntnc = sntnc.replace("m", "ssad"); 
    sntnc = sntnc.replace("b", "dug>?/");
    sntnc = sntnc.replace("g", "jeb..w"); 
    sntnc = sntnc.replace("v", "ag',r"); 
    return sntnc; 
} 

public String decrypt(String sntnc) { 
    sntnc = sntnc.replace("ag',r", "v"); 
    sntnc = sntnc.replace("ssad", "m"); 
    sntnc = sntnc.replace("jeb..w", "g");  
    sntnc = sntnc.replace("dug>?/", "b"); 
    return sntnc; 
  } 
}

The problem isn't in the Tester class, it's in the Crypto class.

The input is: This is a very big morning. And the code should output:

Enter a sentence that is to be encrypted: This is a very big morning.
Original Sentence: This is a very big morning.
Encrypted sentence: This is a ag',rery dug>?/ijeb..w ssadorninjeb..w.
Decrypted sentence: This is a very big morning.

But instead the Encrypted sentence line is printing:

This is a ag',rery dujeb..w>?/ijeb..w ssadorninjeb..w.

The sntnc.replace method is replacing the already replaced letters.

Answers


Tunaki February 2016

The problem comes from your logic of replacing the strings:

sntnc = sntnc.replaceAll("b", "dug>?/");  // <-- replaces with a "g" here
sntnc = sntnc.replaceAll("g", "jeb..w");  // <-- so that "g" is also getting replaced here

A simple solution is to drop using replaceAll. Making your code works by re-ordering the replaceAll calls is very fragile: you don't know that in the future someone will change what is getting replaced and break everything.

The solution is much simpler when building the String by iterating over the characters. Because we have an distinct temporary container when building the Strings, there are no conflicts when the replacements are happening.

public String encrypt(String sntnc) { 
     StringBuilder sb = new StringBuilder();
     for (char ch : sntnc.toCharArray()) {
         if (ch == 'm') sb.append("ssad");
         else if (ch == 'b') sb.append("dug>?/");
         else if (ch == 'g') sb.append("jeb..w");
         else if (ch == 'v') sb.append("ag',r");
         else sb.append(ch);
     }
     return sb.toString();
} 


Rahul February 2016

Instead of using sntnc = sntnc.replaceAll("m", "ssad"); Try replacing each character with the appropriate encryption code and then save it in another string and return it.

`String s = "xyz";
for(int i = 0; i < sntnc.length(); i++)
{
   char c = sntnc.charAt(i);
   // Do your code here saving it in a new string say sntnc2
}`
   return sntnc2;

May not be the most efficient method but using replaceAll("a","c") as you've done replaces each character a with c from the start to the end of the string.


Martín Muñoz del R&# February 2016

Your problem is that one replace intersect with other:

sntnc = sntnc.replace("g", "jeb..w"); 
sntnc = sntnc.replace("b", "dug>?/");

The first include a b and the second include a g even reorder the replaces will don't work.

You have to do all your replaces at once, try:

class Crypto { 
 public String encrypt(String sntnc) {    

    Pattern p = Pattern.compile("(m|g|b|v)");
    Matcher m = p.matcher(sntnc);
    StringBuffer sb = new StringBuffer();

    while (m.find()) {
        if(m.group(1).equals("m"))
            m.appendReplacement(sb, "ssad");
        if(m.group(1).equals("g"))
            m.appendReplacement(sb, "jeb..w");
        if(m.group(1).equals("b"))
            m.appendReplacement(sb, "dug>?/");
        if(m.group(1).equals("v"))
            m.appendReplacement(sb, "ag',r");
    }

    m.appendTail(sb);

    return sb.toString(); 
} 

Post Status

Asked in February 2016
Viewed 2,347 times
Voted 4
Answered 3 times

Search




Leave an answer