Search String array for String - java

I want a command such as this:
setstat <statname> <level>
However, my 'statname's are in a Array; and I need to output the Array number.
This is the code I am using:
String[] statname = {"att", "def", "str", "hp",
"ranged", "pray", "magic", "cooking",
"wc", "fletch", "fish", "fm",
"craft", "smith", "mining", "herb",
"agil", "thieving", "slayer", "farming", "rc"};
int statid = statname.contains(arg[1]);
However, it doesn't work (for me). Seeing as contains(...) isn't compatible with an String[] array.
I have no idea which method to use, or how to handle this.

Use Arrays.asList(statname).indexOf(arg[1]); to find the index of an item.

Since your array is not ordered, this function will work:
public int getFoundIndex(String[] stringArr_toSearch, String str_toFind)
for(int i = 0; i < stringArr_toSearch.length; i++) {
if(stringArr_toSearch[i].equals(str_toFind)) {
return i;
}
}
return -1;
}
Call it with
int foundIdx = getFoundIndex(statName, "str");

Here's a neat code for the linear search which returns the index of the element in the array if the element is found, else returns false.
public int search(String[] array, String element)
{
if(array == null || element == null)
return -1;
for(int i = 0; i < array.length; i++)
{
if(array[i].equals(element))
return i;
}
return -1;
}
Using the approach: Arrays.asList(statname).indexOf(arg[1); can get expensive, if you have to search for the elements a lot of time.
You can sort your array once, and then do a binary search too, in order to achieve faster lookup times, if you have to search for elements in the statname array multiple times.

Related

Java: Find if an array has at least 3 elements with the same value

Pretty much what the title said. I thought of using Sets and comparing sizes with the normal array but then if I had 2 elements with duplicates the Set size would be the same as having one element with 2 duplicates.
Any help on how to approach this would be much appreciated!
I think the fastest approach is the brute force one, i.e. traversing the array and count what you want to count. Each other implementation which you can call by a one liner must traverse the array as well, using a HashMap adds the overhead to fill and maintain the map, and you cannot stop iterating if you have found what you searched for.
With following private method you can use it also by a one liner call from your main code:
main()
{
String[] myArray = new String[] {
"Hello",
"Hello",
"Hello",
null,
null,
};
boolean gotIt = hasAtLeastThreeOccurences( myArray, "Hello");
myLog.debug( "gotIt: " + gotIt );
}
private <T> boolean hasAtLeastThreeOccurences( T[] aArray, T aValue)
{
int count = 0;
boolean isNull = (aValue == null);
for ( T t : aArray )
{
if ( isNull )
{
if ( t == null )
{
count++;
}
}
else
{
if ( aValue.equals( t ) )
{
count++;
}
}
if ( count >= 3 )
{
return true;
}
}
return false;
}
Assuming your array is a String Array (just as an example), you can call this method, if it return null then there is no 3 elements or more with the same value, else it will return the first element found 3 times or more
public String getRedundantItem(String... myArray) {
// Convert the array to List
ArrayList<String> myList = new ArrayList<String>(Arrays.asList(myArray));
// Look for the element which frequency is three or more
for (String item : myList) {
if (Collections.frequency(myList, item) > 2) {
return item;
}
}
// No element more than 2 times
return null;
}
Test Example:
public void test(){
String[] someData = {"stack","over", "flow", "stack", "stack"};
String[] otherData = {"stack","over", "flow", "stack", "flow"};
System.out.println(getRedundantItem(someData)); // prints stack
System.out.println(getRedundantItem(otherData)); // prints null
}
If an array have three elements with same value
we keep : element => number of occurence. difficult to do less or faster
List<String> array=Arrays.asList(new String[] {"aa","bb","cc","aa","bb","dd"}); // Complete with other tests
Iterator<String> it=array.iterator();
// Keep element => occurences
Map<String,Integer> occurences=new HashMap<String,Integer>();
while (it.hasNext())
{
String one_string=it.next();
if (occurences.containsKey(one_string))
{
int how_many=occurences.get(one_string);
if (how_many==2) return true;
// IF NOT
occurences.put(one_string, how_many+1);
}
else // NEW
occurences.put(one_string, 1);
}
// finally
return false;
This is an example using int variables, but the basic idea is that the value to be compared to the other values of the array is set to the first variable. Then as we find elements equal to the key, we increment a temporary count variable. If the temporary count variable is greater than the real count variable, then the real count variable is replaced by the temporary count variable. Once an unequal element is found, a new key value is set to the current element being iterated on and the temporary count variable is reset. This could be tinkered with, however, for example you can break out of the loop once the the temporary count reaches three. I'm not sure if this was what you were looking for, but enjoy.
int key = arr[0];
int tempCount = 0;
int realCount = 0;
for(int i = 1; i < arr.length; i++){
if(arr[i] == key){
tempCount++;
}
else{
key = arr[i];
tempCount = 0;
}
if(tempCount > realCount){
realCount = tempCount;
}
}
if(realCount >= 3){
boolean hasThreeOfTheSame = true;
//do stuff you want to do
}
EDIT: I now realize that the OP wanted a way to find if there were 3 of the same elements in an array despite the order. I misread this so my solution finds whether an array has 3 or more consecutive elements in a row (ex: [1, 1, 1, 2, 3] or [1, 2, 2, 2, 3]). I'm only going to keep this up because it may help someone out there.

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
}

Changing outputs of Arrays

I'm stuck on an assignment in which we have to replace every output comming from an array of "yes" with "no", and leave any other output untouched.
I keep getting the error cannot convert from String to String[], and I'm unsure of how to work around this, because I haven't been able to find any String to String[] conversion in the Javadoc.
I've been trying to find a solution for a while, so I just need a push in the right direction.
String[] makeItANegativeArray(String[] inputArray) {
String x = "no";
if (inputArray.equals("yes")) {
return x;
} else {
return inputArray;
}
}
Let's take a look at the code
//Start the function
String[] makeItANegativeArray( String [] inputArray ) {
// function needs String[] as input
// function suspects String[] as output (or return)
// initialise the variable x
String x = "no";
// if the input array is equal to the string VALUE "yes"
// (which is WEIRD because it's an ARRAY not a VALUE)
if (inputArray.equals("yes"))
{
//return A VALUE
//so here we return a VALUE while the function is suspecting an ARRAY
//this causes the error
return x;
}
else
{
//return an array
//(hence if this happens, the function terminates at the first iteration)
return inputArray;
}
}
Clearly, your input is an array and your output should be an array as well.
Hence you will have to loop over each element of the input array and construct and output array before returning anything.
For example:
String[] makeItANegativeArray( String[] inputArray ) {
String x = "yes";
String y = "no";
for (int i = 0; i < inputArray.length; i++)
{
if (inputArray[i].equals("yes"))
{
inputArray[i] = y;
}
else
{
inputArray[i] = x;
}
}
return inputArray;
}
What this does is turn every "yes" in the array into a "no" and every "no" into a "yes".
So it sort of "inverts" the array.
Is this what it is supposed to do?
Alternatively,
If you just want to turn the whole array into an array of only "no's", then do the following:
String[] makeItANegativeArray( String[] inputArray ) {
String x = "no";
for (int i = 0; i < inputArray.length; i++)
{
if (inputArray[i].equals("yes"))
{
inputArray[i] = x;
}
}
return inputArray;
}
NOTE: You are dealing with an array.
inputArray.equals("yes") is what causing the error. You are supposed to get each element in the Array and compare it to "yes".
What the error is telling you is you cannot compare an array of String with a String.
You should do sth like this
String [] makeItANegativeArray( String [] inputArray )
{
for(int i = 0; i < inputArray.Length; i++)
{
if (inputArray[i].equals("yes"))
{
inputArray[i] = "no";
}
}
return inputArray;
}
When you say inputArray.equals it compares array with string and it gives error.You have to iterate through all elements in array and set yes to no and return the edited array.
What are you trying to do with your String[] inputArray. Because you are comparing it's value as if it were a String object, not a String array. If you want to access the first element of the inputArray and then compare the value of that, then that would be within the makeItNegativeArray(String[]):
String[] outputArray = new String[inputArray.length];
for (int i = 0; i < inputArray.length; i++)
{
if (inputArray[i].equals("yes"))
{
outputArray[i] = "no";
}
else
{
outputArray[i] = "yes"
}
}
return outputArray;
I would suggest that you have a look at the use of Arrays in Java and how they differ from single objects. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html as that may give you a real grasp of the usage of arrays and how they can be accessed. Arrays are a really important concept in programming and if you can master it, you will take another step into becoming a star.

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

Creating an algorithm that can sort string/integer arrays

I am trying to figure out how to make a sorting function that will sort an array in descending order.
public void dsort(String field) throws DataSetException {
int front = 0;
int findex = -1;
String[] tosort = new String[50];
for (int i = 0; i < filedata[0].length; i++) {
if (field.equalsIgnoreCase(filedata[0][i])) {
findex = i;
}
}
if (findex == -1) {
throw new DataSetException();
} else {
for (int k = 0; k < getNumRecords(); k++) {
if (filedata[k][findex] != null) {
tosort[front] = filedata[k][findex];
front++;
}
}
Comparator comparator = Collections.reverseOrder();
Arrays.sort(tosort, comparator);
System.out.println(Arrays.asList(tosort));
}
}
What this does is creates a new array by taking elements from an array of arrays, which is what I want it to do.
However, the output of my sort is something like 32, 3, 25, 20, 2, 1000, 1 etc..
These "integers" are considered strings, and this sorting function is supposed to also be able to sort words as strings. I think I should be trying to use comparable, but I am unsure of how to implement it in this situation.
If everything really is a number, then you don't want to store them as String, store them as numbers and then use a numeric sort.
If on the other hand, you have a combination of Strings, some of which are numeric, and some of which are alphabetic, I'd recommend using something like an AlphanumComparator, available
here
Using Google Guava:
List<String> sortedList = Ordering.natural().reverse().onResultOf(new Function<String, Integer>() {
#Override public Integer apply(String input) {
return Integer.valueOf(input); // assumes input is always valid
}
}).immutableSortedCopy(Iterables.concat(listOfLists));
Or something like that. The Iterables.concat will take an iterable of iterables and turn it into a single iterable for you. You will probably need to turn your array of arrays into a List of Lists.

Categories