Leetcode 833: String replacement depend upon index numbering - java

String index value accessThis question is a part of my previous question .
Example 1:
Input: S = "abcd", indexes = [0,2], sources = ["a","cd"], targets = ["eee","ffff"]
Output: eeebffff
Explanation: a starts at index 0 in S, so it's replaced by eee.
cd starts at index 2 in S, so it's replaced by ffff.
Example 2:
Input: S = "abcd", indexes = [0,2], sources = ["ab","ec"], targets = ["eee","ffff"]
Output: "eeecd"
Explanation: "ab" starts at index 0 in S, so it's replaced by "eee".
"ec" doesn't starts at index 2 in the original S, so we do nothing.
public class Q833 {
public static void main(String args[]){
String S="abcd";
int[] indexes = {0, 2};
String[]sources={"ab","cd"};
String[] targets = {"eee", "ffff"};
Solve833 ob833=new Solve833();
System.out.println(ob833.findReplaceString(S,indexes,sources,targets));
}
}
class Solve833{
public String findReplaceString(String S, int[] indexes, String[] sources, String[] targets) {
char[] array = S.toCharArray();
StringBuilder result = new StringBuilder();
int counter = 0;
String s = "";
for (String n:sources)
s+= n;
char[] c = s.toCharArray();
for (int i = 0; i < array.length; i++) {
if(array[indexes[counter]]==c[counter]){
result.append(targets[counter]);
if(counter<=indexes.length) {
counter++;
}
}
else
result.append(array[i]);
}
return result.toString();
}
}
Code Output: for 1st example
Expected output:Output: "eeebffff".
My output:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Leetcode.Solve833.findReplaceString(Q833.java:30) at
Leetcode.Q833.main(Q833.java:16)
Code Output:2nd example
Expected Output: "eeecd"
My Output: eeebcd. So here a b missing. How can I handle it?

Your problem is that you should NOT do array[indexes[counter]]==c[counter] to determine that if the i-thsource string is presented in the S at index i. Your juegement only check for the first character of the source string.
The key of this problem is how can we find the index correctly, as when we are trying to get the result, the index(where to replce the source string with target string) may change.
try this code:
public String findReplaceString(String S, int[] indexes, String[] sources, String[] targets) {
StringBuilder sb=new StringBuilder(S);
int[] offsets=new int[indexes.length];
for(int i=0;i<indexes.length;i++){
if(S.substring(indexes[i],indexes[i]+sources[i].length()).equals(sources[i])){
int offset=0;
for(int j=0;j<i;j++){
if(indexes[j]<indexes[i])
offset+=offsets[j];
}
sb.replace(indexes[i]+offset,indexes[i]+sources[i].length()+offset,targets[i]);
offsets[i]=targets[i].length()-sources[i].length();
}
}
return sb.toString();
}

You can change your method like this to print the result,
public class Q833 {
public static void main(String args[]) {
String S = "abcd";
int[] indexes = {0, 2};
String[] sources = {"a", "cd"};
String[] targets = {"eee", "ffff"};
Solve833 ob833 = new Solve833();
System.out.println(ob833.findReplaceString(S, indexes, sources, targets));
}
}
class Solve833 {
public String findReplaceString(String S, int[] indexes, String[] sources, String[] targets) {
StringBuffer result = new StringBuffer(S);
for (int i = 0; i < indexes.length; i++) {
if (sources[i].equals(result.substring(indexes[i], indexes[i] + sources[i].length()))) {
result.replace(indexes[i], indexes[i] + sources[i].length(), targets[i]);
if (i < indexes.length - 1)
indexes[i + 1] = indexes[i + 1] + targets[i].length() - sources[i].length();
}
}
return result.toString();
}
}

Related

Remix the String

I am stuck with this challenge, any help would be great.
'Create a function that takes both a string and an array of numbers as arguments. Rearrange the letters in the string to be in the order specified by the index numbers. Return the "remixed" string. Examples
remix("abcd", [0, 3, 1, 2]) ➞ "acdb"'
My attempt -
package edabitChallenges;
//Create a function that takes both a string and an array of numbers as arguments.
//Rearrange the letters in the string to be in the order specified by the index numbers.
//Return the "remixed" string.
public class RemixTheString {
public static String remix(String word, int[] array) {
char[] wordArray = word.toCharArray();
for (int i = 0; i < array.length; i++) {
char ch = ' ';
ch = wordArray[i];
wordArray[i] = wordArray[array[i]];
wordArray[array[i]] = ch;
}
String newString = new String(wordArray);
return newString;
}
public static void main(String[] args) {
System.out.println(remix("abcd", new int[] { 0, 3, 1, 2 }));
}
}
I would suggest just iterating the indices passed in the array[] input, and then building out the output string:
public static String remix(String word, int[] array) {
char[] wordArray = word.toCharArray();
StringBuilder output = new StringBuilder();
for (int i=0; i < array.length; i++) {
output.append(wordArray[array[i]]);
}
return output.toString();
}
public static void main(String[] args) {
System.out.println(remix("abcd", new int[] { 0, 3, 1, 2 })); // adbc
}
Here we use StringBuilder which exposes a handy append(char) method for adding one character at a time to the string in progress.

Java Algorithm regarding taking array of String and Integers to

I'm currently doing an activity that requires me to write this:
Write a definition for a static method stringHeads that inputs an array of ints p and a String s. For each of the ints n in p, the method builds the substring consisting of the first n characters in s (or the whole of s, if n is greater than the length of s). The method returns the array of these substrings.
My code is currently something like this:
public static String[] stringHeads(int[] p, String s) {
String[] rad = new String[p.length];
int e = 0;
for (int b : p)
e = b - 1
for (int de = 0; rad.length > de; de++)
rad[de] = s.substring(0,e);
for (String str : rad)
return str;
}
//Just ignore the rest
int[] a = {4, 2, 3, 2, 0 };
String b = "Radon"
stringHeads(a,b)
The output should be "Rado" , "Ra", "Rad", "Ra", "".
The error that I'm currently getting is that String cannot be converted to String[].
Basically my question is how to fix this error and if a better code can be written.
Three things:
e would be constant if you enter the second loop.
e could be larger than s.length() - you didn't handle this case.
You return a String instead of a String[]
And please always use braces if you use loops, even if the loop only contains one statement. It is much more readable and can avoid errors.
I think you will have to rethink your whole function. Don't know if it would be helpful to write the function for you.
Hints:
Write only one loop!
String[] rad = new String[p.length];
for (int i=0; i < p.length; i++) {
if (s.length() < ??) {
rad[i] = s.substring(0,??);
} else {
??
}
}
return rad;
I hope this will help you to get the answer yourself.
See my code below hope it helps:-
I provided the comments instead of explaining it in paragraph.
As for your error, you are returning String from method but expected is an array of String.
public static void main(String[] args){
int[] a = {4, 2, 3, 2, 0 };
String b = "Radon";
String[] output=stringHeads(a,b);
for(String s:output){
System.out.println(s);
}
}
Your method can be like below:
public static String[] stringHeads(int[] p, String s) {
String[] rad = new String[p.length];
int e = 0;
//Iterate over integer array
for(int index=0; index<p.length; index++){
//Extracting the integer value from array one by one
e=p[index];
//If integer value is greater than String length
if(e>s.length()){
//Put the entire String in String array
rad[index]=s;
}else{
//Put the Substring value with range 0 to e i.e. integer value
rad[index]=s.substring(0,e);
}
}
return rad;
}
You could simplify you code by just using a single iteration with an alternative variable.
public static void main (String[] args) throws java.lang.Exception
{
int[] a = {4, 2, 3, 2, 0 };
String b = "Radon";
String[] result = stringHeads(a,b);
for(String x : result) System.out.println(x);
//Or you can write a separate display method instead.
}
public static String[] stringHeads(int[] p, String s)
{
String[] rad = new String[p.length];
//Use this variable for array allocation/iteration.
int i=0;
//Simply iterate using this for-each loop.
// This takes care of array allocation/ substring creation.
for (int x : p)
rad[i++] = s.substring(0,x);
return rad;
}
Please check the code below
public static String[] stringHeads(int[] intArray, String str) {
String[] result = new String[intArray.length];
int count=0;
for (int intValue : intArray)
{
result[count] = str.substring(0,intValue);
count++;
}
return result;
} //Just ignore the rest
public static void main(String[] args) {
int[] a = {4, 2, 3, 2, 0 };
String b = "Radon";
String[] strArray=stringHeads(a,b);
int count=0;
for(String str:strArray)
System.out.println(++count+"" +str);
}
Change your method like this
public static String[] stringHeads(int[] p, String s) {
String[] rad = new String[p.length];
int e = 0;
for (int b : p) {
rad[e] = s.substring(0, b);
e++;
}
return rad;
}
For use this method
public static void main(String[] args) {
int[] a = {4, 2, 3, 2, 0};
String b = "Radon";
String[] stringHeads = stringHeads(a, b);
for (String stringHead : stringHeads) {
System.out.println(stringHead);
}
}
Output is
Rado
Ra
Rad
Ra
There is no need for the for loop that iterates through the integer array p
public static String[] stringHeads(int[] p, String s) {
String[] rad = new String[p.length];
for (int de = 0; de < p.length; de++){
if (p[de] < s.length())
rad[de] = s.substring(0,p[de]);
else
rad[de]=s;
}
return rad;
}
public static String[] stringHeads(int[] p, String s) {
String[] rad = new String[p.length];
int e = 0;
for (int b : p) {
if(b<=s.length()){
rad[e] = s.substring(0, b);
}
e++;
}
return rad;
}

Is there any method or idea that can select characters from a string at indices which are multiple of given 'n' to get the result string?

If I have this string
String str="characters";
the result would like following
result="caatr";
what I have done is selecting char by char from the given string until we get the result. The chars are selected at indices which are multiples of given n. Example: if n=2, the relevant indices to be selected are 0, 2, 4 ... and for n = 3, the indices are 0, 3, 6...
I have solved it in two ways and are almost the same but is there any other ways?
char[] arr = str.toCharArray();
String s="";
for(int i=0;i<str.length();i=i+n)
s=s+arr[i]+"";
the other one is
String result = "";
for (int i=0; i<str.length(); i = i + n)
result = result + str.charAt(i);
public static void main(String args[]) {
System.out.println(getResultOf("characters"));
}
private static String getResultOf(String input) {
boolean skip = false;
StringBuilder sb = new StringBuilder();
for (char ch : input.toCharArray()) {
if (!skip) {
sb.append(ch);
}
skip = !skip;
}
return sb.toString();
}

Sort ArrayList using predefined list of indices

I am trying to sort an ArrayList using a predefined array of indices.
My current example uses a copy of the original ArrayList for sorting and therefore is not scalable for ArrayLists of larger objects
package sortExample;
import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
public class sortExample {
public static void main(String[] args) {
String [] str = new String[] {"a","b","c","d"};
ArrayList<String> arr1 = new ArrayList<String>(Arrays.asList(str));
int [] indices = {3,1,2,0};
ArrayList<String> arr2 = new ArrayList(arr1.size());
for (int i = 0; i < arr1.size(); i++) {
arr2.add("0");
}
int arrIndex = 0;
for (int i : indices){
String st = arr1.get(arrIndex);
arr2.set(i, st);
arrIndex++;
}
System.out.println(arr1.toString());
System.out.println(arr2.toString());
}
}
For reusing same data, please see my solution:
public static void main(String[] args) {
String[] strs = new String[]{"a", "b", "c", "d"};
int[] indices = {3, 1, 2, 0};
String tmp;
for (int i = 0; i < strs.length; i++) {
if (i != indices[i]) {
tmp = strs[i];
strs[i] = strs[indices[i]];
strs[indices[i]] = tmp;
indices[indices[i]] = indices[i];
indices[i] = i;
}
}
for (int i : indices) {
System.out.print(i + " ");
}
System.out.println();
for (String str : strs) {
System.out.print(str + " ");
}
}
Output is:
0 1 2 3
d b c a
Alternate reorder in place based on cycles. Note that indices will be changed to {0,1,2,3}. I don't have Java installed (yet), so I converted working C++ code to what I think is proper Java syntax.
for (int i = 0; i < arr1.size(); i++) {
if(i != indices[i]) {
String st = arr1.get(i);
int t = indices[i];
int k = i;
int j;
while(i != (j = indices[k])){
arr1.set(k, arr1.get(j));
indices[k] = k;
k = j;
}
arr1.set(k, st);
indices[k] = k;
}
}
For this specific case {3,1,2,0}, all this does is swap 0 and 3. The longest cycle occurs when the indices are rotated, such as {3 0 1 2}, in which case st=arr1[0], arr1[0] = arr1[3], arr[3] = arr1[2], arr1[2] = arr1[1], arr1[1] = st.
There is a (a little bit) more simple solution:
int [] indices = {3,1,2,0};
ArrayList<String> arr2 = new ArrayList<String>();
for (int i = 0; i < arr1.size(); i++) {
arr2.add(arr1.get(indices[i]));
}
At the below, just use "indices" for a new array.
public class Sorting {
public static void main(String[] args) {
String [] str = new String[] {"a","b","c","d"};
int [] indices = {3,1,2,0};
String sorted [] = new String [str.length] ;
int i = 0;
for (String string : str) {
sorted[indices[i]] = string;
i++;
}
for (String string : sorted) {
System.out.print(string + " ");
}
}
}
prints: d b c a

Extraction of numerals from a string

I need to extract the numerals in a given string and store them in a separate array such that each index stores a individual number in the string.
Ex-"15 foxes chases 12 rabbits". I need the numbers 15 and 12 to be stored in a[0] and a[1].
String question=jTextArea1.getText();
String lower=question.toLowerCase();
check(lower);
public void check(String low)
{
int j;
String[] ins={"into","add","Insert"};
String cc=low;
for(int i=0;i<2;i++)
{
String dd=ins[i];
if(cc.contains(dd))
{
j=1;
insert(cc);
break;
}
}}
public void insert(String low)
{
String character = low;
int l=low.length();
int j[]=new int[20];
int m=0;
for(int k=0;k<=2;k++)
{
j[k]=0;
for(int i=0;i<l;i++)
{
char c = character.charAt(i);
if (Character.isDigit(c))
{
String str=Character.toString(c);
j[k]=(j[k]*10)+Integer.parseInt(str);
m++;
}
else if (Character.isLetter(c))
{
if(m>2)
{
break;
}
}}}
Regex is the best option for you.
//Compilation of the regex
Pattern p = Pattern.compile("(\d*)");
// Creation of the search engine
Matcher m = p.matcher("15 foxes chases 12 rabbits");
// Lunching the searching
boolean b = m.matches();
// if any number was found then
if(b) {
// for each found number
for(int i=1; i <= m.groupCount(); i++) {
// Print out the found numbers;
// if you want you can store these number in another array
//since m.group is the one which has the found number(s)
System.out.println("Number " + i + " : " + m.group(i));
}
}
You must import java.util.regex.*;
Assuming you can't use a Collection like a List, I would start by splitting on white space, using a method to count the numbers in that array (with a Pattern on digits), and then build the output array. Something like
public static int getNumberCount(String[] arr) {
int count = 0;
for (String str : arr) {
if (str.matches("\\d+")) {
count++;
}
}
return count;
}
And then use it like
public static void main(String[] args) {
String example = "15 foxes chases 12 rabbits";
String[] arr = example.split("\\s+");
int count = getNumberCount(arr);
int[] a = new int[count];
int pos = 0;
for (String str : arr) {
if (str.matches("\\d+")) {
a[pos++] = Integer.parseInt(str);
}
}
System.out.println(Arrays.toString(a));
}
Output is (as requested)
[15, 12]
To extract numerals from Strings use the following code:
String text = "12 18 100";
String[] n = text.split(" ");
int[] num = n.length;
for (int i =0; i < num.length;i++) {
num[i] = Integer.parseInt(n[i]);
};
All the string numbers in the text will be then integers
I believie it should be
String str = "12 aa 15 155";
Scanner scanner = new Scanner( str );
while( scanner.hasNext() )
{
if( scanner.hasNextInt() )
{
int next = scanner.nextInt();
System.out.println( next );
}
else
{
scanner.next();
}
}
scanner.close();

Categories