Java - removing object from Array - java

I need to create a method to remove an element from an array of objects, without turning it into an ArrayList.
This is the constructor for my object:
public Person(String name1, String telno1)
{
name = name1;
telno = telno1;
}
And my Array:
int capacity = 100;
private Person[] thePhonebook = new Person[capacity];
And i have a shell for my remove method:
public String removeEntry(String name)
{
//name is name of the person to be removed (dont worry about duplicate names)
//returns the telephone number of removed entry
}
Im not sure how to delete the element in the array (i dont want to just set the values to null)
I did think of creating a new array and copying parts on either side of the element to be removed to form a new array but im not sure how to implement that.
I also have a find method which can be used to find the name of the person in the array if that helps:
private int find(String name)
{
String name1 = name;
int i = 0;
int elementNo = 0;
int found = 0;
while(i < size)
{
if(thePhonebook[i].getName().equals(name1))
{
elementNo = i;
found = 1;
break;
}
}
if(found == 1)
{
return dirNo;
}
else
{
dirNo = -1;
return dirNo;
}
}
Thanks for your time.

You cannot directly remove an element from an array in Java. You two choices:
A. If you must preserve the order of the elements in the array: Begin at the index you want to remove, and shift each element "down" one index (toward index 0), as in:
public String removeEntry(String name)
{
String result = null;
int index = find(name);
if (index >= 0)
{
result = thePhonebook[index].telno;
for (int i = index + 1; i < thePhonebook.length; ++i)
{
thePhonebook[i - 1] = thePhonebook[i];
if (thePhonebook[i] == null)
{
break;
}
}
thePhonebook[thePhonebook.length - 1] = null;
}
return result;
}
In the above implementation, the value null in the array signifies the end of the list.
B. If the order of the elements in the array doesn't matter: Swap the element you want to remove with the last element of the list. Note that to do this you need to maintain a length value for the list, which is the value thePhonebookLength in the code below.
public String removeEntry(String name)
{
String result = null;
int index = find(name);
if (index >= 0)
{
result = thePhonebook[index].telno;
thePhonebook[index] = thePhonebook[thePhonebookLength - 1];
thePhonebook[--thePhonebookLength] = null;
}
return result;
}
A benefit of both of these solutions is that the array is modified in place, without using allocation.
Having offered these possibilities, I suggest that using a collection is better suited for your purposes -- such as one of the List subclasses, or perhaps even a Map if lookups by name are common.

To do this is to get the last index in your array and then pass it to the one that was just deleted and the delete the last array.. if the array is the last one dont it just delete it..
for(int i = 0; i < thePhonebook .length; i++)
{
if(thePhonebook[i].getName().equals(string))
{
if(i == thePhonebook .length - 1)
thePhonebook[i] = null;
else
{
thePhonebook[i] = null;
thePhonebook[i] = thePhonebook[thePhonebook .length - 1];
thePhonebook[thePhonebook .length - 1] = null;
}
}
}

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);
}

How to remove duplicate words containing in ArrayList<String> in java [duplicate]

I'm working on a program that uses an ArrayList to store Strings. The program prompts the user with a menu and allows the user to choose an operation to perform. Such operations are adding Strings to the List, printing the entries etc. What I want to be able to do is create a method called removeDuplicates(). This method will search the ArrayList and remove any duplicated values. I want to leave one instance of the duplicated value(s) within the list. I also want this method to return the total number of duplicates removed.
I've been trying to use nested loops to accomplish this but I've been running into trouble because when entries get deleted, the indexing of the ArrayList gets altered and things don't work as they should. I know conceptually what I need to do but I'm having trouble implementing this idea in code.
Here is some pseudo code:
start with first entry;
check each subsequent entry in the list and see if it matches the first entry;
remove each subsequent entry in the list that matches the first entry;
after all entries have been examined, move on to the second entry;
check each entry in the list and see if it matches the second entry;
remove each entry in the list that matches the second entry;
repeat for entry in the list
Here's the code I have so far:
public int removeDuplicates()
{
int duplicates = 0;
for ( int i = 0; i < strings.size(); i++ )
{
for ( int j = 0; j < strings.size(); j++ )
{
if ( i == j )
{
// i & j refer to same entry so do nothing
}
else if ( strings.get( j ).equals( strings.get( i ) ) )
{
strings.remove( j );
duplicates++;
}
}
}
return duplicates;
}
UPDATE: It appears that Will is looking for a homework solution that involves developing the algorithm to remove duplicates, rather than a pragmatic solution using Sets. See his comment:
Thx for the suggestions. This is part of an assignment and I believe the teacher had intended for the solution to not include sets. In other words, I am to come up with a solution that will search for and remove duplicates without implementing a HashSet. The teacher suggested using nested loops which is what I'm trying to do but I've been having some problems with the indexing of the ArrayList after certain entries are removed.
Why not use a collection such as Set (and an implementation like HashSet) which naturally prevents duplicates?
You can use nested loops without any problem:
public static int removeDuplicates(ArrayList<String> strings) {
int size = strings.size();
int duplicates = 0;
// not using a method in the check also speeds up the execution
// also i must be less that size-1 so that j doesn't
// throw IndexOutOfBoundsException
for (int i = 0; i < size - 1; i++) {
// start from the next item after strings[i]
// since the ones before are checked
for (int j = i + 1; j < size; j++) {
// no need for if ( i == j ) here
if (!strings.get(j).equals(strings.get(i)))
continue;
duplicates++;
strings.remove(j);
// decrease j because the array got re-indexed
j--;
// decrease the size of the array
size--;
} // for j
} // for i
return duplicates;
}
You could try this one liner to take a copy of the String preserving order.
List<String> list;
List<String> dedupped = new ArrayList<String>(new LinkedHashSet<String>(list));
This approach is also O(n) amortized instead of O(n^2)
Just to clarify my comment on matt b's answer, if you really want to count the number of duplicates removed, use this code:
List<String> list = new ArrayList<String>();
// list gets populated from user input...
Set<String> set = new HashSet<String>(list);
int numDuplicates = list.size() - set.size();
List<String> lst = new ArrayList<String>();
lst.add("one");
lst.add("one");
lst.add("two");
lst.add("three");
lst.add("three");
lst.add("three");
Set se =new HashSet(lst);
lst.clear();
lst = new ArrayList<String>(se);
for (Object ls : lst){
System.out.println("Resulting output---------" + ls);
}
I've been trying to use nested loops to accomplish this but I've been running into trouble because when entries get deleted, the indexing of the ArrayList gets altered and things don't work as they should
Why don't you just decrease the counter each time you delete an entry.
When you delete an entry the elements will move too:
ej:
String [] a = {"a","a","b","c" }
positions:
a[0] = "a";
a[1] = "a";
a[2] = "b";
a[3] = "c";
After you remove your first "a" the indexes are:
a[0] = "a";
a[1] = "b";
a[2] = "c";
So, you should take this into consideration and decrease the value of j ( j--) to avoid "jumping" over a value.
See this screenshot:
public Collection removeDuplicates(Collection c) {
// Returns a new collection with duplicates removed from passed collection.
Collection result = new ArrayList();
for(Object o : c) {
if (!result.contains(o)) {
result.add(o);
}
}
return result;
}
or
public void removeDuplicates(List l) {
// Removes duplicates in place from an existing list
Object last = null;
Collections.sort(l);
Iterator i = l.iterator();
while(i.hasNext()) {
Object o = i.next();
if (o.equals(last)) {
i.remove();
} else {
last = o;
}
}
}
Both untested.
Assuming you can't use a Set like you said, the easiest way of solving the problem is to use a temporary list, rather than attempting to remove the duplicates in place:
public class Duplicates {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("one");
list.add("two");
list.add("three");
list.add("three");
list.add("three");
System.out.println("Prior to removal: " +list);
System.out.println("There were " + removeDuplicates(list) + " duplicates.");
System.out.println("After removal: " + list);
}
public static int removeDuplicates(List<String> list) {
int removed = 0;
List<String> temp = new ArrayList<String>();
for(String s : list) {
if(!temp.contains(s)) {
temp.add(s);
} else {
//if the string is already in the list, then ignore it and increment the removed counter
removed++;
}
}
//put the contents of temp back in the main list
list.clear();
list.addAll(temp);
return removed;
}
}
You could do something like this, must of what people answered above is one alternative, but here's another.
for (int i = 0; i < strings.size(); i++) {
for (int j = j + 1; j > strings.size(); j++) {
if(strings.get(i) == strings.get(j)) {
strings.remove(j);
j--;
}`
}
}
return strings;
Using a set is the best option to remove the duplicates:
If you have a list of of arrays you can remove the duplicates and still retain array list features:
List<String> strings = new ArrayList<String>();
//populate the array
...
List<String> dedupped = new ArrayList<String>(new HashSet<String>(strings));
int numdups = strings.size() - dedupped.size();
if you can't use a set, sort the array (Collections.sort()) and iterate over the list, checking if the current element is equal to the previous element, if it is, remove it.
Using a set is the best option (as others suggested).
If you want to compare all elements in a list with eachother you should slightly adapt your for loops:
for(int i = 0; i < max; i++)
for(int j = i+1; j < max; j++)
This way you don't compare each element only once instead of twice. This is because the second loop start at the next element compared to the first loop.
Also when removing from a list when iterating over them (even when you use a for loop instead of an iterator), keep in mind that you reduce the size of the list. A common solution is to keep another list of items you want to delete, and then after you finished deciding which to delete, you delete them from the original list.
public ArrayList removeDuplicates(ArrayList <String> inArray)
{
ArrayList <String> outArray = new ArrayList();
boolean doAdd = true;
for (int i = 0; i < inArray.size(); i++)
{
String testString = inArray.get(i);
for (int j = 0; j < inArray.size(); j++)
{
if (i == j)
{
break;
}
else if (inArray.get(j).equals(testString))
{
doAdd = false;
break;
}
}
if (doAdd)
{
outArray.add(testString);
}
else
{
doAdd = true;
}
}
return outArray;
}
You could replace the duplicate with an empty string*, thus keeping the indexing in tact. Then after you've completed you can strip out the empty strings.
*But only if an empty string isn't valid in your implementation.
The problem you are seeing in your code is that you remove an entry during iteration, thus invalidating the iteration location.
For example:
{"a", "b", "c", "b", "b", "d"}
i j
Now you are removing strings[j].
{"a", "b", "c", "b", "d"}
i j
The inner loop ends and j is incremented.
{"a", "b", "c", "b", "d"}
i j
Only one duplicate 'b' detected...oops.
best practice in these cases is to store the locations that have to be removed, and remove them after you have finished iterating through the arraylist. (One bonus, the strings.size() call can be optimized outside of the loops by you or the compiler)
Tip, you can start iterating with j at i+1, you've already checked the 0 - i!
The inner for loop is invalid. If you delete an element, you cannot increment j, since j is now pointing at the element after the one you deleted, and you will need to inspect it.
In other words, you should use a while loop instead of a for loop, and only increment j if the elements at i and j do not match. If they do match, remove the element at j. size() will decrease by 1 and j will now be pointing at the following element, so there is no need to increase j.
Also, there is no reason to inspect all elements in the inner loop, just the ones following i, since duplicates before i have already been removed by prior iterations.
public <Foo> Entry<Integer,List<Foo>> uniqueElementList(List<Foo> listWithPossibleDuplicates) {
List<Foo> result = new ArrayList<Foo>();//...might want to pre-size here, if you have reliable info about the number of dupes
Set<Foo> found = new HashSet<Foo>(); //...again with the pre-sizing
for (Foo f : listWithPossibleDuplicates) if (found.add(f)) result.add(f);
return entryFactory(listWithPossibleDuplicates.size()-found.size(), result);
}
and then some entryFactory(Integer key, List<Foo> value) method. If you want to mutate the original list (possibly not a good idea, but whatever) instead:
public <Foo> int removeDuplicates(List<Foo> listWithPossibleDuplicates) {
int original = listWithPossibleDuplicates.size();
Iterator<Foo> iter = listWithPossibleDuplicates.iterator();
Set<Foo> found = new HashSet<Foo>();
while (iter.hasNext()) if (!found.add(iter.next())) iter.remove();
return original - found.size();
}
for your particular case using strings, you may need to deal with some additional equality constraints (e.g., are upper and lower case versions the same or different?).
EDIT: ah, this is homework. Look up Iterator/Iterable in the Java Collections framework, as well as Set, and see if you don't come to the same conclusion I offered. The generics part is just gravy.
I am bit late to join this question, but I have come with a better solution regarding the same using GENERIC type. All the above provided solutions are just a solution. They are increasing a lead to the complexity of whole runtime thread.
RemoveDuplicacy.java
We can minimize it using a technique which should do the required , at the Load Time.
Example : For suppose when you are using a arraylist of the class type as :
ArrayList<User> usersList = new ArrayList<User>();
usersList.clear();
User user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("AB");
user.setId("2"); // duplicate
usersList.add(user);
user = new User();
user.setName("C");
user.setId("4");
usersList.add(user);
user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("A");
user.setId("2"); // duplicate
usersList.add(user);
}
The Class for which is the base for the arraylist used above : User class
class User {
private String name;
private String id;
/**
* #param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* #return the id
*/
public String getId() {
return id;
}
}
Now in java there are two Overrided methods present of Object (parent) Class, which can help here in the means to serve our purpose better.They are :
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
You have to override these methods in the User class
Here is the complete code :
https://gist.github.com/4584310
Let me know if you have any queries.
You can add the list into a HashSet and then again convert that hashset into list to remove the duplicates.
public static int removeDuplicates(List<String> duplicateList){
List<String> correctedList = new ArrayList<String>();
Set<String> a = new HashSet<String>();
a.addAll(duplicateList);
correctedList.addAll(a);
return (duplicateList.size()-correctedList.size());
}
here it will return the number of duplicates. You can also use the correctList with all unique values
Below is the code to remove duplicate elements from a list without changing the order of the list,without using temporary list and without using any set variables.This code saves the memory and boosts performance.
This is a generic method which works with any kind of list.
This was the question asked in one of the interviews.
Searched in many forums for the solution but could not find one,so thought this is the correct forum to post the code.
public List<?> removeDuplicate(List<?> listWithDuplicates) {
int[] intArray = new int[listWithDuplicates.size()];
int dupCount = 1;
int arrayIndex = 0;
int prevListIndex = 0; // to save previous listIndex value from intArray
int listIndex;
for (int i = 0; i < listWithDuplicates.size(); i++) {
for (int j = i + 1; j < listWithDuplicates.size(); j++) {
if (listWithDuplicates.get(j).equals(listWithDuplicates.get(i)))
dupCount++;
if (dupCount == 2) {
intArray[arrayIndex] = j; // Saving duplicate indexes to an array
arrayIndex++;
dupCount = 1;
}
}
}
Arrays.sort(intArray);
for (int k = intArray.length - 1; k >= 0; k--) {
listIndex = intArray[k];
if (listIndex != 0 && prevListIndex != listIndex){
listWithDuplicates.remove(listIndex);
prevListIndex = listIndex;
}
}
return listWithDuplicates;
}

How to determine which input value was entered the most

I am having a hard time figuring how to determine which productType was inputted the most. For example, a person could input "water", "water", "coffee", and "milk". My expected output would be "Water was the most ordered product." This is my mainline logic. Can anyone help?
public static void main(String[] args) {
final int MAX_GUESTS = 16;
final int MAX_DRINKS = 48;
double[] drinkCosts = new double[MAX_DRINKS];
int count = 0;
String productType = getProductType();
while (!productType.equals("-1")) {
if (count < MAX_GUESTS) {
count++;
String productVariation = getProductVariation(productType);
for (int i = 0; i < count; i++) {
drinkCosts[count] = getDrinkCost(productVariation);
}
}
else {
JOptionPane.showMessageDialog(null, "Come back tomorrow.");
}
productType = getProductType();
}
double total = getTotal(drinkCosts);
print(total);
}
I would recommend using a java.util.HashMap<>. Use a String for the key type (the productType) and use Integer for the value type (the number of occurrences of that productType).
Each time you read in a productType (at the start of your while loop), check if the productType is already a key in the map. If so, increment the count that it maps to by one. If not, use the HashMap.put(String key, Integer value) method to add the productType to the map with a count of 1.
After your while loop, simply loop through the map to check which productType was entered the most (has the highest count):
int highestCount = -1;
String mostEnteredProductType = null;
for (Entry<String,Integer> entry : map.entrySet()) {
if (entry.getValue() > highestCount) {
highestCount = entry.getValue();
mostEnteredProductType = entry.getKey();
}
}
System.out.println(mostEnteredProductType + " was the most ordered product.");
EDIT:
To do this with only arrays, you will need to have two arrays, one for the productType and one for the number of occurrences of that productType. Since arrays have a fixed length, you will need to initialize them to the number of possible productTypes (I think that is what MAX_DRINKS is?).
So, we create two arrays:
String[] productTypes = new String[MAX_DRINKS];
int[] counts = new int[MAX_DRINKS];
These arrays will essentially function as a map, with each productType in the String array mapping to the count at the same index in counts (e.g., productTypes[5] was entered counts[5] times).
Then, when you read in a productType in the while loop, loop through productTypes. If you find that type, increment the corresponding index of counts (e.g., if the productType is at productTypes[5], increment counts[5]. If not (if you reach an element that is null in productTypes before finding the type that was entered), set that element to the given productType, and set the corresponding index of counts to 1.
Then, simply change the above code fragment I gave to this:
int highestCount = 0;
String mostEnteredProductType = null;
for (int i = 0; i < NUM_DRINKS; i++) {
// Once we reach a null productType, we have reached the end of the
// entered productTypes
if (productTypes[i] == null) {
break;
} else if (counts[i] > highestCount) {
highestCount = counts[i];
mostEnteredProductType = productTypes[i];
}
}
// Should probably check that mostEnteredProductType isn't null here.
System.out.println(mostEnteredProductType + " was the most ordered product.");

Applying Linear and Binary Searches to Arrays

I have to create a program that takes a user input (a number) and then the program should have that number and apply a search to the array and output the corresponding title by matching the index and the number the user inputted. However during run time, nothing happens. I have set breakers in my code and noticed a problem with the for loop (search algorithm). Please help me and let me know what is wrong is my search algorithm. What I am trying to do is use the number of that the user inputs to match a index and then output the book title that is stored in the index.
private void btnFindActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
// declares an array
String[] listOfBooks = new String [101];
// assigns index in array to book title
listOfBooks[1] = "The Adventures of Tom Sawyer";
listOfBooks[2] = "Huckleberry Finn";
listOfBooks[4] = "The Sword in the Stone";
listOfBooks[6] = "Stuart Little";
listOfBooks[10] = "Treasure Island";
listOfBooks[12] = "Test";
listOfBooks[14] = "Alice's Adventures in Wonderland";
listOfBooks[20] = "Twenty Thousand Leagues Under the Sea";
listOfBooks[24] = "Peter Pan";
listOfBooks[26] = "Charlotte's Web";
listOfBooks[31] = "A Little Princess";
listOfBooks[32] = "Little Women";
listOfBooks[33] = "Black Beauty";
listOfBooks[35] = "The Merry Adventures of Robin Hood";
listOfBooks[40] = "Robinson Crusoe";
listOfBooks[46] = "Anne of Green Gables";
listOfBooks[50] = "Little House in the Big Woods";
listOfBooks[52] = "Swiss Family Robinson";
listOfBooks[54] = "The Lion, the Witch and the Wardrobe";
listOfBooks[54] = "Heidi";
listOfBooks[66] = "A Winkle in Time";
listOfBooks[100] = "Mary Poppins";
// gets user input
String numberInput = txtNumberInput.getText();
int number = Integer.parseInt(numberInput);
// Linear search to match index number and user input number
for(int i = 0; i < listOfBooks.length - 1; i++) {
if (listOfBooks.get(i) == number) {
txtLinearOutput.setText(listOfBooks[i]);
break;
}
}
*There is a problem with the listOfBooks.get in the if statement. Also I need to apply a binary search that would search the same array just using the binary method. Need help to apply this type of binary search.
How could I make a statement that checks if the int number is equal to an index?
Note that the following code is just an example of what I have to apply. Variables are all for example purposes:
public static Boolean binarySearch(String [ ] A, int left, int right, String V){
int middle;
if (left > right) {
return false;
}
middle = (left + right)/2;
int compare = V.compareTo(A[middle]);
if (compare == 0) {
return true;
}
if (compare < 0) {
return binarySearch(A, left, middle-1, V);
} else {
return binarySearch(A, middle + 1, right, V);
}
}
you can avoid for loop and check condition by just giving number like this: txtLinearOutput.setText(listOfBooks[number-1]);
remove your code
// Linear search to match index number and user input number
for(int i = 0; i < listOfBooks.length - 1; i++) {
if (listOfBooks.get(i) == number) {
txtLinearOutput.setText(listOfBooks[i]);
break;
}
with
try{
int number = Integer.parseInt(numberInput);
if(number>0 && number<101){
txtLinearOutput.setText(listOfBooks[number-1]);
}else{
// out of range
}
}catch(Exception e){
// handle exception here
}
You are comparing if (listOfBooks.get(i) == number) it is wrong, you should compare: if (i == number), becouse you need compare element position.
This isn't a binary search answer. Just an implementation of HashMap. Have a look at it.
HashMap<String, Integer> books = new HashMap();
books.put("abc", 1);
books.put("xyz", 2);
books.put("pqr", 3);
books.put("lmo", 4);
System.out.println(books.getValue("abc");
Using the inbuilt BinarySearch.
String []arr = new String[15];
arr[0] = "abc";
arr[5] = "prq";
arr[7] = "lmo";
arr[10] = "xyz";
System.out.println(Arrays.binarySearch(arr, "lmo"));
How to compare Strings using binary search.
String[] array = new String[4];
array[0] = "abc";
array[1] = "lmo";
array[2] = "pqr";
array[3] = "xyz";
int first, last, middle;
first = 0;
last = array.length - 1;
middle = (first + last) / 2;
String key = "abc";
while (first <= last) {
if (compare(array[middle], key))
first = middle + 1;
else if (array[middle].equals(key)) {
System.out.println(key + " found at location " + (middle) + ".");
break;
} else {
last = middle - 1;
}
middle = (first + last) / 2;
}
if (first > last)
System.out.println(key + " is not found.\n");
}
private static boolean compare(String string, String key) {
// TODO Auto-generated method stub
for (int i = 0; i < Math.min(string.length(), key.length()); ++i)
if (string.charAt(i) < key.charAt(i))
return true;
return false;
}
Your linear search code looks something like this
try{
txtLinearOutput.setText(listOfBooks[yourNumber]);
}
catch(IndexOutOfBoundsException ie){
// prompt that number is not an index
}
catch(Exception e){
// if any other exception is caught
}
What you are doing here:
if (listOfBooks.get(i) == number) {
is that you are matching the content of the array with the input number, which is irrelevant.
You can directly use the input number to fetch the value stored at the index.
For example:
txtLinearOutput.setText(listOfBooks[number-1]);
Additionally, int number = Integer.parseInt(numberInput); should be placed within try-catch block to validate input number parsing. And you can check if the input number is within the range of the array to avoid exceptions like:
try{
int number = Integer.parseInt(numberInput);
// Linear search to match index number and user input number
if (number > 0 && number <=100) {
txtLinearOutput.setText(listOfBooks[number-1]);
} else {
// Display error message
}
} catch(Exception e) {
// Handle exception and display error message
}
And for using binary search, the string array need to be sorted. You can use Arrays.sort() method for sorting it.
And regarding using binary search, you can use Java Arrays Binary Search method

How to remove specific value from string array in java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Removing an element from an Array (Java)
How to remove specific String array value for example
String[] str_array = {"item1","item2","item3"};
i want to remove "item2" from str_array pls help me i want output like
String[] str_array = {"item1","item3"};
I would do it as follows:
String[] str_array = {"item1","item2","item3"};
List<String> list = new ArrayList<String>(Arrays.asList(str_array));
list.remove("item2");
str_array = list.toArray(new String[0]);
If you must use arrays, System.arraycopy is the most efficient, scalable solution. However, if you must remove one element from an array several times, you should use an implementation of List rather than an array.
The following utilizes System.arraycopy in order to achieve the desired effect.
public static Object[] remove(Object[] array, Object element) {
if (array.length > 0) {
int index = -1;
for (int i = 0; i < array.length; i++) {
if (array[i].equals(element)) {
index = i;
break;
}
}
if (index >= 0) {
Object[] copy = (Object[]) Array.newInstance(array.getClass()
.getComponentType(), array.length - 1);
if (copy.length > 0) {
System.arraycopy(array, 0, copy, 0, index);
System.arraycopy(array, index + 1, copy, index, copy.length - index);
}
return copy;
}
}
return array;
}
Also, you can increase the method's efficiency if you know that your array consists of only Comparable objects. You can use Arrays.sort to sort them before passing them through the remove method, modified to use Arrays.binarySearch to find index rather than a for loop, raising that portion of the method's efficiency from O(n) to O(nlogn).
Other Option is to copy array to other array accept than remove item.
public static String[] removeItemFromArray(String[] input, String item) {
if (input == null) {
return null;
} else if (input.length <= 0) {
return input;
} else {
String[] output = new String[input.length - 1];
int count = 0;
for (String i : input) {
if (!i.equals(item)) {
output[count++] = i;
}
}
return output;
}
}

Categories