PDA

View Full Version : [SOLVED] Replacing multiple things at a time in Java



blazemore
March 5th, 2010, 12:07 PM
I need to replace some characters in a given string with strings, eg. 'x' with "abcd", and 'y' with "bcde".
I can't use usual replace methods for this, because when I go to replace b, it will replace characters from the string that 'a' has already been replaced by.
I need both of these to operate on the same string at the same time, and not affect each others operation.
I hope I've made it clear, can anyone help?

Some Penguin
March 5th, 2010, 11:09 PM
If X and Y have common letters, or X and Y can overlap with each other, you probably need to define how you're going to resolve such things. e.g.


X = 'aaa';
b = 'aab';

How do you intend to handle 'aaaaab' ?


I would suggest taking something like the following approach:
1- Use a StringBuilder to accumulate pieces of the result.
2- Use java.util.regex.Pattern / Matcher to build a Matcher which will match *either*
of the sequences you want. Be sure to use \Q and \E to quote.
3- loop, initially on full string, using Matcher's find method.
- if you find a match, use the 'start' and 'end' methods to find out where the match was.
- Add everything that was before the match to the StringBuilder.
- Add the replacement string to the StringBuilder.
- Repeat on the rest of the string.
- Once you don't find a match, well, add the entire string and you're done.

blazemore
March 5th, 2010, 11:11 PM
If X and Y have common letters, or X and Y can overlap with each other, you probably need to define how you're going to resolve such things. e.g.


X = 'aaa';
b = 'aab';

How do you intend to handle 'aaaaab' ?


it would go to aaaaaaab, until the next iteration (I'm doing this multiple times, the string will get longer and longer)

hyperAura
March 6th, 2010, 04:03 PM
what u can do is parse each character and store it to an array.. after that u should check which letters need to be changed and store them in another array and then perform the changes at the appropriate positions in the array u have stored.. this way u won't have any problems.. :)

lets say u have "xubuntu is crazy"
so if u are replacing x and y in this case u mark in the array position[0] and position[15] that are going to be changed each by the appropriate substitute.. after u are done with the whole document u perform the substitution based on the positions u have stored..

blazemore
March 7th, 2010, 11:11 AM
what u can do is parse each character and store it to an array.. after that u should check which letters need to be changed and store them in another array and then perform the changes at the appropriate positions in the array u have stored.. this way u won't have any problems.. :)

lets say u have "xubuntu is crazy"
so if u are replacing x and y in this case u mark in the array position[0] and position[15] that are going to be changed each by the appropriate substitute.. after u are done with the whole document u perform the substitution based on the positions u have stored..

That's a great solution! I'll do that one I think.
If I have an array of characters, and I am replacing one of them with a string, will I need to split that string up into another array of characters and reinsert them into the original array?

LKjell
March 7th, 2010, 11:36 AM
I suggest you read something about Huffman codes

blazemore
March 7th, 2010, 01:39 PM
I suggest you read something about Huffman codes

Huffman codes are a way of encoding data for transmission in the smallest possible size. They're designed to minimise the number of bits needed to encode information, and have absolutely nothing to do with this problem, other than the fact that both are computer-science related.

EDIT: Did you mean HashMap?

LKjell
March 7th, 2010, 03:25 PM
The principle between Huffman coding and what you are trying to do is similar. The function you want to make is bijective otherwise you can't do multiple things at the same time.

blazemore
March 7th, 2010, 11:46 PM
Could someone give me a quick example of code?
For example replacing
all instances of 'X' with "XY"
all instances of 'Y' with "Y+"

LKjell
March 8th, 2010, 12:08 AM
public class Blaze {
public static void main (String [] args)
{
String str = "XYXYXYXYXYXY";
String decode = "";
Blaze blaze[] = new Blaze[str.length()];

for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'X')
blaze[i] = new X();
else
blaze[i] = new Y();
}
for (Blaze b : blaze) {
System.out.print(b.toString());
}
}
}

class X extends Blaze {
private String x = "XY";

public String toString(){
return x;
}
}

class Y extends Blaze {
private String y = "Y+";

public String toString(){
return y;
}
}

blazemore
March 8th, 2010, 12:17 AM
public class Blaze {
public static void main (String [] args)
{
String str = "XYXYXYXYXYXY";
String decode = "";
Blaze blaze[] = new Blaze[str.length()];

for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'X')
blaze[i] = new X();
else
blaze[i] = new Y();
}
for (Blaze b : blaze) {
System.out.print(b.toString());
}
}
}

class X extends Blaze {
private String x = "XY";

public String toString(){
return x;
}
}

class Y extends Blaze {
private String y = "Y+";

public String toString(){
return y;
}
}

That's an interesting way of doing it, with the classes.
Why not, instead of

blaze[i] = new X();

just do

blaze[i] = "XY";
Wouldn't that be a lot easier and have the same output?

LKjell
March 8th, 2010, 12:28 AM
I was using classes since I been thinking too much about OOP. But of course you do not need them. Here is another way. I merged them so the below one uses string class to do the work still the same.


public class Blaze {
public static void main (String [] args)
{
String str = "XYXYXYXYXYXY";
Blaze blaze[] = new Blaze[str.length()];

for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'X')
blaze[i] = new X();
else
blaze[i] = new Y();
}

for (Blaze b : blaze) {
System.out.print(b.toString());
}

////////////////////////////

System.out.println();
String decode[] = new String[str.length()];

for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'X')
decode[i] = "XY";
else
decode[i] = "Y+";
}

for (String b : decode) {
System.out.print(b);
}
}
}

class X extends Blaze {
private String x = "XY";

public String toString(){
return x;
}
}

class Y extends Blaze {
private String y = "Y+";

public String toString(){
return y;
}
}

blazemore
March 19th, 2010, 02:32 PM
Solved the problem.
Took in an uppercase string, replaced the relevent parts with lowercase in each rule ("X" with "fx" for example)
Converted back to uppercase after doing ALL the rules, ready for the next iteration.
Ugly hack? or elegant solution?
You decide.

LKjell
March 19th, 2010, 10:37 PM
Show us your code

blazemore
March 19th, 2010, 11:19 PM
Show us your code
str is a BufferedReader


...

while (str != null)
{
i++;
axiom = replace(axiom, str);
str = reader.readLine();
}

...


static String replace(String axiom, String rule)
/*
* This function takes an axiom, and a rule in the form
* x:foo
* where x should be replaced by foo
*/
{
// get the character we want to replace
String replaceChar = Character.toString(rule.charAt(0));

// get what we want to replace it with, in lowercase
String replaceString = rule.substring(2).toLowerCase();

// do the replacement
axiom = axiom.replaceAll(replaceChar, replaceString);
return string;
}

blazemore
March 19th, 2010, 11:43 PM
For those who are curious, working full LSystem code is here:
http://pastebin.com/dpv8Bq0A

LKjell
March 20th, 2010, 12:09 AM
What is the angle for?

blazemore
March 20th, 2010, 09:07 AM
What is the angle for?

That's for later. Same with the commented new GraphicDisplay

See, I'm writing an LSystem. The final string is like a set of rules, where each character represents a drawing instruction.
See here: http://en.wikipedia.org/wiki/L-system