I'm trying to write a code that will give this output:
plusOut("12xy34", "xy") → "++xy++"
it returns a string where the characters in the original have been replaced by + except for where the 2nd string appears in the first string, but im having problems with my code. Here it is:
public String plusOut(String str, String word) {
String newString = "";
for (int i=0; i<str.length()-1; i++) {
if (str.substring(i, word.length()).equals(word)) {
newString = newString + str.substring(i, word.length());
}
else {
newString = newString + "+";
}
}
return newString;
}
There are some bugs in your code, see the comments.
public String plusOut(String str, String word) {
String newString = "";
// iterate up to length() to catch the last char if word.length() is 1
for (int i = 0; i < str.length(); i++) {
// use min() to avoid an IndexOutOfRange
String sub = str.substring(i, Math.min(i+word.length(), str.length()));
if (sub.equals(word)) {
newString = newString + sub;
// skip remaining characters of word
i += sub.length()-1;
}
else {
newString = newString + "+";
}
}
return newString;
}
In addition to that, I'd use a StringBuilder instead of the + operator.
You should really tell us what specific problems you are facing with your current code. In any case, here's how I would do it:
Split str on all occurrences of word to form a String[].
Loop through this array and append a number of '+' characters to newString corresponding to the length of whatever element of the array you're on.
On the same loop iteration, append word to newString, unless of course you're on the last element of the array.
This is what I mean:
public static String plusOut(String str, String word) {
StringBuilder newString = new StringBuilder(str.length());
String[] split = str.split(word);
for (int i = 0; i < split.length; i++) {
for (int j = 0; j < split[i].length(); j++)
newString.append('+');
if (i != split.length - 1)
newString.append(word);
}
return newString.toString();
}
Oh and just another tip: try to avoid appending to strings repeatedly within a loop. If you need to, use a StringBuilder instead.
System.out.println(plusOut("12xy34", "xy"));
++xy++
The best and simplest way I can think of is to use regular expressions and do a replaceAll.
General idea will be to get the second character build an regex with that and replaceAll with the regular expression and the replacement character.
public String plusOut(String str, String word) {
String regEx="[^"+Pattern.quote(word)+"]";
str.replaceAll(regEx,"+");
}
Note that the Pattern.quote() will make sure that your word won't screw the regex.
I didn't try out the code, but it should work without a problem.
This will do that for you.
public String plusOut(String str, String word) {
if(!str.contains(word)){
System.out.println("Word not found in string!");
return "Ut-oh!";
}
int indexOfStart = str.indexOf(word);
StringBuilder sb = new StringBuilder();
for(int i = 0; i<indexOfStart; i++){
sb.append('+');
}
sb.append(word);
for(int i=indexOfStart+word.length(); i < str.length(); i++){
sb.append('+');
}
return sb.toString();
}
So many answers! Well, here's mine as well:
public static String plusOut(String str, String word) {
String output = "";
int index = str.indexOf(word); // if -1 is returned, replace all chars
for (int i= 0; i < str.length(); i++) {
if(i == index)
{
output += word;
i += word.length() -1; // because i++ will still occurr
continue;
}
output += "+";
}
return output;
}
and test code in main:
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String test = "somethinghello12345.1!#";
System.out.println(test + " -> " + plusOut(test, "hello"));
test = "somethinghello12345.1!#";
System.out.println(test + " -> " + plusOut(test, "not gonna work"));
}
will produce the ouput:
somethinghello12345.1!# -> +++++++++hello+++++++++
somethinghello12345.1!# -> +++++++++++++++++++++++
Try this :
public static String plusOut(String word, String find) {
StringBuilder newStr = new StringBuilder();
int start = word.indexOf(find);
if (start > -1) {
for (int i = 0; i < start; i++) {
newStr.append("+");
}
newStr.append(find);
for (int i = 0; i < word.length() - (start + find.length()); i++) {
newStr.append("+");
}
}
return newStr;
}
Related
I am solving coding challenge on CodingBat.com. Here is the question:
Given a string and a non-empty word string, return a version of the
original String where all chars have been replaced by pluses ("+"),
except for appearances of the word string which are preserved
unchanged.
plusOut("12xy34", "xy") → "++xy++"
plusOut("12xy34", "1") → "1+++++"
plusOut("12xy34xyabcxy", "xy") → "++xy++xy+++xy"
Here is my attempted solution:
public String plusOut(String str, String word)
{
String ret = "";
for (int i = 0; i < str.length() - word.length() + 1; ++i) {
if (str.substring(i, i + word.length()).equals(word))
ret += word;
else
ret += "+";
}
return ret;
}
But is giving wrong outputs: giving too many plus signs. I don't understand why this shouldn't work. I suspect that the substring method is not returning enough matches, so the plus sign is appended. But I don't see why this maybe so.
I would use a StringBuilder to construct the result to avoid creating multiple String objects as String in java is immutable:
public String plusOut(String str, String word) {
StringBuilder result = new StringBuilder(str);
int len = str.length(), wordLen = word.length(), index = 0;
while(index < len){
if ( (index <= len-wordLen) && (str.substring(index, index+wordLen).equals(word))){
index += wordLen;
continue;
}
result.setCharAt(index++, '+');
}
return result.toString();
}
You were doing a few things wrong. I've corrected your code although there is probably a cleaner way to do this. I will explain what's changed below.
public static String plusOut(String str, String word)
{
String ret = "";
for (int i = 0; i < str.length(); ++i) {
int endIndex = i + word.length();
if (endIndex < str.length() + 1
&& str.substring(i, i + word.length()).equals(word)) {
ret += word;
i = i + word.length() - 1;
} else
ret += "+";
}
return ret;
}
First mistake is that you are not looping over the whole content of str and therefore never reach the last character of str.
Another problem is that once you find a word, you don't "jump" to the correct next index in the loop, but still continue looping over characters of the found word, which results in additional + characters in your result string.
i = i + word.length() - 1;
In your solution, the above will put you to the next index of a character inside str that you should be looking at. Example:
In string 12xy34xyabcxy looking for xy.
You will find that word xy starts at index 2 and ends at 3.
At that point you have result string ++xy after adding the found word to it.
Now, the problem begins. You still end up going over index 3 and adding an additional + because the next couple of characters do not add up to your word.
The 2 characters after the found xy also add + and you now have ++xy+++ which is incorrect.
endIndex < str.length() + 1
endIndex is named after what it is - end index of your substring.
This check prevents us from checking for xy when there aren't enough characters left in the string from current index to the last in order to make up xy, so we end up adding + for each remaining character instead.
Do it like this :
public static String plusOut(String str, String word)
{
String ret = "";
int i;
for (i = 0; i < str.length() - word.length() +1 ; i++) {
if (str.substring(i, i + word.length()).equals(word)) {
ret += word;
i += word.length() - 1;
}
else
ret += "+";
}
while (i < str.length()) {
ret += "+";
i++;
}
return ret;
}
Here is your solution
public String plusOut(String str, String word)
{
String ret = "";
for (int i = 0; i < str.length();) {
if (i + word.length()<= str.length() && str.substring(i, i + word.length()).equals(word)) {
ret += word;
i+=word.length();
}
else{
ret += "+";
i++;
}
}
return ret;
}
This is my method. It doesn't return anything. Please help, I don't know how to get the desired String name longer (the initial word string with hyphens between characters). `
public static String stretch(String word){
String longer = "" + word.charAt(0);
for (int i=1; i<=word.length()-1; i++){
longer += "-" + word.charAt(i);
}
return longer;
}
Below are three different ways of achieving your desired result, they are in ascending order in terms of performance + simplicity to understand i.e. stretch3 > stretch2 > stretch1.
import java.util.StringJoiner;
class Main {
public static void main(String[] args) {
System.out.println(stretch("test"));
System.out.println(stretch2("test"));
System.out.println(stretch3("test"));
}
// Using String Concatenation (bad)
public static String stretch(String word) {
String longer = "" + word.charAt(0);
for (int i = 1; i < word.length(); i++) {
longer += "-" + word.charAt(i);
}
return longer;
}
// Using StringBuilder (good)
public static String stretch2(String word) {
StringBuilder longer = new StringBuilder(word.substring(0,1));
for (int i = 1; i < word.length(); i++) {
longer.append("-" + word.charAt(i));
}
return longer.toString();
}
// Using StringJoiner (best)
public static String stretch3(String word) {
StringJoiner longer = new StringJoiner("-");
for (int i = 0; i < word.length(); i++) {
longer.add(word.substring(i,i+1));
}
return longer.toString();
}
}
Output:
t-e-s-t
t-e-s-t
t-e-s-t
Try it here!
Try if you want to insert a hyphen between letters (and not words)
"test sample".replaceAll("\\w(?=\\w)", "$0-");
Output -> t-e-s-t s-a-m-p-l-e
I am trying to replace all occurrences of a word in a string. However with this code I can only find the first occurrence of it and replace it. Is there any way to expand this code to replace the words in the entire string? I am attempting to do this without using the replace built in methods in Java since I already know how to use those function, I was wondering if there was another way to go about it.
public static String replace(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0) {
return input;
}
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return partBefore + newWord + partAfter;
}
First, you need a loop of some kind. Probably a while.
In the loop, since you're replacing the "old" string, you could just keep looping until you don't find it anymore. But if you want to avoid re-searching the first part of the string, or if you want to allow the replacement to contain the string it's replacing (without then looping infinitely), then once you've done each replacement, use String#indexOf(String str, int fromIndex), which lets you continue from the middle of the string.
There is a simple solution that uses recursion. Once you have replaced the word for the first time in the string, you can then replace the word in the partAfter part of the string by calling the replace method again:
public static String replace(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0) {
return input;
}
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return partBefore + newWord +
replace(old, newWord, partAfter); // <<-- Note recursion here
}
This only changes one line from your original source.
public static String replace(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0) {
return input;
}
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return partBefore + newWord + replace(old, newWord, partAfter );
}
However, it's more efficient to collect the bits and pieces in a StringBuilder.
public static String replace(String oldStr, String newStr, String input) {
StringBuilder sb = new StringBuilder();
int i;
int prev = 0;
while( (i = input.indexOf(oldStr, prev)) >= 0 ){
sb.append( input.substring(prev, i) ).append( newStr );
prev = i + oldStr.length();
}
sb.append(input.substring(prev));
return sb.toString();
}
First of all, don't use new for a variable name. It's a reserved word.
Second of all, in order to replace multiple occurences, you should have a loop.
Finally, it's better to create the new String using a StringBuilder, not String concatenation.
This is untested, but something like this should work:
public static String replace(String oldStr, String newStr, String input) {
int i = input.indexOf(oldStr);
if (i < 0) {
return input;
}
StringBuilder buffer = new StringBuilder();
int prev = 0;
while (i >= 0) {
String partBefore = input.substring(prev, i);
prev = i + oldStr.length();
buffer.append(partBefore);
buffer.append(newStr);
i = input.indexOf(oldStr, i + oldStr.length());
}
buffer.append(input.substring(i+oldStr.length()));
return buffer.toString();
}
Use Recursion:
public static String replaceAll(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0)
return input;
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return replaceAll(old, newWord, partBefore + newWord + partAfter);
}
Use do-While and go on replacing words:
public static String replaceAll(String old, String newWord, String input) {
boolean loop = true;
do {
int i = input.indexOf(old);
if (i > 0) {
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
input = partBefore + newWord + partAfter;
} else
loop = false;
} while (loop);
return input;
}
Here is the Code
import java.util.Scanner;
public class replacechar {
String line;
String s = "";
char from ;
char to ;
public replacechar()
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter The String");
line = scan.nextLine();
System.out.println("Enter The Character you want to changer");
from = scan.nextLine().charAt(0);
System.out.println("Enter the Character you want to replace with");
to = scan.nextLine().charAt(0);
replacecharacter(from,to);
}
public void replacecharacter(char f,char t)
{
for(int i =0;i< line.length();i++)
{
if(line.charAt(i) == f)
{
s += t;
}
else
{
s += line.charAt(i);
}
}
System.out.println(s);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
replacechar obj = new replacechar();
}
}
Not too sure if OP is still looking for answers but it might help others. Here is my code with just for loop and java's substring method...
public static void main(String ar[])
{
String str = "This is some string. replace lower case is with IS";
String pattern = "is";
String replaceWith = "IS"; // word to replace with
System.out.println(replaceString(str, pattern, replaceWith));
}
static String replaceString(String str, String pattern, String replaceWith) {
String temp = "";
String replacedString = ""; // Replaced String
int remainingString = 0; // append the rest of the string after last
// occurance of pattern.
for (int i = 0; i <= str.length() - pattern.length(); i++) {
temp = str.substring(i, i + 1);
if (str.substring(i, i + pattern.length()).equals(pattern)) {
temp = replaceWith + " ";
i += pattern.length();
}
remainingString = i;
replacedString += temp;
}
replacedString += str.substring(remainingString + 1, str.length());
return replacedString;
}
}
Posting this here incase somebody needs an implementation without using StringUtils helper methods.
static String replaceAll(String str, String oldW, String newW) {
// code here
char[] ch = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ch.length;i++) {
if (ch[i] == oldW.charAt(0) && checkForString(i+1,oldW,str)) {
sb.append(newW);
i += oldW.length() -1;
}
else
sb.append(ch[i]);
}
return sb.toString();
}
static boolean checkForString(int i, String str,String ogStr) {
int start = i;
for (int j = 1; j < str.length() && i < ogStr.length(); j++, i++) {
if (ogStr.charAt(i) != str.charAt(j))
return false;
}
return (i-start+1) == str.length()?true:false;
}
Given a string and a non-empty word string, return a version of the original String where all chars have been replaced by pluses ("+"), except for appearances of the word string which are preserved unchanged.
plusOut("12xy34", "xy") → "++xy++"
plusOut("12xy34", "1") → "1+++++"
plusOut("12xy34xyabcxy", "xy") → "++xy++xy+++xy"
I am having trouble trying to code a StringBuffer solution to this problem.
This is the original code to this:
public static String plusOut(String str, String word) {
int i = 0;
String str2 = "";
while (i < str.length() - word.length()+1)
if (!str.substring(i,i+word.length()).equals(word)) {
str2 += "+";
i++;
}
else {
str2 += word;
i += word.length(); //found pattern - skip
}
//if any remaining chars at end (guaranteed not to be pattern) replace
//with +s
if (i < str.length() && !str.substring(i).equals(word.substring(1))) {
for (int j = 0; j < word.length()-1; j++) str2 += "+";
}
return str2;
}
public String plusOut(String str, String word) {
String result = "";
int i = 0 ;
while(i < str.length() ) {
if (str.substring(i).startsWith(word)) {
result = result + word;
i = i + word.length();
} else {
result = result + "+" ;
i++;
}
}
return result ;
}
//StringBuilder
public String plusOut(String str, String word) {
StringBuilder strBuilder = new StringBuilder();
int i = 0 ;
while(i < str.length() ) {
if (str.substring(i).startsWith(word)) {
strBuilder.append(word);
i = i + word.length();
} else {
strBuilder.append("+");
i++;
}
}
return strBuilder.toString();
}
Here's what I came up with:
public String plusOut(String str, String word)
{
//Create a blank string.
String out = "";
//Create a counter to get the end amount.
int endAmt = 0;
//We can only manipulate from 0 to str.length() - word.length() in this for loop, because
//when searching for word in str, we can't go beyond the bounds.
for (int i = 0; i < str.length() - word.length(); i++)
{
//If we find word in str,
if (str.substring(i, i + word.length()).equals(word))
{
//We append word and increment 2 times further.
out = out + str.substring(i, i + word.length());
//increment i by 2 (one here, and one at the end)
i += word.length() - 1;
//We set the endAmt equal to the next iteration for future use when getting the rest
//of the amount later.
endAmt = i + 1;
}
//if it doesn't match, we change the character to a '+'
else
{
out = out.substring(0,i) + '+';
}
}
//Now, we finish the string after the searching for word in str.
//If the last substring is word, we add word to the mix.
if (str.substring(str.length() - word.length()).equals(word))
{
out = out + word;
}
//If it's not, then we refactor the string to after then last instance of word
else
{
out = out.substring(0, endAmt);
//and then we add the remaining amount of +'s
for (int i = 0; i < str.length() - endAmt; i++)
{
out = out + "+";
}
}
//finally, we return the string.
return out;
}
Here's a very simplified and easy to understand code
public static String plusOut(String str,String word){
StringBuffer b = new StringBuffer();
int indexOfWord = str.indexOf(word, 0);
for (int i = 0; i < str.length(); i++) {
if(i==indexOfWord){
b.append(word);
i=i+word.length()-1;//move index by word length
//get next index for the word
indexOfWord = str.indexOf(word,indexOfWord+word.length());
}else{
b.append("+");
}
}
return b.toString();
}
public String plusOut(String str, String word) {
String temp = str.replace(word, "+");
String newStr = "";
for (int i=0; i<temp.length(); i++)
{
if (temp.charAt(i) == '+')
{
newStr += word;
}
else
{
newStr += "+";
}
}
return newStr;
}
public String plusOut(String str, String word) {
String result = "";
for (int i = 0; i < str.length(); i++){
if (str.substring(i).length() >= word.length()
&& str.substring(i, i + word.length()).equals(word)) {
result += word;
i += word.length() - 1;
}
else if (str.length() < word.length()
|| str.substring(i).length() < word.length())
result += '+';
else
result += '+';
}
return result;
}
public String plusOut(String str, String word) {
String newStr = "";
int sLength = str.length();
int wLength = word.length();
for (int i = 0; i < sLength; i++){
if (i <= (sLength-wLength) && str.substring(i, i+wLength).equals(word)){
newStr += word;
i += (wLength-1);
continue;
}
newStr += "+";
}
return newStr;
}
Solution with regular expression:
public String plusOut(String str, String word) {
String regex = "(?<!(?=word).{0,M}).";
return str.replaceAll(
regex
.replace("word", java.util.regex.Pattern.quote(word))
.replace("M", String.valueOf(word.length() - 1)), "+");
}
Explanation:
Negative Lookbehind (?<!(?=word).{0,M}) - Assert that the Regex below does not match
Positive Lookahead (?=word) - Assert that the Regex below matches
Word matches the characters word literally (case sensitive)
. matches any character (except for line terminators)
{0,M} matches the characters {0,M} literally (case sensitive)
. matches any character (except for line terminators)
I need to replace a repeated char with $% followed by the char followed by $%.
e.g. "HELLO" will become "HE$%L$%O"
The following code that I wrote gives "HE$%L$%LO".
Please guide
int index=0;
String str1="";
String str2="";
String str4="";
String str5="";
for(int i=0;i<str.length();i++) {
char ch=str.charAt(i);
index=str.indexOf(ch);
if(index!=i) {
str4="$%"+str.charAt(index)+ "$%";
str1=str.charAt(index)+str5;
str2=str.replaceFirst(str1,str4);
}
}
return str2;
It looks like there's code missing because i can't see the duplicate character check, but what you want to do is go through str5 before you concat it and strip off all of the duplicate characters that are at the beginning. Then concat to your String.
Here a solution: Id solves the case if duplicates are more than 2 too. So remove all duplicates:
public class Converter {
public static void main(String[] args) {
final String result = replace("HELLO");
System.out.println("result = " + result);
}
private static String replace(String data) {
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < data.length();) {
int j = i + 1;
while (j < data.length() && data.charAt(i) == data.charAt(j)) {
j++;
}
if(j > i + 1) { // exist duplicate
stringBuilder.append("$%").append(data.charAt(i)).append("$%");
} else {
stringBuilder.append(data.charAt(i));
}
i = j;
}
return stringBuilder.toString();
}
}
And the result is:
result = HE$%L$%O