Overlay Strings In Java While Skipping Spaces - java

I want to overlay two strings together in Java to make one string. I already have a method to do something like this, but not exactly what I want.
For example, if I tell it to overlay "Hello World" with " Hi", I will get " Hiorld".
I want to be able to overlay "Hello World" with " Hi", and get "HelloHiorld"!
Here is the method I currently am using:
public static String overlayString(String str, String overlay, int start, int end) {
if (str == null) {
return null;
}
if (overlay == null) {
overlay = "";
}
int len = str.length();
if (start < 0) {
start = 0;
}
if (start > len) {
start = len;
}
if (end < 0) {
end = 0;
}
if (end > len) {
end = len;
}
if (start > end) {
int temp = start;
start = end;
end = temp;
}
return new StringBuffer(len + start - end + overlay.length() + 1)
.append(str.substring(0, start))
.append(overlay)
.append(str.substring(end))
.toString();
}
How would this method look if I wanted the method to avoid replacing characters with spaces, but still keep the positioning of the text?

You could put the first String into a StringBuffer, use a loop to check which characters in the second String are not spaces, then use the StringBuffer's .replace() method to replace these characters.
For example,
StringBuffer sb = new StringBuffer("Hello World");
sb.replace(5, 7, "Hi");
gives "HelloHiorld"

I can thing of two ways you might be able to achieve something like this...
First...
public static String overlay1(String value, String with) {
String result = null;
if (value.length() != with.length()) {
throw new IllegalArgumentException("The two String's must be the same length");
} else {
StringBuilder sb = new StringBuilder(value);
for (int index = 0; index < value.length(); index++) {
char c = with.charAt(index);
if (!Character.isWhitespace(c)) {
sb.setCharAt(index, c);
}
}
result = sb.toString();
}
return result;
}
Which allows you to pass to Strings of the same length and will replace all the "non-whitespace" content of the second in the first, something like...
overlay1("Hello World",
" Hi "));
Or you could specify the location you want the String to be overlaied, for example...
public static String overlay2(String value, String with, int at) {
String result = null;
if (at >= value.length()) {
throw new IllegalArgumentException("Insert point is beyond length of original String");
} else {
StringBuilder sb = new StringBuilder(value);
// Assuming a straight replacement with out needing to
// check for white spaces...otherwise you can use
// the same type of loop from the first example
sb.replace(at, with.length(), with);
result = sb.toString();
}
return result;
}
overlay2("Hello World",
"Hi",
5));

Related

How do I replace certain characters in a String without using .replace()?

I have to write a programme that encrypts and decrypts hidden messages. My problem is changing the alphabet. Originally I was going to use .replace() method, however, my teacher said we're not allowed to. The only methods we are allowed to do are,
.indexof();
.length();
.substring();
I have no idea how I'm supposed to do this. For example, Apple would be &**$# but how can I do this without .replace();
Below is the idea, can be optimised by yourself :
public String replace(String original, String toBeReplacedStr, String withStr) {
while(true) {
int i = original.indexOf(toBeReplacedStr);
if (i == -1) {
break;
}
original = original.substring(0, i) + withStr + original.substring(i + toBeReplacedStr.length());
}
return original;
}
Or can use the StringBuilder with recursion:
public String replace(String original, String toBeReplacedStr, String withStr) {
int i = original.indexOf(toBeReplacedStr);
if (i < 0) {
return original;
}
StringBuilder sb = new StringBuilder();
String before = original.substring(0, i);
String rawAfter = original.substring(i + toBeReplacedStr.length());
String replacedAfter = replace(rawAfter, toBeReplacedStr, withStr);
return sb.append(before).append(withStr).append(replacedAfter).toString();
}
I suggest you read source code of String.replace(char oldChar, char newChar) to implement your own method.
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) { // comment 1, aims to find
// first index of oldChar. You can use indexOf() to achieve this.
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j]; // comment 2, copy prefix chars
// before the oldChar to buf. You can use subString() to achieve this.
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c; // comment 3,
// replace oldChar with newChar, for other chars, just copy.
// You can use the thought above. I suggest you divide to 3
// methods to do "replace" thing.
i++;
}
return new String(buf, true);
}
}
return this;
}

Substring alternative

So I'm creating a program that will output the first character of a string and then the first character of another string. Then the second character of the first string and the second character of the second string, and so on.
I created what is below, I was just wondering if there is an alternative to this using a loop or something rather than substring
public class Whatever
{
public static void main(String[] args)
{
System.out.println (interleave ("abcdefg", "1234"));
}
public static String interleave(String you, String me)
{
if (you.length() == 0) return me;
else if (me.length() == 0) return you;
return you.substring(0,1) + interleave(me, you.substring(1));
}
}
OUTPUT: a1b2c3d4efg
Well, if you really don't want to use substrings, you can use String's toCharArray() method, then you can use a StringBuilder to append the chars. With this you can loop through each of the array's indices.
Doing so, this would be the outcome:
public static String interleave(String you, String me) {
char[] a = you.toCharArray();
char[] b = me.toCharArray();
StringBuilder out = new StringBuilder();
int maxLength = Math.max(a.length, b.length);
for( int i = 0; i < maxLength; i++ ) {
if( i < a.length ) out.append(a[i]);
if( i < b.length ) out.append(b[i]);
}
return out.toString();
}
Your code is efficient enough as it is, though. This can be an alternative, if you really want to avoid substrings.
This is a loop implementation (not handling null value, just to show the logic):
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
for (int i = 0 ; i < Math.max(you.length(), me.length()) ; i++) {
if (i < you.length()) {
result.append(you.charAt(i)); }
if (i < me.length()) {
result.append(me.charAt(i));
}
}
return result.toString();
}
The solution I am proposing is based on the expected output - In your particular case consider using split method of String since you are interleaving by on character.
So do something like this,
String[] xs = "abcdefg".split("");
String[] ys = "1234".split("");
Now loop over the larger array and ensure interleave ensuring that you perform length checks on the smaller one before accessing.
To implement this as a loop you would have to maintain the position in and keep adding until one finishes then tack the rest on. Any larger sized strings should use a StringBuilder. Something like this (untested):
int i = 0;
String result = "";
while(i <= you.length() && i <= me.length())
{
result += you.charAt(i) + me.charAt(i);
i++;
}
if(i == you.length())
result += me.substring(i);
else
result += you.substring(i);
Improved (in some sense) #BenjaminBoutier answer.
StringBuilder is the most efficient way to concatenate Strings.
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
int min = Math.min(you.length(), me.length());
String longest = you.length() > me.length() ? you : me;
int i = 0;
while (i < min) { // mix characters
result.append(you.charAt(i));
result.append(me.charAt(i));
i++;
}
while (i < longest.length()) { // add the leading characters of longest
result.append(longest.charAt(i));
i++;
}
return result.toString();
}

Substring between two same or different delimiters (when delimiters occur multiple times)

I need to fetch a sub string that lies between two same or different delimiters. The delimiters will be occurring multiple times in the string, so i need to extract the sub-string that lies between mth occurrence of delimiter1 and nth occurrence of delimiter2.
For eg:
myString : Ron_CR7_MU^RM^_SAF_34^
What should i do here if i need to extract the sub-string that lies between 3rd occurrence of '_' and 3rd occurence of '^'?
Substring = SAF_34
Or i could look for a substring that lies between 2nd '^' and 4th '_', i.e :
Substring = _SAF
An SQL equivalent would be :
substr(myString, instr(myString, '',1,3)+1,instr(myString, '^',1,3)-1-instr(myString, '',1,3))
I would use,
public static int findNth(String text, String toFind, int count) {
int pos = -1;
do {
pos = text.indexOf(toFind, pos+1);
} while(--count > 0 && pos >= 0);
return pos;
}
int from = findNth(text, "_", 3);
int to = findNth(text, "^", 3);
String found = text.substring(from+1, to);
If you can use a solution without regex you can find indexes in your string where your resulting string needs to start and where it needs to end. Then just simply perform: myString.substring(start,end) to get your result.
Biggest problem is to find start and end. To do it you can repeat this N (M) times:
int pos = indexOf(delimiterX)
myString = myString.substring(pos) //you may want to work on copy of myString
Hope you get an idea.
You could create a little method that simply hunts for such substrings between delimiters sequentially, using (as noted) String.indexOf(string); You do need to decide whether you want all substrings (whether they overlap or not .. which your question indicates), or if you don't want to see overlapping strings. Here is a trial for such code
import java.util.Vector;
public class FindDelimitedStrings {
public static void main(String[] args) {
String[] test = getDelimitedStrings("Ron_CR7_MU'RM'_SAF_34'", "_", "'");
if (test != null) {
for (int i = 0; i < test.length; i++) {
System.out.println(" " + (i + 1) + ". |" + test[i] + "|");
}
}
}
public static String[] getDelimitedStrings(String source,
String leftDelimiter, String rightDelimiter) {
String[] answer = null;
;
Vector<String> results = new Vector<String>();
if (source == null || leftDelimiter == null || rightDelimiter == null) {
return null;
}
int loc = 0;
int begin = source.indexOf(leftDelimiter, loc);
int end;
while (begin > -1) {
end = source
.indexOf(rightDelimiter, begin + leftDelimiter.length());
if (end > -1) {
results.add(source.substring(begin, end));
// loc = end + rightDelimiter.length(); if strings must be
// returned as pairs
loc = begin + 1;
if (loc < source.length()) {
begin = source.indexOf(leftDelimiter, loc);
} else {
begin = -1;
}
} else {
begin = -1;
}
}
if (results.size() > 0) {
answer = new String[results.size()];
results.toArray(answer);
}
return answer;
}
}

How to remove single character from a String by index

For accessing individual characters of a String in Java, we have String.charAt(2). Is there any inbuilt function to remove an individual character of a String in java?
Something like this:
if(String.charAt(1) == String.charAt(2){
//I want to remove the individual character at index 2.
}
You can also use the StringBuilder class which is mutable.
StringBuilder sb = new StringBuilder(inputString);
It has the method deleteCharAt(), along with many other mutator methods.
Just delete the characters that you need to delete and then get the result as follows:
String resultString = sb.toString();
This avoids creation of unnecessary string objects.
You can use Java String method called replace, which will replace all characters matching the first parameter with the second parameter:
String a = "Cool";
a = a.replace("o","");
One possibility:
String result = str.substring(0, index) + str.substring(index+1);
Note that the result is a new String (as well as two intermediate String objects), because Strings in Java are immutable.
No, because Strings in Java are immutable. You'll have to create a new string removing the character you don't want.
For replacing a single char c at index position idx in string str, do something like this, and remember that a new string will be created:
String newstr = str.substring(0, idx) + str.substring(idx + 1);
String str = "M1y java8 Progr5am";
deleteCharAt()
StringBuilder build = new StringBuilder(str);
System.out.println("Pre Builder : " + build);
build.deleteCharAt(1); // Shift the positions front.
build.deleteCharAt(8-1);
build.deleteCharAt(15-2);
System.out.println("Post Builder : " + build);
replace()
StringBuffer buffer = new StringBuffer(str);
buffer.replace(1, 2, ""); // Shift the positions front.
buffer.replace(7, 8, "");
buffer.replace(13, 14, "");
System.out.println("Buffer : "+buffer);
char[]
char[] c = str.toCharArray();
String new_Str = "";
for (int i = 0; i < c.length; i++) {
if (!(i == 1 || i == 8 || i == 15))
new_Str += c[i];
}
System.out.println("Char Array : "+new_Str);
To modify Strings, read about StringBuilder because it is mutable except for immutable String. Different operations can be found here https://docs.oracle.com/javase/tutorial/java/data/buffers.html. The code snippet below creates a StringBuilder and then append the given String and then delete the first character from the String and then convert it back from StringBuilder to a String.
StringBuilder sb = new StringBuilder();
sb.append(str);
sb.deleteCharAt(0);
str = sb.toString();
Consider the following code:
public String removeChar(String str, Integer n) {
String front = str.substring(0, n);
String back = str.substring(n+1, str.length());
return front + back;
}
You may also use the (huge) regexp machine.
inputString = inputString.replaceFirst("(?s)(.{2}).(.*)", "$1$2");
"(?s)" - tells regexp to handle newlines like normal characters (just in case).
"(.{2})" - group $1 collecting exactly 2 characters
"." - any character at index 2 (to be squeezed out).
"(.*)" - group $2 which collects the rest of the inputString.
"$1$2" - putting group $1 and group $2 together.
If you want to remove a char from a String str at a specific int index:
public static String removeCharAt(String str, int index) {
// The part of the String before the index:
String str1 = str.substring(0,index);
// The part of the String after the index:
String str2 = str.substring(index+1,str.length());
// These two parts together gives the String without the specified index
return str1+str2;
}
By the using replace method we can change single character of string.
string= string.replace("*", "");
Use replaceFirst function of String class. There are so many variants of replace function that you can use.
If you need some logical control over character removal, use this
String string = "sdsdsd";
char[] arr = string.toCharArray();
// Run loop or whatever you need
String ss = new String(arr);
If you don't need any such control, you can use what Oscar orBhesh mentioned. They are spot on.
Easiest way to remove a char from string
String str="welcome";
str=str.replaceFirst(String.valueOf(str.charAt(2)),"");//'l' will replace with ""
System.out.println(str);//output: wecome
public class RemoveCharFromString {
public static void main(String[] args) {
String output = remove("Hello", 'l');
System.out.println(output);
}
private static String remove(String input, char c) {
if (input == null || input.length() <= 1)
return input;
char[] inputArray = input.toCharArray();
char[] outputArray = new char[inputArray.length];
int outputArrayIndex = 0;
for (int i = 0; i < inputArray.length; i++) {
char p = inputArray[i];
if (p != c) {
outputArray[outputArrayIndex] = p;
outputArrayIndex++;
}
}
return new String(outputArray, 0, outputArrayIndex);
}
}
In most use-cases using StringBuilder or substring is a good approach (as already answered). However, for performance critical code, this might be a good alternative.
/**
* Delete a single character from index position 'start' from the 'target' String.
*
* ````
* deleteAt("ABC", 0) -> "BC"
* deleteAt("ABC", 1) -> "B"
* deleteAt("ABC", 2) -> "C"
* ````
*/
public static String deleteAt(final String target, final int start) {
return deleteAt(target, start, start + 1);
}
/**
* Delete the characters from index position 'start' to 'end' from the 'target' String.
*
* ````
* deleteAt("ABC", 0, 1) -> "BC"
* deleteAt("ABC", 0, 2) -> "C"
* deleteAt("ABC", 1, 3) -> "A"
* ````
*/
public static String deleteAt(final String target, final int start, int end) {
final int targetLen = target.length();
if (start < 0) {
throw new IllegalArgumentException("start=" + start);
}
if (end > targetLen || end < start) {
throw new IllegalArgumentException("end=" + end);
}
if (start == 0) {
return end == targetLen ? "" : target.substring(end);
} else if (end == targetLen) {
return target.substring(0, start);
}
final char[] buffer = new char[targetLen - end + start];
target.getChars(0, start, buffer, 0);
target.getChars(end, targetLen, buffer, start);
return new String(buffer);
}
*You can delete string value use the StringBuilder and deletecharAt.
String s1 = "aabc";
StringBuilder sb = new StringBuilder(s1);
for(int i=0;i<sb.length();i++)
{
char temp = sb.charAt(0);
if(sb.indexOf(temp+"")!=1)
{
sb.deleteCharAt(sb.indexOf(temp+""));
}
}
To Remove a Single character from The Given String please find my method hope it will be usefull. i have used str.replaceAll to remove the string but their are many ways to remove a character from a given string but i prefer replaceall method.
Code For Remove Char:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class Removecharacter
{
public static void main(String[] args)
{
String result = removeChar("Java", 'a');
String result1 = removeChar("Edition", 'i');
System.out.println(result + " " + result1);
}
public static String removeChar(String str, char c) {
if (str == null)
{
return null;
}
else
{
return str.replaceAll(Character.toString(c), "");
}
}
}
Console image :
please find The Attached image of console,
Thanks For Asking. :)
public static String removechar(String fromString, Character character) {
int indexOf = fromString.indexOf(character);
if(indexOf==-1)
return fromString;
String front = fromString.substring(0, indexOf);
String back = fromString.substring(indexOf+1, fromString.length());
return front+back;
}
BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
String line1=input.readLine();
String line2=input.readLine();
char[] a=line2.toCharArray();
char[] b=line1.toCharArray();
loop: for(int t=0;t<a.length;t++) {
char a1=a[t];
for(int t1=0;t1<b.length;t1++) {
char b1=b[t1];
if(a1==b1) {
StringBuilder sb = new StringBuilder(line1);
sb.deleteCharAt(t1);
line1=sb.toString();
b=line1.toCharArray();
list.add(a1);
continue loop;
}
}
When I have these kinds of questions I always ask: "what would the Java Gurus do?" :)
And I'd answer that, in this case, by looking at the implementation of String.trim().
Here's an extrapolation of that implementation that allows for more trim characters to be used.
However, note that original trim actually removes all chars that are <= ' ', so you may have to combine this with the original to get the desired result.
String trim(String string, String toTrim) {
// input checks removed
if (toTrim.length() == 0)
return string;
final char[] trimChars = toTrim.toCharArray();
Arrays.sort(trimChars);
int start = 0;
int end = string.length();
while (start < end &&
Arrays.binarySearch(trimChars, string.charAt(start)) >= 0)
start++;
while (start < end &&
Arrays.binarySearch(trimChars, string.charAt(end - 1)) >= 0)
end--;
return string.substring(start, end);
}
public String missingChar(String str, int n) {
String front = str.substring(0, n);
// Start this substring at n+1 to omit the char.
// Can also be shortened to just str.substring(n+1)
// which goes through the end of the string.
String back = str.substring(n+1, str.length());
return front + back;
}
I just implemented this utility class that removes a char or a group of chars from a String. I think it's fast because doesn't use Regexp. I hope that it helps someone!
package your.package.name;
/**
* Utility class that removes chars from a String.
*
*/
public class RemoveChars {
public static String remove(String string, String remove) {
return new String(remove(string.toCharArray(), remove.toCharArray()));
}
public static char[] remove(final char[] chars, char[] remove) {
int count = 0;
char[] buffer = new char[chars.length];
for (int i = 0; i < chars.length; i++) {
boolean include = true;
for (int j = 0; j < remove.length; j++) {
if ((chars[i] == remove[j])) {
include = false;
break;
}
}
if (include) {
buffer[count++] = chars[i];
}
}
char[] output = new char[count];
System.arraycopy(buffer, 0, output, 0, count);
return output;
}
/**
* For tests!
*/
public static void main(String[] args) {
String string = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";
String remove = "AEIOU";
System.out.println();
System.out.println("Remove AEIOU: " + string);
System.out.println("Result: " + RemoveChars.remove(string, remove));
}
}
This is the output:
Remove AEIOU: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
Result: TH QCK BRWN FX JMPS VR TH LZY DG
For example if you want to calculate how many a's are there in the String, you can do it like this:
if (string.contains("a"))
{
numberOf_a++;
string = string.replaceFirst("a", "");
}

Accurately retrieving data from a string

I have written a function in my program that allows me to retrieve strings and a separate string. ie, the string:
'copy "C:\Users\USERNAME\Desktop\file.bat" "C:\Users\"'
would result in having a string like: 'C:\Users\USERNAME\Desktop\file.bat' with the function getArgs(command, 0), and the other 'C:\Users\' with the function getArgs(command, 1).
The problem is that the function always seems to retrieve an empty string. Please be lenient on me, this is my first time using string manipulation functions in Java.
Notice: When I say empty I do not mean NULL, I mean "".
static String getArgs(String command, int argumentIndex) {
int start = 0;
int end = 0;
for (int i = 0; i <= argumentIndex; i++) {
start = command.indexOf("\"", end);
end = command.indexOf("\"", start);
if (i == argumentIndex) {
return command.substring(start, end);
}
}
return null;
}
Any ideas? Thanks.
#Darestium
According to your string it is clear that you've an empty space in between your paths. And also you've a problem with empty space.
To make it simple just split the string with space and the use the last 2 in the output.
Use `split(String arg)` in your case it is
String[] words=YOUR_STRING.split(" ");
for(int i=0;i<llength;i++)
{ if(words[i].startsWith("\"") && words[i].endsWith("\"")
{
word[i];YOUR DESIRED OUTPUT
}
}
Try the following correction. Keep in mind that your solution while work only if all the arguments in the command string are wrapped in quotes, even the ones without spaces. In the example you provided the first argument ('copy') must be also wrapped in quotes since you are using the quotes as delimiters.
static String getArgs(String command, int argumentIndex) {
int start = 0;
int end = -1;
for (int i = 0; i <= argumentIndex; i++) {
start = command.indexOf("\"", end+1)+1;
end = command.indexOf("\"", start+1);
if (i == argumentIndex) {
return command.substring(start, end);
}
}
return null;
}
Try this for a more generic solution which accepts arguments without quotes also
static String getArgs(String command, int argumentIndex) {
int start = 0;
int end = -1;
String delimiter = " ";
for (int i = 0; i <= argumentIndex && !command.equals(""); i++) {
if (command.startsWith("\"")) {
delimiter = "\"";
start = 1;
} else {
delimiter = " ";
start = 0;
}
end = command.indexOf(delimiter, start+1);
if (i == argumentIndex) {
end = (end==-1?command.length():end);
return command.substring(start, end).trim();
} else {
end = (end==-1?command.length():end+1);
command = command.substring(end).trim();
}
}
return null;
}

Categories

Resources