I have this question here
Once a player has drawn the top card from the deck, they must discard it.
Given a deck of cards, return a new deck containing all the cards except the first from the original deck.
Note: The new array returned is one element shorter than the original, except when the deck has no cards. Then the array returned must be empty.
So basically I have to make a new array thats the same as the old array minus the card at index 0. The issue im having is when I have to put an empty array and IntelliJ keeps throwing a NegativeArraySizeException.
public String[] discardTopCard(String[] remainingDeck) {
String[] newHand = new String[remainingDeck.length - 1];
String[] emptyArray = new String[] {};
int k = 0;
if (remainingDeck.length == 0 || remainingDeck.length == 1) {
return emptyArray;
}
for (int i = 1; i < remainingDeck.length; i++) {
newHand[k] = remainingDeck[i];
k++;
}
return newHand;
}
this is my current code.
I've also tried this and just setting it to null
public String[] discardTopCard(String[] remainingDeck) {
String[] newHand = new String[remainingDeck.length - 1];
int k = 0;
if (remainingDeck.length == 0 || remainingDeck.length == 1) {
return remainingDeck;
}
for (int i = 1; i < remainingDeck.length; i++) {
newHand[k] = remainingDeck[i];
k++;
}
return newHand;
}
If you want to work with a new array that is only part of an existing on, I would recommend to use an existing method: java.util.Arrays.copyOfRange
Example:
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public String[] discardTopCard(String[] remainingDeck) {
int length = remainingDeck.length;
if (length < 2) {
return EMPTY_STRING_ARRAY;
}
return Arrays.copyOfRange(remainingDeck, 1, length);
}
I declared the empty string array as constant outside the method, because it is immutable and it's not necessary to create more than one instance in the whole program.
Both cases, empty input array and input array of lenght 1 will have the same result: an empty array.
Also note that usage of length in the copyOfRange method is OK because there it acts as "to"-index and not as number of elements to copy.
Or, even simpler:
public String[] discardTopCard(String[] deck) {
if (deck.length > 1)
deck = Arrays.copyOfRange(deck, 1, deck.length);
return deck;
}
How about this?
public String[] discardTopCard(String[] deck) {
if (deck.length == 0) {
return deck;
}
String[] smallerDeck = new String[deck.length - 1];
for (int i = 0; i < smallerDeck.length; i++) {
smallerDeck[i] = deck[i];
}
return smallerDeck;
}
Related
I have a .txt file which has data for states as given below:
AL,Alab,4860
AK,Alas,7415
AZ,Ariz,6908
AR,Arka,2988
I have made a function which counts how many states there are that start with the initial passed as such:
public int CInitial(char initial) {
int total = 0;
for(int i = 0; i < states.length; i++) { //states is an array which includes all states present in the .txt file
String testString = states[i].getName(); // getName gets the name of the states present in the .txt file
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
total++;
}
}
}
return total;
}
This would return the number 4 if "A" is passed and 0 if any other initial is passed as there are 4 states that begin with the letter "A".
Now how can I create a new function that passes a character and returns the name of all the states that begin with that character? For Instance this is the initial return type needed for this, however I'm having troubles starting this. Is the process identical to the countStatesCountByInitial function I created?
public State[] CByInitial(char initial) {
return new State[] {}; //to be completed
}
Yes, it will be very similar to the countStatesCountByInitial. The main difference is each time you find a match, you want to add the state into the array. Since we don't know the size of the array beforehand, we may want to use a List instead.
public State[] getStatesCountByInitial(char initial) {
ArrayList<State> found = new ArrayList<>();
// this is the same as before
for(int i = 0; i < states.length; i++) {
String testString = states[i].getName();
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
// except here when you find a match, you add it into the list
found.add(states[i]);
}
}
}
// return as array
return found.toArray(new State[found.size()]);
}
As suggested by Patrick, we can avoid using List by using countStatesCountByInitial to initialize the size of the states.
public State[] getStatesCountByInitial(char initial) {
int matchSize = countStatesCountByInitial(initial);
States[] found = new States[matchSize];
int foundIndex = 0;
// this is the same as before
for(int i = 0; i < states.length; i++) {
String testString = states[i].getName();
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
// except here when you find a match, you add it into the array
found[foundIndex] = states[i];
foundIndex++;
}
}
}
// return the array
return found;
}
You can done both operations simply by one method.
public static ArrayList<State> getStatesCountByInitial(char initial) {
ArrayList selectedStates = new ArrayList<State>();
for(int i = 0; i < states.length; i++) {
if(states.charAt(0) == initial){
selectedStates.add(states[i]);
}
}
return selectedStates;
}
This method will return a arraylist.
If you want to get the count, call this method and get the size of the array.
ArrayList<State> statesNew = getStatesCountByInitial('A');
int count = statesNew.size();
public static String[] findWordsOfLength(String letters, int wordSize) {
letters = "fourgooddogsswam";
for(int i = 0; i < letters.length()-3;i++){
String fourLetter = letters.substring(i,i+4);
}
for(int i = 0; i < letters.length()-4;i++){
String fiveLetter = letters.substring(i,i+5);
}
return ?;
}
I was wondering if I could somehow set the list of strings generated from this loop, into a string array? Is there a way I could return that value if I used multiple loops for different strings?
Here´s an answer not involving a List.
Based on the input you can precalculate the output length of your array and initialize it with the given size. Than you´d just be looping over the array size and use mathematics again to substring from the input.
public static void main(String[] args){
String[] words = findWordsOfLength("fourgooddogsswam", 4);
print(words);
}
public static String[] findWordsOfLength(String letters, int wordSize) {
// your working and output array definition
String[] words;
// If not even dividable add one to the size
if (letters.length() % wordSize == 0) {
words = new String[letters.length() / wordSize];
} else {
words = new String[letters.length() / wordSize + 1];
}
for(int i = 0; i < words.length;i++){
// To not run into IndexOutOfBound check if we´d be going out of bound
if(i*wordSize + wordSize > letters.length()) {
words[i] = letters.substring(i*wordSize);
} else {
words[i] = letters.substring(i*wordSize, i*wordSize+wordSize);
}
}
return words;
}
// Just prints
public static void print(String[] input) {
for(String string : input) {
System.out.println(string);
}
}
O/P:
four
good
dogs
swam
As Scary Wombat suggested in the comments, in the beginning of the method, you can create an ArrayList. Then within in each loop iteration, you can just keep adding to it. At the end of the method, you can convert the list to an array using the toArray method.
import java.util.ArrayList;
import java.util.List;
class Example {
public static String[] findWordsOfLength(String letters, int wordSize) {
if(letters == null) {
return null;
}
int size = letters.length();
int wordMax = size - wordSize + 1;
if(size < wordMax || wordMax <= 0) {
return new String[0];
}
List<String> result = new ArrayList<>();
for (int i = 0; i < wordMax; i++) {
result.add(letters.substring(i, i + wordSize));
}
return result.toArray(new String[0]);
}
public static void main(String[] args) {
String[] word = findWordsOfLength("fourgooddogsswam", 4);
for(String word : words) {
System.out.println(word);
}
/**
* Output in console:
*
* four
* ourg
* urgo
* rgoo
* good
* oodd
* oddo
* ddog
* dogs
* ogss
* gssw
* sswa
* swam
*/
}
}
Note that the advantage of using a list is that you don't need to know its size in advance. An array, on other hand, is initialized with a set size.
If you must use an array, you could do:
public static String[] findWordsOfLength(String letters, int wordSize) {
if(letters == null) {
return null;
}
int size = letters.length();
int wordMax = size - wordSize + 1;
if(size < wordMax || wordMax <= 0) {
return new String[0];
}
int j = 0;
String[] result = new String[wordMax];
for (int i = 0; i < wordMax; i++) {
result[j ++] = letters.substring(i, i + wordSize);
}
return result;
}
I have two arrays:
arrayA = {"b","c","a"}
arrayB = {"99","11","22"}
How do I sort them together so that arrayA = {"a","b","c"} and arrayB = {"22","99","11"}?
I have made one alphanumeric sorting programm Check it out.
import java.util.Arrays;
import java.util.Comparator;
public class AlphanumericSorting implements Comparator {
public int compare(Object firstObjToCompare, Object secondObjToCompare) {
String firstString = firstObjToCompare.toString();
String secondString = secondObjToCompare.toString();
if (secondString == null || firstString == null) {
return 0;
}
int lengthFirstStr = firstString.length();
int lengthSecondStr = secondString.length();
int index1 = 0;
int index2 = 0;
while (index1 < lengthFirstStr && index2 < lengthSecondStr) {
char ch1 = firstString.charAt(index1);
char ch2 = secondString.charAt(index2);
char[] space1 = new char[lengthFirstStr];
char[] space2 = new char[lengthSecondStr];
int loc1 = 0;
int loc2 = 0;
do {
space1[loc1++] = ch1;
index1++;
if (index1 < lengthFirstStr) {
ch1 = firstString.charAt(index1);
} else {
break;
}
} while (Character.isDigit(ch1) == Character.isDigit(space1[0]));
do {
space2[loc2++] = ch2;
index2++;
if (index2 < lengthSecondStr) {
ch2 = secondString.charAt(index2);
} else {
break;
}
} while (Character.isDigit(ch2) == Character.isDigit(space2[0]));
String str1 = new String(space1);
String str2 = new String(space2);
int result;
if (Character.isDigit(space1[0]) && Character.isDigit(space2[0])) {
Integer firstNumberToCompare = new Integer(Integer
.parseInt(str1.trim()));
Integer secondNumberToCompare = new Integer(Integer
.parseInt(str2.trim()));
result = firstNumberToCompare.compareTo(secondNumberToCompare);
} else {
result = str1.compareTo(str2);
}
if (result != 0) {
return result;
}
}
return lengthFirstStr - lengthSecondStr;
}
public static void main(String[] args) {
String[] alphaNumericStringArray = new String[] { "NUM10071",
"NUM9999", "9997", "9998", "9996", "9996F" };
Arrays.sort(alphaNumericStringArray, new AlphanumericSorting());
for (int i = 0; i < alphaNumericStringArray.length; i++) {
System.out.println(alphaNumericStringArray[i]);
}
}
}
Here is the output:
9996
9996F
9997
9998
NUM9999
NUM10071
Use Arrays.sort(arrayB). You can even supply your custom Comparator to affect the sorting.
This link will help you Try array.sort(Arg);
http://www.leepoint.net/notes-java/data/arrays/70sorting.html
If you will be using the same letters and only 1 digit from 0 to 9, then, you can sort it in the same manner you have sorted the first array. If you intend to throw in more letters with more numbers, you will have to implement your own custom comparator (assuming the default behaviour does not suit you).
The answer to the question as written seems so obvious that I think we are not understanding what you are really asking.
I'm guessing that what you are really asking is how to sort one array, and reorder the second array based on how the sort reordered the first array. (Your example is poorly chosen to illustrate this ... but it does in fact doing this.)
Assuming that's what you mean, the simplest way to do this is to turn the two arrays into a single array of pairs, sort the pairs based on the first field, and then use the sorted pair list to repopulate the original arrays.
The (possible) snag is that the total ordering of the second array is indeterminate if the sort is not stable. (Or to put it another way, if there are duplicates in arrayA, then the relative order of the corresponding arrayB elements cannot be predicted.) There are ways to deal with this.
you can use
Arrays.sort(arrayB);
Output is
C1
C2
C3
arrayB = {"22","99","11"}
Arrays.sort(arrayB);
Output:
11
22
99
I've written a method to remove null-values from an array i need in a program.
The method, however, doesn't seem to work, the null values won't go away. This is my code so far.
public void removeNull(String[] a)
{
for(int i=0; i<a.length; i++)
{
if(a[i] == null)
{
fillArray(a, i);
}
}
}
public void fillArray(String[] a, int i)
{
String[] a2 = new String[a.length-1];
for(int j=0; j<a2.length; j++)
{
if(j<i)
{
a2[j]=a[j];
}
else if(j>i)
{
a2[j]=a[j+1];
}
}
a=a2;
}
Thanks in advance!
I would advocate doing it the simple way unless performance is really a problem:
public String[] removeNull(String[] a) {
ArrayList<String> removedNull = new ArrayList<String>();
for (String str : a)
if (str != null)
removedNull.add(str);
return removedNull.toArray(new String[0]);
}
Streams API version of the solution:
SomeClass[] array = new SomeClass[N];
...
array = Arrays.stream(array).filter(Objects::nonNull).toArray(SomeClass[]::new);
(I post this down to maybe get some thoughts on applicability, relative performance etc)
hi everyone first of all i want to appologize for my english im learning at this moment and this is my first post so i want to try to put my solution about the problem here it is
String[] removeNulls(String[] nullsArray) {
int countNulls = 0;
for (int i = 0; i < nullsArray.length; i++) { // count nulls in array
if (nullsArray[i] == null) {
countNulls++;
}
}
// creating new array with new length (length of first array - counted nulls)
String[] nullsRemoved = new String[nullsArray.length - countNulls];
for (int i = 0, j = 0; i < nullsArray.length; i++) {
if (nullsArray[i] != null) {
nullsRemoved[j] = nullsArray[i];
j++;
}
}
return nullsRemoved;
}
You can't change the reference to a variable in a method and expect it to be reflected in the calling method.
You'll instead have to return the new array.
public String[] removeNull(String[] a)
{
for(int i=0; i<a.length; i++)
{
if(a[i] == null)
{
a = fillArray(a, i);
}
}
return a;
}
public String[] fillArray(String[] a, int i)
{
String[] a2 = new String[a.length-1];
for(int j=0; j<a2.length; j++)
{
if(j<i)
{
a2[j]=a[j];
}
else if(j>i)
{
a2[j]=a[j+1];
}
}
return a2;
}
This way would be faster:
private static String[] removeNulls(String[] strs) {
int i = 0;
int j = strs.length - 1;
while (i <= j) {
if (strs[j] == null) {
--j;
} else if (strs[i] != null) {
++i;
} else {
strs[i] = strs[j];
strs[j] = null;
++i; --j;
}
}
return Arrays.copyOfRange(strs, 0, i);
}
I can see two errors in your code:
Your method fillArray doesn't cover the case i == j
Your assignation a = a2; doesn't have the effect you think it might have. Arguments are passed by value in Java, and your assignment does NOT change the value of a in your first method. Try returning an instance to a2 in fillArray, and assign this value to a in removeNull.
A couple of things:
Don't you wantString[] a2 = new String[a.length-1];` to be
String[] a2 = new String[a.length];
Won't making it length - 1 make it too short?
You need a case for i == j in your code. This is why the nulls aren't getting updated.
What problem are you trying to solve with the second function? It seems complicated given what I thought your problem was.
Try this (I didn't test it):
public String[] removeNull(String[] a) {
String[] tmp = new String[a.length];
int counter = 0;
for (String s : a) {
if (s != null) {
tmp[counter++] = s;
}
}
String[] ret = new String[counter];
System.arraycopy(tmp, 0, ret, 0, counter);
return ret;
}
This way you can remove nulls in one cycle, but it will not resize array:
public static void removeNull(String[] a) {
int nullCount = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == null) {
nullCount++;
} else {
a[i-nullCount] = a[i];
}
}
}
This one creates new array, but includes two cycles:
public static String[] removeNull(String[] a) {
int nullCount = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == null) nullCount++;
}
String[] b = new String[a.length-nullCount];
int j = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != null) b[j++] = a[i];
}
return b;
}
You can think on optimizing that code using System.arraycopy. I hope the code works.
When removing values in an array, the size changes so you can't keep the same array (you could push the nulls at the end).
The structure close to an array that has a auto-adjustable size is an ArrayList. One option would be :
String[] inputs;
List<String> items = new ArrayList<String>(inputs.length);
for(String input : inputs) {
if (input != null) {
items.add(input);
}
}
String[] outputs = items.toArray(new String[items.size()]);
Performance might be a bit less than working directly with arrays, but because an array has a fixed size, you would need two loops with arrays :
one to count the number of non-null values
after building the array, the same loop to copy the values.
This might not have an ideal performance either, and it is really much more complex to get it right...
Another approach would be to move the nulls at the end, then create a shorter array that wouldn't include the nulls. The idea would be :
String[] strings;
int writeIndex = 0;
int max = strings.length;
for(int readIndex = 0; readIndex < max; readIndex++) {
String read = strings[readIndex];
if (read != null) {
strings[writeIndex++] = read;
}
}
String[] outputs = new String[writeIndex];
System.arraycopy(strings, 0, ouputs, 0, writeIndex);
Well, more people said it before... but I also want to emphasize this solution:
You can use some type of Collection, like ArrayList or List and add only the not null elements. Finally you must return the new String[] formed by the Collection.
Here an example where you can check the correctness:
import java.util.ArrayList;
public class NullRemove {
public static String[] removeNull(String[] a) {
ArrayList<String> aux = new ArrayList<String>();
for (String elem : a) {
if (elem != null) {
aux.add(elem);
}
}
return (String[]) aux.toArray(new String[aux.size()]);
}
public static void main(String[] args) {
String[] init = new String[]{"aaa", null, "bbb", "ccc", null, "ddd",
"eee", "fff", null};
String[] result = NullRemove.removeNull(init);
System.out.println("Start Check result");
for (String elem : result) {
if (elem == null) System.out.println("NULL element");
}
System.out.println("End Check result");
}
}
The for with the code don't print anything cause there is any null element :)
Regards!
You have two options:
Create new array that length is same as the input, then assign to it not null values and add the substract it to the count of not null elememts .
Example in 0xJoKe answer.
If You need to work only sutch array you could create an adapter for it.
public class NullProofIterable<T> implements Iterable<T>{
private final T[] array;
public NullProofIterable(T[] array){
this.array = array;
}
#Override
public Iterator<T> iterator() {
return new NullProofIterator<T>(this.array);
}
private static class NullProofIterator<T> implements Iterator<T> {
private final T[] array;
private final int index = 0;
private NullProofIterator(T[] array) {
this.array = array;
}
#Override
public boolean hasNext() {
return this.index < this.array.length;
}
#Override
public T next() {
return this.array[this.index];
}
#Override
public void remove() {
throw new RuntimeException("Remove not allowed in this iterator");
}
}
}
Then in source code, only thing you have to do is:
for(String str : new NullProofIterable<String>(strArray)) {
//Perform action on not null string
}
The second option is very fancy usage of != null condition bu it might be helful when a method need to return some data.
I have an array of strings, and I want to delete a particular string from that array. How can I do that? My code is:
private void nregexp(){
String str_nregexp = i_exp_nregexp.getText();
boolean b;
for(int i=0; i<selectedLocations.length; i++){
b= selectedLocations[i].indexOf(str_nregexp) > 0;
if(b){
String i_matches = selectedLocations[i];
........
........
}
}
}
I have to remove i_matches from selectedLocations.
I depends what you mean by "delete a particular String from an array". If you wish to remove its value, you can simply set its value to null, however if you mean actually remove that element from the array (you have an array of 5 elements and you want the result after deleting the element to be 4), this is not possible without copying the array with the item removed.
If you want this behavior, you might want to take a look at a dynamic list such as ArrayList or LinkedList
Edit: If you wanted a simple method to copy the array into an array with the String removed, you could do something like:
List<Foo> fooList = Arrays.asList(orgArray);
fooList.remove(itemToRemove);
Foo[] modifiedArray = fooList.toArray();
You will need to copy the array to a smaller array, omitting the string you don't want. If this is a common situation, you should consider using something other than an array, such as LinkedList or ArrayList.
If you really want to do it yourself, here is an example:
import java.util.Arrays;
public class DelStr {
public static String[] removeFirst(String[] array, String what) {
int idx = -1;
for (int i = 0; i < array.length; i++) {
String e = array[i];
if (e == what || (e != null && e.equals(what))) {
idx = i;
break;
}
}
if (idx < 0) {
return array;
}
String[] newarray = new String[array.length - 1];
System.arraycopy(array, 0, newarray, 0, idx);
System.arraycopy(array, idx + 1, newarray, idx, array.length - idx - 1);
return newarray;
}
public static void main(String[] args) {
String[] strings = { "A", "B", "C", "D" };
System.out.printf("Before: %s%n", Arrays.toString(strings));
System.out.printf("After: %s%n",
Arrays.toString(removeFirst(strings, "D")));
}
}
You cannot change the length of the array, after initializing an array its length is set. So you cannot delete the element directly, you can only replace it, also with null.
String[] arr = new String[10];
// fill array
...
// replace the fifth element with null
arr[4] = null;
If you want to change the length of the Array you should try a list instead:
List<String> list = new ArrayList<String>();
// fill list
...
// remove the fifth element
list.remove(4);
Could you show us your code? Why don't you use ArrayList, as it has a remove(index) and remove(object) support?
Edit: Perhaps
private void nregexp() {
String str_nregexp = i_exp_nregexp.getText();
boolean b;
List<String> list = new ArrayList<String>(Arrays.asList(selectedLocations));
for(Iterator<String> it = list.iterator(); i.hasNext();){
String e = it.next();
b = e.indexOf(str_nregexp) > 0;
// b = e.matches(str_regexp); // instead?
if(b){
String i_matches = s;
it.remove(); // we don't need it anymore
........
........
}
}
selectedLocations = list.toArray(new String[list.size()]);
}
I've reached this solution that allows you to remove all the elements that equal the removal element:
private static <T> T[] removeAll(T[] array, T element) {
if (null == array)
throw new IllegalArgumentException("null array");
if (null == element)
throw new IllegalArgumentException("null element");
T[] result = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length);
int j = 0;
for (int i = 0; i < array.length; i++) {
if (!element.equals(array[i]))
result[j++] = array[i];
}
return Arrays.copyOf(result, j);
}
I also did some benchmarking and this solution is definitely better then using Lists. Although, if performance is not a problem here, I would use Lists.
If you really need to remove only one element (the first) #kd304 has the solution.