• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 124
  • Last Modified:

wordsWithout

I am working on below challenge
http://codingbat.com/prob/p121236

Psedo code:
1. loop given array
2. if array element is equa to target element increment count by 1
3. form new array with above count
4. fill new array from original array
5. return new array

I wrote my code as below

public boolean hasOne(int n) {
  if(n%10==1){
 
 // if(n/10==1){
  return true;
 // }
  }
  return false;
 
}





I am not passing all tests
Expected      Run             hasOne(10) → true      false      X      
hasOne(22) → false      false      OK      
hasOne(220) → false      false      OK      
hasOne(212) → true      false      X      
hasOne(1) → true      true      OK      
hasOne(9) → false      false      OK      
hasOne(211112) → true      false      X      
hasOne(121121) → true      true      OK      
hasOne(222222) → false      false      OK      
hasOne(56156) → true      false      X      
hasOne(56556) → false      false      OK      
other tests
X      

How to improve/modify my design, code and any other alternate approaches. please advise
0
gudii9
Asked:
gudii9
  • 27
  • 8
  • 6
  • +3
4 Solutions
 
awking00Commented:
I'm a little confused. The question title is wordsWithout and the CodingBat link shows the wordsWithout challenge, but your failing tests show a hasOne method?
0
 
Bill BachPresidentCommented:
Your array count is going to be wrong.  Fix #2:
   2. if array element is NOT equal to target element increment count by 1

I agree with awking00 that your code is not from the same problem, so I ignored everything after the pseudocode.
0
 
awking00Commented:
Which challenge are you seeking help on? wordsWithout or hasOne?
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
awking00Commented:
For the hasOne challenge, notice that your only correct answers are where the number ends in 1 or doesn't contain a 1. You need to create a loop to modify the number so that you can test for the 10s, position, the 100s position, etc. in addition to the 1s position that already works. In pseudo code, something like this -
get the modulus 10 of the number, if it's 1 return true
if it's not, divide the number by 10 (note the resulting int will not contain any decimal places)
get the modulus 10 of the resulting number, if it's 1 return true
if it's not repeat the process for as long as the resulting num is greater than 0.
0
 
gudii9Author Commented:
oops i mean wordswithout

public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
 
   for(int i=0;i<words.length-1;i++){
     if(words[i]==target)
    targetCount++;
  }
  String[] arr=new String[targetCount];
  for(int j=0;j<words.length-1;j++){
    arr[j]=words[j];
    
  }
  return arr;
  
}

Open in new window


http://codingbat.com/prob/p121236

other one i got solution now
0
 
Bill BachPresidentCommented:
Still need to reverse the logic in #2 to != instead of ==.
Also, you are not supposed to copy the ENTIRE array -- just copy those elements that are != target.
0
 
gudii9Author Commented:
package com.solution;

import java.util.Arrays;

public class WordsWithout {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] words = { "a", "b", "c", "a" };
		System.out.println("value is-->" + Arrays.toString(wordsWithout(words, "a")));

	}

	public static String[] wordsWithout(String[] words, String target) {
		int targetCount = 0;

		for (int i = 0; i < words.length - 1; i++) {
			if (words[i] == target)
				targetCount++;
		}
		String[] arr = new String[targetCount];
		for (int j = 0; j < targetCount - 1; j++) {
			if (words[j] != target) {
				arr[j] = words[j];
			}

		}
		return arr;

	}

}

Open in new window

value is-->[null]

above results null some how
0
 
Bill BachPresidentCommented:
For the third time, please fix line 18 -- the NEW array will have a length equal to the original array length WITHOUT the indicated word, not with!

As a debug, verify that targetCount==2 at the end of the first loop.  It should be.

Finally, look again at line 22.  You need two counters, to iterate over the two arrays.
0
 
gudii9Author Commented:
ok
0
 
ozoCommented:
public String[] wordsWithout(String[] words, String target) {
  List<String> list = new ArrayList<String>();
  for (String word:words) {
    if( !target.equals(word) ){
      list.add(word);
    }
  }
  return   list.toArray(new String[0]);
}
0
 
Bill BachPresidentCommented:
Doesn't writing a complete set of code take the "challenge" out of this challenge?
0
 
gudii9Author Commented:
 return   list.toArray(new String[0]);

what is meaning of above line?
0
 
gudii9Author Commented:
You need two counters, to iterate over the two arrays.*/

why we need two counters and two arrays to iterate?
0
 
Bill BachPresidentCommented:
The original Pseudo code stated:
    4. fill new array from original array
When you are READING data from the source array, you need a counter to iterate over each individual element, right?  So, if your source array is 10 elements long, you need to go from 0 through 9.  However, your target array may be only 4 elements long.  In that case, you will keep a SEPARATE counter to maintain your position in the target array.

I suppose as long as we are giving answers, here's the way of doing it based on your code:
public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
 
   for(int i=0;i<words.length-1;i++){
     if(words[i]!=target)
    targetCount++;
  }
  String[] arr=new String[targetCount];
  for(int j=0, int t=0;j<words.length-1;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
  }
  return arr;
}

Open in new window


Note how we use the J counter to index over the source array, but we use T to specify the index into the target array.  Further, we only increment T when we actually add a word.

As for the other constructs in Ozo's implementation, these are a bit more advanced for a beginner.  As you are learning, you'll want to stick to the straightforward design.  As you get better and you understand the various shortcuts, you'll save time and/or make your code more efficient.  However, starting at that level will make learning more difficult.
0
 
gudii9Author Commented:
I got below error


Compile problems:


Error:      for(int j=0, int t=0;j<words.length-1;j++){
                   ^^^
Syntax error on token "int", delete this token


see Example Code to help with compile problems

I removed extra int as below

public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
 
   for(int i=0;i<words.length-1;i++){
     if(words[i]!=target)
    targetCount++;
  }
  String[] arr=new String[targetCount];
  for(int j=0, t=0;j<words.length-1;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
  }
  return arr;
}

Open in new window



Now i am failing few tests as below

Expected      Run            
wordsWithout(["a", "b", "c", "a"], "a") → ["b", "c"]      ["b", "c"]      OK      
wordsWithout(["a", "b", "c", "a"], "b") → ["a", "c", "a"]      ["a", "c"]      X      
wordsWithout(["a", "b", "c", "a"], "c") → ["a", "b", "a"]      ["a", "b"]      X      
wordsWithout(["b", "c", "a", "a"], "b") → ["c", "a", "a"]      ["c", "a"]      X      
wordsWithout(["xx", "yyy", "x", "yy", "x"], "x") → ["xx", "yyy", "yy"]      ["xx", "yyy", "yy"]      OK      
wordsWithout(["xx", "yyy", "x", "yy", "x"], "yy") → ["xx", "yyy", "x", "x"]      ["xx", "yyy", "x"]      X      
wordsWithout(["aa", "ab", "ac", "aa"], "aa") → ["ab", "ac"]      ["ab", "ac"]      OK      
other tests
X
0
 
gudii9Author Commented:
/*public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
   for(int i=0;i<words.length-1;i++){
     if(words[i]!=target)
    targetCount++;
   } 
   String[] arr=new String[targetCount];
  for(int j=0;j<targetCount-1;j++){
     if(words[j]!=target)
    arr[j]=words[j];
  }  return arr;
} */
public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
 
   for(int i=0;i<words.length-1;i++){
     if(words[i]!=target)
    targetCount++;
  }
  String[] arr=new String[targetCount];
  for(int j=0, t=0;j<words.length-1;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
  }
  return arr;
}

Open in new window

i was comparing your code with my code which are almost same except extra counter t as below

     arr[t++]=words[j];

I wonder why we need extra for loop  to find targetCount

for(int i=0;i<words.length-1;i++){
     if(words[i]!=target)
    targetCount++;
  }

Open in new window



cannot we define array as open length
i mean instead of as below
 String[] arr=new String[targetCount];
how about as below
 String[] arr=new String[];

later on however many not equal that many filled inside arr?

 
if(words[j]!=target)
        arr[t++]=words[j];

Open in new window

0
 
gudii9Author Commented:
return   list.toArray(new String[0]);

instead of above why cannot we return something like below

return   list.toArray(new String[1]);
or below

return   list.toArray(new String[2]);

why only 0??
0
 
sarabandeCommented:
I wonder why we need extra for loop  to find targetCount
the first loop is to find out how many items are to be copied. the second loop does the copy.

if you want to use only one loop you either need a dynamic array (list) as ozo has suggested or you use an array same length as the input array and return the array resized to the needed length.

pseudo code:

create target_array(size = words.length)
loop words using two counters n=0 and t=0, incrementing n for each step
    if words[n] != target then
           target_array[t] := words[n]
           increment(t)
    end if
end loop
resize target_array(size = t)
return target_array

Open in new window


you could use Array.Resize method to get a copy of the array resized to a wished size.

see http://www.dotnetperls.com/array-resize

Sara
0
 
gudii9Author Commented:
the first loop is to find out how many items are to be copied. the second loop does the copy.

but we are filling only till t++ right not all the way till end

if(words[j]!=target)
        arr[t++]=words[j];
0
 
gudii9Author Commented:
public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
 
   for(int i=0;i<words.length;i++){
     if(words[i]!=target)
    targetCount++;
  }
  String[] arr=new String[targetCount];
  for(int j=0, t=0;j<words.length;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
  }
  return arr;
}

Open in new window


above passed all tests. any improvements or alternate approaches?
0
 
gudii9Author Commented:
if you want to use only one loop you either need a dynamic array (list) as ozo has suggested

below solution i was not clear on return part
public String[] wordsWithout(String[] words, String target) {
  List<String> list = new ArrayList<String>();
  for (String word:words) {
    if( !target.equals(word) ){
      list.add(word);
    }
  }
  return   list.toArray(new String[0]);
}

Open in new window

we are creating string array and looping given words array to word and comparing with target if not equal filling array right.

In return why we are saying

 list.toArray(new String[0]);

why not

 list.toArray(new String[1]);//what is significance of 0 or 1 whatever number here?
0
 
gudii9Author Commented:
or you use an array same length as the input array and return the array resized to the needed length.

pseudo code:

create target_array(size = words.length)
loop words using two counters n=0 and t=0, incrementing n for each step
    if words[n] != target then
           target_array[t] := words[n]
           increment(t)
    end if
end loop
resize target_array(size = t)
return target_array
you mean like below?
public String[] wordsWithout(String[] words, String target) {
  
   
  String[] arr=new String[words.length];
  for(int j=0, t=0;j<words.length;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
        resizeArray(arr,t);
  }
  
//resizeArray(arr,t);


  return arr;
}

Open in new window


getting below error

Compile problems:


Error:      resizeArray(arr,t);
      ^^^^^^^^^^^
The method resizeArray(String[], int) is undefined


see Example Code to help with compile problems

please advise.

I followed one link example as below
http://javatechknowledge.blogspot.com/2013/10/how-to-resize-array-in-java.html
0
 
rrzCommented:
i was comparing your code with my code which are almost same except extra counter t
BillBach just copied your code and added to it. The problem is your terminations were wrong. Instead of
words.length-1

Open in new window

you should have used
words.length

Open in new window

0
 
rrzCommented:
In return why we are saying

  list.toArray(new String[0]);

 why not

  list.toArray(new String[1]);//what is significance of 0 or 1 whatever number here?
Check the API
http://docs.oracle.com/javase/8/docs/api/java/util/List.html#toArray-T:A- 
 But, you could  use  
return   list.toArray(new String[list.size()]);

Open in new window

0
 
gudii9Author Commented:
return   list.toArray(new String[list.size()]);

above is understandable where you are passing size and returning new llist


 list.toArray(new String[0]);

above is not clear in terms of using 0 there which is bit odd to me but works?
public String[] wordsWithout(String[] words, String target) {
 
   
  String[] arr=new String[words.length];
  for(int j=0, t=0;j<words.length;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
        resizeArray(arr,t);
  }
 
//resizeArray(arr,t);


  return arr;
}

Select all
 
Open in new window

getting below error

Compile problems:


Error:      resizeArray(arr,t);
      ^^^^^^^^^^^
The method resizeArray(String[], int) is undefined


see Example Code to help with compile problems

please advise.

how to fix resize issue
0
 
gudii9Author Commented:
so while converting list to array using list.toArray
return   list.toArray(new String[list.size()]);

why cannot we use as below(but only as new String?
   Integer list2[] = new Integer[arrlist.size()];

i thought size is simply number regardless of list is of string list or Integer list?
0
 
gudii9Author Commented:
public String[] wordsWithout(String[] words, String target) {
  List<String> list = new ArrayList<String>();
  for (String word:words) {
    if( !target.equals(word) ){
      list.add(word);
    }
  }
 // return   list.toArray(new String[0]);
// return   list.toArray(new String[list.size()]);
return      list.toArray(new Integer[arrlist.size()]);
  // Integer list2[] = new Integer[arrlist.size()];
  // list2 = arrlist.toArray(list2);
 // arrlist.toArray(list2);
 //return   list.toArray(new String[list.size()]);
}

Open in new window


when i tried as above getting below error

Compile problems:


Error:      return list.toArray(new Integer[arrlist.size()]);
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Type mismatch: cannot convert from Integer[] to String[]


see Example Code to help with compile problems

please advise
0
 
rrzCommented:
Error:      return list.toArray(new Integer[arrlist.size()]);
You don't want to do that. You have created
List<String> list = new ArrayList<String>();

Open in new window

So, you have to provide a String array.
return   list.toArray(new String[list.size()]);

Open in new window

That creates a new String array with list.size() elements.    

list.toArray(new String[0]);

 above is not clear in terms of using 0 there which is bit odd to me but works?
  It does look odd. But, the API(see link above here) states
If the list fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this list.
We could look at the source code for that method to see how they do that. But, I will just accept their word.  
The method resizeArray(String[], int) is undefined
Did you provide the code for that method along with the wordsWithout method? I think that should be a separate topic. So I won't try to analyze it here.
0
 
gudii9Author Commented:
public String[] wordsWithout(String[] words, String target) {
  List list = new ArrayList();
  for (String word:words) {
    if( !target.equals(word) ){
      list.add(word);
    }
  }
 // return   list.toArray(new String[0]);
// return   list.toArray(new String[list.size()]);
return list.toArray();
  // Integer list2[] = new Integer[arrlist.size()];
  // list2 = arrlist.toArray(list2);
 // arrlist.toArray(list2);
 //return   list.toArray(new String[list.size()]);
}

Open in new window


why i cannot i write simply without generics as above.

i am getting below error


Compile problems:


Error:      return list.toArray();
             ^^^^^^^^^^^^^^
Type mismatch: cannot convert from Object[] to String[]


see Example Code to help with compile problems
0
 
gudii9Author Commented:
Type mismatch: cannot convert from Object[] to String[]
i see method expecting String[] whereas i am returning Object[] instead with non generic method
0
 
rrzCommented:
Error:      return list.toArray();
              ^^^^^^^^^^^^^^
 Type mismatch: cannot convert from Object[] to String[]
You should look at the API at
http://docs.oracle.com/javase/8/docs/api/java/util/List.html#toArray-- 
That method returns a Object[] .  We can't cast a Object[] to a String[].  But, since the array actually contains Strings we can cast each element. Here is code that does that
public String[] wordsWithout(String[] words, String target) {
    List list = new ArrayList();
  for (String word:words) {
    if( !target.equals(word) ){
      list.add(word);
    }
  }
  Object[] objectArray = list.toArray();
  String[] stringArray = new String[objectArray.length];
  for (int i=0;i<stringArray.length;i++) stringArray[i]= (String) objectArray[i];
return stringArray;
}

Open in new window

0
 
gudii9Author Commented:
i see above api method is bit length
Object[] objectArray = list.toArray();
  String[] stringArray = new String[objectArray.length];
  for (int i=0;i<stringArray.length;i++) stringArray[i]= (String) objectArray[i];
return stringArray;

Open in new window

0
 
rrzCommented:
i see above api method is bit length
I don't understand that comment. Please explain what you meant.
0
 
gudii9Author Commented:
public String[] wordsWithout(String[] words, String target) {
  int targetCount=0;
 
   for(int i=0;i<words.length-1;i++){
     if(words[i]!=target)
    targetCount++;
  }
  String[] arr=new String[targetCount];
  for(int j=0, int t=0;j<words.length-1;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
  }
  return arr;
}

Open in new window


instead of == i have to use .equals and instead of != should i use like below
 
if(!(words[i].equals(target))){

Open in new window

0
 
gudii9Author Commented:
i see above api method is bit length
I don't understand that comment. Please explain what you meant.

i meant it seems using toArray(T[] a) better compared to toArray()

https://examples.javacodegeeks.com/core-java/util/list/java-list-to-array-example/
0
 
gudii9Author Commented:
public String[] wordsWithout(String[] words, String target) {
  int count=0;
 for(int i=0;i<words.length;i++){
   if(!(words[i].equals(target))){
     count++;
   }
 }
 
 String[] arr=new String[count];
 for(int i=0,t=0;i<words.length;i++){
   if(!(words[i].equals(target))){
     arr[t++]=words[i];
   }
 }
 return arr;
}

Open in new window

above also passing all tests.

any other improvements or alternate approaches? otherwise i will close this question
0
 
gudii9Author Commented:
for strings always use .equals right not ==
0
 
rrzCommented:
instead of == i have to use .equals and instead of != should i use like below
When we want to compare String content, we use the String methods equals.  
When we want to compare one int to another int , we use == or !=.
0
 
gudii9Author Commented:
agree
0
 
rrzCommented:
for strings always use .equals right not ==
Yes.  To be more precise,
string is not String. If you talking about the java object String, then use capitalization. That way everybody knows what you are referring to.
0
 
awking00Commented:
rrz has provide a good method although I think the last part could be shortened.
Remove the object array, then simply
String[] stringArray = new String[list.size()];
return list.toArray(stringArray);
0
 
awking00Commented:
Forget my last comment, I didn't see all of the previous statements, including rrz's comment to use list.toArray. There are just too many comments to keep up with :-)
0
 
gudii9Author Commented:
Remove the object array, then simply
String[] stringArray = new String[list.size()];
return list.toArray(stringArray);

you mean like below

public String[] wordsWithout(String[] words, String target) {
  ArrayList list=new ArrayList();
 for(String word:words){
   if(!word.equals(target)){
     list.add(word);
   }
 }
 String[] stringArray = new String[list.size()];
return list.toArray(stringArray);
// return al.toArray(stringArray);
}



/*public String[] wordsWithout(String[] words, String target) {
    List list = new ArrayList();
  for (String word:words) {
    if( !target.equals(word) ){
      list.add(word);
    }
  }
  Object[] objectArray = list.toArray();
  String[] stringArray = new String[objectArray.length];
  for (int i=0;i<stringArray.length;i++) stringArray[i]= (String) objectArray[i];
return stringArray;
}*/

Open in new window


i am getting error as below

Compile problems:


Error:	return list.toArray(stringArray);
	       ^^^^^^^^^^^^^^^^^^^^^^^^^
Type mismatch: cannot convert from Object[] to String[]


see Example Code to help with compile problems

Open in new window

0
 
gudii9Author Commented:
so only way to use toArray is going through objArray then strArray?

public String[] wordsWithout(String[] words, String target) {
  ArrayList list=new ArrayList();
 for(String word:words){
   if(!word.equals(target)){
     list.add(word);
   }
 }
 Object[] objArray=list.toArray();
 String[] strArray=new String[objArray.length];
 for(int i=0;i<strArray.length;i++) strArray[i]=(String)objArray[i];
 return strArray;
// String[] stringArray = new String[list.size()];
//return list.toArray(stringArray);
// return al.toArray(stringArray);
}

Open in new window

0
 
awking00Commented:
You just need to change this -
 ArrayList list=new ArrayList();
to this -
List<String> list = new ArrayList<String>();
0
 
gudii9Author Commented:
public String[] wordsWithout(String[] words, String target) {
  
   
  String[] arr=new String[words.length];
  for(int j=0, t=0;j<words.length;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
        resizeArray(arr,t);
  }
  
//resizeArray(arr,t);


  return arr;
}

Open in new window


above resize approach is not working. please advise. Getting below error?

resizeArray(arr,t);
      ^^^^^^^^^^^
The method resizeArray(String[], int) is undefined
0
 
rrzCommented:
The method resizeArray(String[], int) is undefined
The compiler can't find the resizeArray method.   Here is working code. A simple "thank you" will do.
import java.util.Arrays;
public class WordsWithout{
	public static void main(String[] args){
	    System.out.println(" first test ");
		String[] first = new String[]{"a", "b", "c", "a"};
		System.out.println(" input ([a, b, c, a], a) gives output of " + Arrays.toString(wordsWithout(first, "a")));
		System.out.println(" second test ");
		String[] second = new String[]{"a", "b", "c", "a"};
		System.out.println(" input ([a, b, c, a], b) gives output of " + Arrays.toString(wordsWithout(second, "b")));
	}
public static String[] wordsWithout(String[] words, String target) {
  String[] arr=new String[words.length];
  int t = 0;
  for(int j=0;j<words.length;j++){
    if(words[j]!=target)
        arr[t++]=words[j];
  } 
  return (String[])resizeArray(arr,t);
}
 public static Object resizeArray (Object oldArray, int newSize) {
    int oldSize = java.lang.reflect.Array.getLength(oldArray);
    Class elementType = oldArray.getClass().getComponentType();
    Object newArray = java.lang.reflect.Array.newInstance(elementType,newSize);
    int preserveLength = Math.min(oldSize,newSize);
    if (preserveLength > 0)
		System.arraycopy (oldArray,0,newArray,0,newSize);
    return newArray; 
 }
}

Open in new window

The output:
 first test
 input ([a, b, c, a], a) gives output of [b, c]
 second test
 input ([a, b, c, a], b) gives output of [a, c, a]
0
 
gudii9Author Commented:
thank you. it was nice work
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 27
  • 8
  • 6
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now