Remove the duplicate from the array (Deep Copy) Java - java

public static boolean testGetUniqueCheckedOutItems() {
String[] items = new String[]{"Carrot","Chicken","Chicken", "Tomato", "Onion","Carrot","Tomato"};
int size = 7;
String[] empty = {};
getUniqueCheckedOutItems(items,size,empty));
public static int getUniqueCheckedOutItems(String[] items, int size, String[] itemsSet) {
itemsSet = new String [items.length];
for (int i =0; i<items.length; i++) {
itemsSet[i] = items[i];
}
for (int i=itemsSet.length-1; i>=0; i--) {
for (int j = i-1; j>=0; j--) {
if (itemsSet[i].equals(itemsSet[j])) {
size--;
}
}
return size;
}
The code supposes to return the size which remove the duplicates in array. However, it suppose not to remove both duplicate, but just one. So in here, since duplicates are "carrot, chicken,tomato" Thus, it suppose to return 4. However, it only return 6.
Can anyone help me to solve this?
I been on this problem for like an hour and half now

This has several syntax errors so I'm not sure how you are obtaining any output.
The method testGetUniqueCheckedOutItems() does not have a closing brace
The method getUniqueCheckedOutItems() does not have a closing brace
and the method getUniqueCheckedOutItems(items,size,empty)); has an unexpected closing parenthesis.
The reason you would be getting the wrong value is that the return statement is inside of the outer for loop. So you prematurely return size. Did you incorrectly enter your code?

Related

How can I eliminate/remove a duplication of an object array element which is duplicated a ton of time in the array. (Return same array type)

I tried this for loop but when for duplicated element in the array the inner loop breaks and if more than 10 repeated element are place in the array then the outer-loop brakes.
I need to return an array of same object type since I need to use the methods to pick some values from it.
public Mode insT(Guide[] guide){
Guide[] guideVo = checkGuideDuplication(guide);
}
public Guide[] checkGuideDuplication (Guide[] guide){
for(int i = 0; i<guide.length-1; i++){
for(int j = i+1; i<guide.length; i++){
if(guide[i].getGuide().trim().equals(guide[j].getGuide().trim())){
guide = (Guide[]) ArrayUtils.remove(guide);
}
}
}
return guide;
}
You need to reset the inner index once you remove an element so it gets checked (and bounds-checked) again:
guide = (Guide[]) ArrayUtils.remove(guide);
j--;
You can avoid the inner loop entirely if you use a map to weed out duplicates:
public Guide[] checkGuideDuplication (Guide[] guide){
Map<String, Guide> uniques = new HashMap<>();
for(Guide g : guide){
uniques.putIfAbsent(g.getGuide().trim(), g);
}
return uniques.values().toArray(new Guide[0]);
}
The most performing O(N) solution would be to use Map as shown in shmosel's answer.
But if using Map is not an option due to some constraints/limitations (e.g. only arrays are allowed), another solution would be to set removed elements to null and count the number of deletions, then shift nulls to the end of the array and return a truncated array:
public Guide[] checkGuideDuplication (Guide ... guide) {
int deleted = 0;
for (int i = 0; i < guide.length-1; i++) {
if (null == guide[i]) {
continue;
}
String currGuide = guide[i].getGuide().trim();
for(int j = i + 1; j < guide.length; j++) {
if (null == guide[j]) {
continue;
}
if (currGuide.equals(guide[j].getGuide().trim())) {
guide[j] = null;
deleted++;
}
}
}
// shift remaining elements
for (int i = 0, j = 0; i < guide.length; i++) {
if (guide[i] != null) {
guide[j++] = guide[i];
}
}
return Arrays.copyOf(guide, guide.length - deleted);
}

IndexOutOfBoundsException in ArrayList Java

Whenever I try to run the code I get IndexOutOfBoundsException. I have tried numerous of ways fixing it but none of them have helped. The method should add a new String element "****" into ArrayList before every String which's length is equal to 4. In this case, it must add "****" before "5555".
Where could be the problem?
import java.util.ArrayList;
public class Main {
public static ArrayList<String> markLength4(ArrayList<String> list) {
int sum = 0;
for ( int i = 0; i < list.size(); i++) {
if (list.get(i).length() == 4) {
list.add(list.indexOf(i), "****");
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ddddddddddddd");
list.add("fffffffffffff");
list.add("5555fdgdfg");
list.add("5555");
list.add("5555");
System.out.println(markLength4(list));
}
}
list.indexOf(i) will return -1, since i doesn't appear in your list. Therefore adding an element at the -1 position will throw an exception.
If you change list.add(list.indexOf(i), "****") to list.add(i, "****");, you'll get an infinite loop that will end with OutOfMemoryError, since the newly added String also has a length() of 4, so another String will be added on the next iteration, and so on.
i is not in your arraylist - it is a list of String, not Integer. That means that list.indexOf(i) == -1.
From your description, I think you mean:
list.add(i, "****");
but you will also need to increment i, e.g.
list.add(i++, "****");
to avoid the infinite loop that Eran mentions.
Or, of course, you can iterate the list backwards, and avoid the infinite loop/need to change the loop variable inside the loop body:
for ( int i = list.size() - 1; i >= 0; i--)
{
if (list.get(i).length() == 4)
{
list.add(i, "****");
}
}
import java.util.ArrayList;
public class Test {
public static ArrayList<String> markLength4(ArrayList<String> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).length() == 4) {
list.add(i++, "****");
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ddddddddddddd");
list.add("fffffffffffff");
list.add("5555fdgdfg");
list.add("5555");
list.add("5555");
list = markLength4(list);
for (String x : list) {
System.out.println(x);
}
}
}
You'll loop forever this way, because there's 4-lengthened strings forward and you keep adding...
You can solve this by looping from the end, but you'll have to be careful with your index(you should add and increment the index to avoid that)
After Editing list.add(i++,"****"); the code should work just fine.
Notable
If you want to add before use i++;.
If you want to add after your match use ++i;.
list.indexOf(i) is not present in the list . It will produce -1
-1 is not available in ArrayList
Replace the Line
list.add(list.indexOf(i), "****");
with the following line
list.set(i, "****");
It replace the existing content of the List with new element in the index of i with new element i.e (****)
list.indexOf(i) where i is an int and therefore not in your list will throw your error as stated in comments (index -1).
use either of the following:
list.add("str") to add a String to the end of the list
OR
list.set(i, "****") which will set the value at a given index to this new string.
In the markLength4 method, by adding the element in the for loop you keep adding Strings and increasing the list size. You need a flag that tells the index and then ends the loop. You can try something like that
public static ArrayList<String> markLength4(ArrayList<String> list) {
int i = 0;
boolean found = false;
int pos = 0;
while(i < list.size() && !found){
if (list.get(i).length() == 4) {
found = true;
pos = i;
}
i++;
}
list.add(pos, "****");
return list;
}

Sorting Strings as inserted into array in Java

I'm trying to create a program that takes user input and sorts it alphabetically as it comes in using compareTo String operations (not array.sort) and prints the final sorted array at the end. I've got most of the body of this problem down but am lost once I get to the sort function. Does anyone have any ideas on how I might be able to finish out the SortInsert method?
import java.util.*;
public class SortAsInserted {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int array_size = GetArraySize();
String[] myArray = new String[array_size];
for (int i = 0; i < array_size; i++){
String nextString = GetNextString();
String[] sortedArray = SortInsert(nextString, myArray);
}
PrintArray(sortedArray);
}
input.close();
}
}
public static String[] SortInsert(String nextString, String[] myArray){
for(int i = 0; i < myArray.length;)
if (nextString.compareToIgnoreCase(myArray[i]) > 0) {
i++;
//if current text is less(alphabetically) than position in Array
}else if (nextString.compareToIgnoreCase(myArray[i]) < 0){
}
}
public static int GetArraySize(){
Scanner input = new Scanner(System.in);
System.out.print("How many items are you entering?: ");
int items_in_array = input.nextInt();
return items_in_array;
}
public static void PrintArray(String[] x) {
for (int i = 0; i < x.length; i++){
System.out.print(x[i]);
}
}
public static String GetNextString(){
Scanner input = new Scanner(System.in);
System.out.println("Enter the next string: ");
String next_string = input.nextLine();
return next_string;
}
}
There are a number of problems with this code. First I'll answer your immediate question, then enumerate some of the other problems.
The SortInsert method takes a String[] that will have been initialized with null values, so you will need to take that into account. The for loop would look something like this. (I'm using comments instead of writing the actual code since I'm not doing the project)
for (int i=0; i<myArray.length; ++i) {
if (myArray[i] == null) {
// we found a blank spot. use it to hold nextString.
break;
} else if (nexString.compareToIgnoreCase(myArray[i]) < 0) {
// nextString should be in spot i, so make room for it
// by shuffling along whatever is in the array at "i" and later
// by one place, then put nextString into position "i"
break;
}
// otherwise we'll just move to the next position to check
}
Now for the other issues.
You have a Scanner object in main that is never used. There's no point in having it and closing it at the end if your other methods make their own.
myArray will always be the sorted array so there's no point in making a local variable called sortedArray and return it from SortInsert. Note that your attempt to print sortedArray would fail anyway because that local variable is only in scope within the for loop.
When printing it should be myArray being passed to PrintArray.
If you're going to sort as you go, the TreeMap data structure is what you should be using, not an array. However, if you want to sort as you go with an array, you need to add some lines into your else if clause in SortInsert (should be sortInsert, BTW). (Another question: why is it else if rather than just else?)
The lines should create a new array of size one greater than the existing array, copy the first i-1 elements of the old array to the new array, put the new element in position i, then copy the remaining elements of the old array into positions one greater in the new array.
Once you find the position you wish to insert at, you have to shift all of the following elements down by one. Something like the following:
String temp = array[position];
for (int j = position+1; j < array_size-1; j++) {
String temp2 = array[j];
array[j] = temp;
temp = temp2;
}
array[array_size-1] = temp;

Array list in java

I am trying to do this problem but can't get around with it. Please tell me what i did wrong and any tips on how to solving it? Thanks.
here is the problem:
Write a method stutter that takes an ArrayList of Strings and an integer k as parameters and that replaces every string with k copies of that string. For example, if the list stores the values ["how", "are", "you?"] before the method is called and k is 4, it should store the values ["how", "how", "how", "how", "are", "are", "are", "are", "you?", "you?", "you?", "you?"] after the method finishes executing. If k is 0 or negative, the list should be empty after the call.
my code:
public static void stutter(ArrayList<String> list,int k) {
String s = "";
for(int i = 0; i<list.size(); i++) {
s = list.get(i);
}
for(int j = 0; j < k; j++) {
list.add(j,s);
}
}
Well...two things are wrong here:
You're not returning anything, which is a bit of a problem if you want to get back the modified list without changing/destroying your original data.
Your loops aren't doing anything meaningful. The first loop is only going to give you the last element in your list, and then you only add that k times. Most definitely not what you want.
I won't give the entire thing away, as this is an exercise for you, but here's some suggestions:
Create your own ArrayList<String> to return instead of that String variable. You'll also be declaring the method to return ArrayList<String>. May as well initialize it, too.
Read each word in the list passed in. Add that to the local list k times (hint: nested loops). If there's no words to be read, then the loop to add the elements isn't fired.
Here is the code
public static List<String> stutter(ArrayList<String> list,int k) {
List<String> resultList=new ArrayList<String>(); // creating new list
if(k<=0) {
return resultList; //return empty list. Return null if necessary
} else {
for(String s : list) { //looping the list input
for(int i=0;i<k;i++) {
resultList.add(s); // adding the same string k times
}
}
return resultList;
}
}
Second for loop should be nested in first for loop
And strings should be added to a newlist instead of adding them to
the samelist
Done modifications to your code.
public static void stutter(List<String> list,int k) {
String s = "";
List<String> newList=new ArrayList<String>();
if(k>0) {
for(int i = 0; i<list.size(); i++) {
s = list.get(i);
for(int j = 0; j < k; j++) {
newList.add(s);
}
}
}
list=newList; // Assigning it your input list since you want to change the actual list
System.out.println(list.toString()); //Since not returning anything, printing the data
}

NullPointerException error while trying to remove a string word from an Array in a remove() method

I'm making this method remove() which takes a String word as argument, to delete from a global Array "words", but I keep getting a NullPointerException for some reason I cannot find, been stuck for hours.
Basically I check for if the word is in the first position, else if is in the last position, or else if it is in neither so I check all the array, and add the first half before the position of the word, and then add the second half after the position of the word in the array, as to skip it and "delete it". But I'm getting a NullPointerException in the for loop looking for the position of the word in the array. Code for the method is here:
public void remove(String a){
String[] temp_arr = new String[words.length-1]; // make array with 1 less length for deleted
if(words[0].equals(a)){ // if the word is the first in the array
for(int x=0, z=1; x<temp_arr.length; x++,z++)
temp_arr[x]=words[z];
words = temp_arr;
} else if(words[words.length-1].equals(a)){ // if the word is in the last position of the array
for(int x=0, z=0; x<temp_arr.length; x++,z++)
temp_arr[x] = words[z];
words = temp_arr;
} else{ // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop, in the if(words[k].equals(a))
int k=0;
for (; k<words.length; k++){ // find the position of the word to delete
if (words[k].equals(a)) {
break;
}
}
for (int i = 0; i < k-1; i++){ // add first part of array before the word
temp_arr[i] = words[i];
}
for(int c = k, b = k+1; c< temp_arr.length; c++,b++){
temp_arr[c] = words[b];
}
words = temp_arr; // assign the new values to global array
}
}
Also, if theres any suggestions for good coding practice would be appreciated, thanks!
** I can only use Arrays as my data structure for this method.
Modify the condition like this
a.equals(words[0])
because you know the string value a. But dont know what value will come from array. So even null value comes from the array it does allow the null pointer exception.
I run your code and find a few errors, I correct somethings without changing the core idea:
} else { // if the word is in neither first or last position of array
// THIS IS WHERE the exception is thrown, in this for loop.
int k = -1;
for (int i = 0; i < words.length; i++) { // find the position of the word to delete
if (words[i].equals(a)) {
k=i;
break;
}
}
if(k<0)//if not exists
return;
for (int i = 0; i < k /*- 1*/; i++) { // add first part of array before the word
temp_arr[i] = words[i];
}
for (int i = k; i < temp_arr.length; i++) {
temp_arr[i] = words[i+1];
}
words = temp_arr; // assign the new values to global array
}
If the original array could't have null elements I would do like this:
public static String[] remove(String words[] , String a) {
int counter = 0;
for (int i = 0; i < words.length; i++) {
if( a.equals(words[i]) ){
words[i] = null;
counter++;
}
}
if(counter==0){
return words;
}
String[] words2 = new String[words.length - counter];
int i=0;
for (String string : words) {
if(string!=null){
words2[i++]=string;
}
}
return words2;
}
I would do that like this:
public void remove(String a) {
List<String> tmp = new ArrayList<String>();
for (String word : words) {
if ((word != null) && (word.equals(a))) {
continue;
}
tmp.add(word);
}
words = tmp.toArray(new String[]);
}
I have a question for you:
Why oh why are you using an array? You should always use a collection (eg a List) unless you absolutely have to use an array (which is rare indeed).
If it were a List, you wouldn't even need this method, because List has the remove() method that does all this for you!

Categories