Would it be possible to get an answer in pseudocode please, guys?
How could I write a method that, in O(n log n), takes a string array and removes null entries.
I appreciate you can't alter the array size which means I need to copy the contents over to a new one but I can only seem to do it with nested for-loops which compresses my algorithm time and would then become O(n^2)
You need to make a copy of the array, but you only need to make a shallow copy, not a deep copy -- the individual strings don't need to be copied. So it would look something like this:
create new output array O
for each string S in the input array I
if S is not null
add S to O
If you're using ArrayLists, you can use this as-is; however, if you're using plain old Java arrays, you can't resize it each time you add an element. So, instead, you'll need to count the number of non-null entries first, then create an output array of the appropriate size, then loop through the input array again.
Your question suggests that you might be looking for a way to avoid allocating a new array. If that's the case, this solution might be what you're looking for. Rather than returning an array of a smaller size, it instead modifies the given array, moving all null references to the end and packing all the Strings at the front. So {"Foo","Bar",null,"Baz"} becomes {"Foo","Bar","Baz",null}, as an example.
public static void packStrings(String[] strArr) {
int writeIndex = 0;
for (String str : strArr)
if (str != null) strArr[writeIndex++] = str;
Arrays.fill(strArr, writeIndex, strArr.length, null);
}
And in psudocode that would be... ah....
function packString(stringArray)
initialize write index to 0
for each string in stringArray
if the string isn't null
write it to stringArray at the write index
advance the write index
set the rest of stringArray at the write index and beyond to null
That's O(n), but more so, that's a mere n array assignments and zero allocations.
You need to keep track of your progress through both arrays. Let a[] be the original array and b[] be a second array of the same size.
initialize acount to 0
initialize bcount = 0
for acount = 0 to a.length - 1
if(array[acount] != null)
b[bcount++] = a[acount]
return b[]
At the end b will contain only bcount + 1 entries which is less than or equal to the length of the array. So optionally you may want to define an array with only bcount elements to return.
Related
So i am using string.split because i need to take certain parts of a string and then print the first part. The part size may vary so I can't use substring or a math formula. I am attempting to store everything I need in the string array to then selectively print what I need based on the position, this much I can control. However, I am not sure what to do because I know when I do a split, it takes the two parts and stores them in the array. However, there is one case where I need that value in the array untouched. I'm afraid if I do
format[0] = rename
That it will overwrite that value and mess up the entire array. My question is how do I assign a position to this value when I don't know what the position of the others will be? Do I need to preemptively assign it a value or give it the last possible value in the array? I have attached a segment of the code that deals with my question. The only thing I can add is that this is in a bigger loop and rename's value changes every iteration. Don't pay to much attention to the comments, those are more of reminders for me as to what to do rather than what the code is suppose to do. Any pointers, tips, help is greatly appreciated.
String format[];
rename = workbook.getSheet(sheet).getCell(column,row).getContents();
for(int i = 0; i < rename.length(); i++) {
//may need to add[i] so it has somewhere to go and store
if(rename.charAt(i) == '/') {
format = rename.split("/");
}
else if(rename.charAt(i) == '.') {
if(rename.charAt(0) == 0) {
//just put that value in the array
format = rename;
} else {
//round it to the tenths place and then put it into the array
format = rename.split("\\.");
}
} else if(rename.charAt(i) == '%') {
//space between number and percentage
format = rename.split(" ");
}
}
Whenever you assign a variable it gets overwritten
format[0] = rename
Will overwrite the first index of this array of Strings.
In your example, the 'format' array is being overwritten with each iteration of the for loop. After the loop has been completed 'format' will contain only the values for the most recent split.
I would suggest looking into using an ArrayList, they are much easier to manage than a traditional array and you can simply just iterate through the split values and append them at the end.
int[][] a = new int[0][5];
Why the above code is valid in java?
This 2d array is pretty much useless, because the first dimension is ZERO.
Logically, if the first dimension is 0, the second dimension should not be bigger than 0.
I understand we can initiate a 1d empty array.
By the JLS, an array expression indicating a size of zero is valid - it is just an expression - so you can legally declare an n-dimensional array that has zero cardinality.
The only thing that JLS lexer checks (as of Java 8) is whether or not the expression evaluates to zero:
Next, the values of the dimension expressions are checked. If the value of any DimExpr expression is less than zero, then a NegativeArraySizeException is thrown.
This says nothing of its usefulness, as I'm sure you're aware, any attempt to index into this array will produce an ArrayIndexOutOfBoundsException since your index location starts at zero.
It shouldn't be weird to think as an empty array as something normal. There is a very similar case where we deal with empty arrays all the time.
List<String> names = new ArrayList<String>();
names is currently an empty array. Wouldn't it be weird to always declare arrays with at least the first element?
List<String> names = new ArrayList<String>(Arrays.asList("John"));
The alternative to new int[0] being valid syntax would be to set the array to null when the first element is not available. In this world, we would be expected to regularly check for null before iterating an array.
int[] nums = null; // Because empty primitive arrays are "weird"
//typical for-each loop
if(nums != null){
for(int x: nums){
// do something
}
}
//typical for loop
if(nums != null){
for(int c = 0; c < nums.length; c++){
// do something
}
}
Without empty arrays, regular for loops would throw NullPointerExceptions all the time. All that said, it is weird to use new int[0][5] instead of new int[0][]. I don't think it's worthy of a syntax error, but I think it deserves one of these from the IDE:
Currently, I have trouble attempting to print out the individual lengths efficiently.
String[] array = {"test", "testing", "tests"};
int arraylength = array[0].length();
System.out.println(arraylength);
Now, this does work in printing out the length however, it is inefficient and doesn't work if theoretically I don't know the length of the array.
Thanks for your input and I would appreciate if the code insisted contains "System.out.println" included so I don't have trouble figuring out which to print out.
Use this:
String[] array = {"test", "testing", "tests"};
for(String str : array) {
System.out.println(str.length());
}
If you are using Java 8 then it's a one liner :)
Arrays.asList(array).forEach(element -> System.out.println(element.length()));
What you are doing is, converting your array to a list and then running a for loop over it. Then for every element, you are printing out the length of the element.
EDIT
From one of the comment, this is even a better version of my code.
Arrays.stream(array).map(String::length).forEach(System.out::println);
Here first you convert your array to a list and then map each element to the function length of string class, then you run a foreach over it which prints out the mapped values.
String[] array = {"test", "testing", "tests"};
The length for array is:
int arraylength = array.length;
To have retrieve length for string:
for(String string: array) {
System.out.println(string.length());
}
So I am creating a Hash Table that uses an Array of Linked Lists of Arrays. Let me take a second to explain why this is.
So I have previously implemented Hash Tables by creating an Array, and each element of the array is a Linked List. This way I could quickly look up a LL of 450,000 elements by searching for the hash value first in the array, and searching the elements of this LL. I should add that this is a project for school and I cannot just use the Hash Tables that comes with java.
Now I want to do something similar... but I massive have a LL of Arrays that I need to search. Here each element of the LL is line of a text file, which represented by a 4 element array, where each of the 4 elements is a different string that was tab delimited in the input file. I need to be able to quickly access the 2nd, 3rd, and 4th string that was located in each line, and that is now an element of this array.
So What I want is to be able to create an Array of LL of Arrays... first I will find the sum of the ascii values of the second element of an array. Then I will hash the entire array using this value into by Hash Table. Then when I later need to find this element, I will go to the corresponding element of the array, where I have a list of arrays. I will the search for the 2nd value of each array in the list. If i find the one I want, then I return that array, and use the 3rd and 4th element of this array.
As I said, I have this working fine for an Array of LL, but adding the extra dimension of Arrays inside has thrown me off completely. I think it is mostly just figuring out syntax, since I have successfully initialized a Array of LL of Arrays (public static LinkedList[] RdHashLL) so it appears that Java is okay with this in principal. However, I have no idea how to put elements into the Hash Table, and how to read them out.
Below is my code for a ARRAY OF LINKED LISTS that works FINE. I just need help getting it to work for an ARRAY OF LL OF ARRAYS!
public class TableOfHash{
public static LinkedList<String>[] HashLL;
//HASH FUNCTION - Finds sum of ascii values for string
public static int charSum(String s){
int hashVal = 0;
int size = 1019; //Prime Number around size of 8 char of 'z', (8 chars is amoung largest consistantly in dictionary)
for(int i = 0; i < s.length(); i++){
hashVal += s.charAt(i);
}
return hashVal % size;
}
//CREATE EMPTY HASH TABLE - Creates an array of LL
public static void makeHash(){
HashLL = new LinkedList[1019];
for(int i=0; i<HashLL.length; i++){
HashLL[i] = new LinkedList<String>();
}
}
//HASH VALUES INTO TABLE!
public static void dictionary2Hash(LinkedList<String> Dict){
for(String s : Dict){
HashLL[charSum(s)].add(s);
//Finds sum of char vales of dictionary element i,
//and then word at i to the HashLL at point defined
//by the char sum.
}
//Print out part of Hash Table (for testing! for SCIENCE!)
//System.out.println("HASH TABLE::");
//printHashTab();
}
//SEARCH HashTable for input word, return true if found
public boolean isWord(String s){
if(HashLL[charSum(s)].contains(s)){
wordsfound++;
return true;
}
return false;
}
}
I have made some attempts to change this, but for things like if(HashLL[charSum(s)].contains(s)) which searches the LL at the element returned by charsum(s)... I have no idea how to get it to work when it is a LL of Arrays and not of Strings. I have tired HashLL[charSum(s)].[1].contains(s)), and HashLL[charSum(s)][1].contains(s)), and various other things.
The fact that a Google search for "Array of Linked Lists of Arrays" (with quotes) turns up empty has not helped.
Last bit. I realize there might be another data structure that would do what I want, but unless you believe that a Array of LL of Arrays is a totally hopeless cause, I'd like to get it to work as is.
if you have
LinkedList<String[]>[] hashLL;
you can read a specific String like this (one of many ways)
String str = hashLL[outerArrayIndex].get(listIndex)[innerArrayIndex];
To write into the fields, this is possible (assuming everything is initialized correctly).
String[] arr = hashLL[outerArrayIndex].get(listIndex);
arr[index] = "value";
Or is there ?
I just have
int[] results
and want to check each element in array has the same int value.
(yeah I could just loop through them).
There's no need to loop, just convert the array into a Set object and then check its length, if the length is 1 then everything in the array was equal.
Integer[] myArray = ...;
assertThat(new HashSet(Arrays.asList(myArray)).size(), is(1));