public static String[] dictionary(String s){
int count=0;
String[] ans = sentence(s);
int size = ans.length;
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < ans.length; j++) {
if (ans[i].compareTo(ans[j]) > 0) {
String temp = ans[i];
ans[i] = ans[j];
ans[j] = temp;
}
}
}
for (int i = 0; i < ans.length; i++) {
ans[i] = [i].to lowerCase);
}
return ans;
}
I have to find duplicated strings and remove them from an array of strings that are sorted lexicographically
Because you know that incoming array sorted, you can get current element and compare next elements with current one. If it is equals skip it, otherwise add this element to the result, and change current. Something like this
public static String[] dictionary(String s){
String[] ans = sentence(s);
if (ans == null || ans.length == 0) {
return ans;
}
List<String> result = new ArrayList<String>();
String current = ans[0];
result.add(current);
for (int i= 1; i < ans.length; i++) {
if (!ans[i].equals(current)) {
result.add(ans[i]);
current = ans[i];
}
}
return result.toArray(new String[0]);
}
If you don't want to use sets, you can do it like this. And it does not require a sorted array. It works as follows. Note: This changes the passed in array.
Get the first element. If it is null continue to next element.
Compare first element to next.
If equal, replace next with a null and increment removed
Continue processing elements.
Now create a new array of original size minus - removed.
And copy all non null values to new array and return it.
public static String[] removeDups(String[] arr) {
// keep track of removed values
int removed = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[i] == null) {
// skip this entry and go to next
break;
}
if (arr[i].equals(arr[j])) {
// designate as removed
arr[j] = null;
removed++;
}
}
}
// copy remaining items to new array and return.
String[] result = new String[arr.length-removed];
int k = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != null) {
result[k++] = arr[i];
}
}
return result;
}
If you want to do it with streams you can do it this way.
String[] result = Arrays.stream(arr).distinct().toArray(String[]::new);
A simple way to do this would be to place them into a set
Set<String> setsHaveNoDuplicates = new HashSet<>(Arrays.asList(ans));
Sets have no duplicates, and if you want to convert the set back to an array of strings, you can do this
String[] result = setsHaveNoDuplicates.toArray(new String[0]);
Related
I have homework about arrays in Java and I am stuck on this question.
Fill in the body of the program below, which removes duplicate values from the sorted array input. Your solution should set the variable result to the number of values remaining after the duplicate values have been removed. For example, if input is (0,1,1,2,3,3,3,4,4), the first five values of input after removing the duplicates should be (0,1,2,3,4), and the value of result should be 5.
Here's my code:
import java.util.Scanner;
public class RemoveDups {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
int[] input = 0,1,1,2,3,3,3,4,4;
int result;
int count = input[0];
result++;
String count1="";
int result2=0;
count1=count1+count;
input[0]=Integer.parseInt(count1);
count1="";
for (int j = 1; j <input.length-1;j++ ) {
if (count != input[j+1] && result2 == 0||count != input[j-1] &&result2==0 ) {
input[j] = count;
result++;
count = input[j + 1];
count1=count1+count;
input[j]=Integer.parseInt(count1);
count1="";
}
}
for (int i = 0; i < result; i++) {
System.out.println(input[i]);
}
}
}
}
I can't do this exercise. i have left always the last cell in array that is different from all another cells and this code not working for me.
public static int removeDuplicateElements(int arr[], int n){
if (n==0 || n==1){
return n;
}
int j = 0;
for (int i=0; i < n-1; i++){
if (arr[i] != arr[i+1]){
arr[j++] = arr[i];
}
}
arr[j++] = arr[n-1];
return j;
}
public static void main(String args []) {
int arr[] = {0,1,1,2,3,3,3,4,4};
int length = arr.length;
length = removeDuplicateElements(arr, length);
for (int i=0; i<length; i++)
System.out.print(arr[i]+" ");
}
Answer will be 0 1 2 3 4
Please refer following link.
Remove Duplicate Element in Array using separate index
I am not sure if you needed a filtered array or just the result value. The below will give you result value.
Since this is homework, I suggest you work on the below logic to create the non duplicate array.
int result = 1;
if(input == null || input.length == 0){
result = 0;
}
else{
for(int i = 1; i < input.length; i++){
if(input[i-1] != input[i]){
result++;
}
}
}
I have to solve an exercise with the following criteria:
Compare two arrays:
int[] a1 = {1, 3, 7, 8, 2, 7, 9, 11};
int[] a2 = {3, 8, 7, 5, 13, 5, 12};
Create a new array int[] with only unique values from the first array. Result should look like this: int[] result = {1,2,9,11};
NOTE: I am not allowed to use ArrayList or Arrays class to solve this task.
I'm working with the following code, but the logic for the population loop is incorrect because it throws an out of bounds exception.
public static int[] removeDups(int[] a1, int[] a2) {
//count the number of duplicate values found in the first array
int dups = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
dups++;
}
}
}
//to find the size of the new array subtract the counter from the length of the first array
int size = a1.length - dups;
//create the size of the new array
int[] result = new int[size];
//populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
return result;
}
I would also love how to solve this with potentially one loop (learning purposes).
I offer following soulution.
Iterate over first array, and find out min and max it's value.
Create temporary array with length max-min+1 (you could use max + 1 as a length, but it could follow overhead when you have values e.g. starting from 100k).
Iterate over first array and mark existed values in temorary array.
Iterate over second array and unmark existed values in temporary array.
Place all marked values from temporary array into result array.
Code:
public static int[] getUnique(int[] one, int[] two) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < one.length; i++) {
min = one[i] < min ? one[i] : min;
max = one[i] > max ? one[i] : max;
}
int totalUnique = 0;
boolean[] tmp = new boolean[max - min + 1];
for (int i = 0; i < one.length; i++) {
int offs = one[i] - min;
totalUnique += tmp[offs] ? 0 : 1;
tmp[offs] = true;
}
for (int i = 0; i < two.length; i++) {
int offs = two[i] - min;
if (offs < 0 || offs >= tmp.length)
continue;
if (tmp[offs])
totalUnique--;
tmp[offs] = false;
}
int[] res = new int[totalUnique];
for (int i = 0, j = 0; i < tmp.length; i++)
if (tmp[i])
res[j++] = i + min;
return res;
}
For learning purposes, we won't be adding new tools.
Let's follow the same train of thought you had before and just correct the second part:
// populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
To this:
//populate the new array with the unique values
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
result[position] = a1[i];
position++;
}
}
I am assuming the "count" that you implemented was in attempt to prevent false-positive added to your result array (which would go over). When a human determines whether or not an array contains dups, he doesn't do "count", he simply compares the first number with the second array by going down the list and then if he sees a dup (a1[i] == a2[j]), he would say "oh it's not unique" (unique = false) and then stop going through the loop (break). Then he will add the number to the second array (result[i] = a1[i]).
So to combine the two loops as much as possible:
// Create a temp Array to keep the data for the loop
int[] temp = new int[a1.length];
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
temp[position] = a1[i];
position++;
}
}
// This part merely copies the temp array of the previous size into the proper sized smaller array
int[] result = new int[position];
for (int k = 0; k < result.length; k++) {
result[k] = temp[k];
}
Making your code work
Your code works fine if you correct the second loop. Look at the modifications I did:
//populate the new array with the unique values
int counter = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
result[counter] = a1[i];
counter++;
}
}
}
The way I would do it
Now, here is how I would create a method like this without the need to check for the duplicates more than once. Look below:
public static int[] removeDups(int[] a1, int[] a2) {
int[] result = null;
int size = 0;
OUTERMOST: for(int e1: a1) {
for(int e2: a2) {
if(e1 == e2)
continue OUTERMOST;
}
int[] temp = new int[++size];
if(result != null) {
for(int i = 0; i < result.length; i++) {
temp[i] = result[i];
}
}
temp[temp.length - 1] = e1;
result = temp;
}
return result;
}
Instead of creating the result array with a fixed size, it creates a new array with the appropriate size everytime a new duplicate is found. Note that it returns null if a1 is equal a2.
You can make another method to see if an element is contained in a list :
public static boolean contains(int element, int array[]) {
for (int iterator : array) {
if (element == iterator) {
return true;
}
}
return false;
}
Your main method will iterate each element and check if it is contained in the second:
int[] uniqueElements = new int[a1.length];
int index = 0;
for (int it : a1) {
if (!contains(it, a2)) {
uniqueElements[index] = it;
index++;
}
}
I have an Array of Cars that contains Car objects and I've been stuck for a while now on the method that gets a car number and needs to delete all objects that has that car number and then return that array without any holes. it's my homework so I can't use any arrayList or Array. methods.
I've tried to do the following but for some reason when I try to run it, it doesn't complie and gives me a IndexOutOfBounds error and refer me to my toString method(it prints all of the cells in the array).
noOfCars, saves the amount of cars there actually is right now as we built the array with a container constructor for holding more places for future cars just in case.
public void removeCarNumbers(int CarNum) {
int count = 0;
for(int i = 0; i < this.noOfCars; i++) {
if(this.cars[i].getCarNum() == CarNum) {
this.cars[i] = this.cars[noOfCars- 1 - count];
count++;
}
}
CarsLines [] newArr = new CarLines[this.noOfCars- count];
for(int i = 0; i< this.noOfCars - count; i++)
{
newArr[i] = this.cars[i];
}
this.cars= newArr;
}
*edit: after playing with it more I still get an error that refers me to my toString() method. is there a problem with it as well?
public String toString()
{
String output = "";
for (int i = 0; i < this.noOfCars; i++)
output += "" + this.cars[i].toString() + "\n";
return output;
}
Try:
// count
int count = 0;
for(int i = 0 ; i < this.cars.length ; ++i) {
if(this.cars[i].getCarNum() == CarNum) {
++count;
}
}
// create new array
CarsLines[] newArr = new CarLines[this.cars.length - count];
int index = 0;
for(int i = 0 ; i < this.cars.length ; ++i) {
if(this.cars[i].getCarNum() != CarNum) {
newArr[index++] = this.cars[i];
}
}
// assign
this.cars = newArr;
I don't think those two loops are doing what you think they are. In the first loop you should eliminate Cars which have the same number, perhaps setting them to null:
for (int i = 0; i < this.cars.length; i++) {
if (this.cars[i] != null && this.cars[i].getCarNum() == CarNum) {
this.cars[i] == null;
} else {
count++;
}
}
This will now eliminate duplicates, and keep a count of unique Cars. In the second loop, fill in just the non-null values:
CarsLines [] newArr= new CarLines[count];
int index = 0;
for(int i = 0; i< this.cars,length; i++)
{
if (this.cars[i] != null) { // Only pass in the non-null values
newArr[index] = this.cars[i];
index++;
}
}
this.cars= newArr;
Before you had this creating pretty much an identical copy of your list because you were filling it in on a one-to-one basis i.e. the same index.
Another possible way of doing this would be an in place conversion:
for (int i = 0; i < this.cars.length; i++) {
if (this.cars[i] != null && this.cars[i].getCarNum() == CarNum) {
for (int j = i+1; j < this.cars.length; j++) { // This loop will shift the
this.cars[j-1] = this.cars[j]; // whole list down one when
} // a duplicate is found,
// overwriting it.
i--; // sets the index back to recheck the shifted list.
this.noOfCars--; // You removed one duplicate by overwriting it
}
}
In response to #Boris The Spiders Comment, you could reduce the complexity of this algorithm by eliminating the inner for loop. I would recommend doing this by tracking the last valid position and using that for updating.
int writeIndex = 0;
for (int readIndex = 0; readIndex < this.cars.length; readIndex++) {
if (this.cars[readIndex] != null && this.cars[readIndex].getCarNum() == CarNum) {
// pass on this because nextIndex should track only the valid cars.
} else {
this.cars[writeIndex++] = this.cars[readIndex];
}
if (writeIndex < readIndex) {
this.cars[i] = null;
}
}
The idea is that you keep one index for reading (i) and one index for writing writeIndex. If your readIndex gets ahead of your writeIndex (this means you found a duplicate) you should clear it after it is read, and you will transer if to the previous writeIndex.
EDIT In response to the addition to your question, you should be extra careful on how noOfCars is calculated as this is probably the source of your Exception, instead try a more reliable indexing method by using the intrinsic length property from your array:
public String toString() {
String output = "";
for (int i = 0; i < this.cars.length; i++) {
if (this.cars[i] != null) {
output += "" + this.cars[i].toString() + "\n";
} else {
// condition that the i-th car is null
output += "null\n"; // one possible approach
// you could also do nothing and your toString would output just the non-null cars
}
}
return output;
}
for reliability, at the cost of efficiency, you could implement a count() method to double check your tracking. Maybe as a temporary check until your sure it is working correctly.
public int getNumCars() {
int c = 0;
for (int i = 0; i < this.cars.length; i++) {
if (this.cars[i] != null) {
c++;
}
}
return c;
}
For every car that you remove try swapping the last element in the array into the "hole". Keepa counter for the max element that is valid and decrement it everytime you swap out an element into the hold. You are basically rearragning the array elemtns in place
int max=this.noOfCars.length;
int i=0;
do{
if(this.cars[i]==null)
break;
if(this.cars[i].getCarNum() == CarNum) {
this.cars[i] = this.cars[max-1];
this.cars[max-1] = null;
}
else{
i++;
}
}while(1==1);
PS: you might have to add a few checks for boundary conditions(like empty array)
Here is a simple example of how to do this with a single loop, no nested loops.
The idea is that you keep track of how maybe elements you have removed (also how many null elements you have found) and then, if the current element is not to be removed, just shift it back by that number.
public static void main(final String[] args) throws IOException {
final Integer[] data = {1, 2, 2, 3, 4, 5, 1, 2, 3, 7, 8, 2, null, null, null};
int shift = 0;
for (int i = 0; i < data.length; ++i) {
if (data[i] == null || data[i] == 2) {
shift++;
data[i] = null;
} else if (shift > 0) {
data[i - shift] = data[i];
data[i] = null;
}
}
System.out.println(Arrays.toString(data));
}
Output:
[1, 3, 4, 5, 1, 3, 7, 8, null, null, null, null, null, null, null]
So you can see the 2s have been removed and the rest have been shifted up.
I'm coding trough codingbat.com/java and ran into an error i don't understand. I got two String arrays and want to compare them. If I just use the arrays all works fine (but the result is not right). To get the right result I programmed a helper function which eliminates all duplicates of an array. I tested the helper function, it returns the array shortened of the duplicates.
I can retrieve the values in the new Arrays with _a[i] etc., and don't get errors, but if i use _a[0].equals(_b[0]) or _a[0].compareTo(_b[0]) I get a NullPointerException (_a[0] == _b[0] works fine...).
If I just use the original arrays a,b the code runs without problems. I don't comprehend why i get a NullpointerException there.
Thanks for any help!
Code:
public int commonTwo(String[] a, String[] b) {
String[] _a = killDuplicate(a);
String[] _b = killDuplicate(b);
int ai=0, bi=0,count=0;
for (int i = 0; ai < _a.length & bi < _b.length; i++){
if ( _a[ai].compareTo(_b[bi]) > 0) { //NullPointerException here, but not if I use a,b
bi++;
} else if ( _a[ai].compareTo(_b[bi]) < 0){ //NullPointerException here, but not if I use a,b
ai++;
} else {
count++;
ai++;
bi++;
}
}
return count;
}
Helper Function:
public String[] killDuplicate(String[] a){
String temp = "";
int counter = 0, counter2 = 0;
for (int i = 0; i < a.length; i++){
if (! a[i].equals(temp)){
temp = a[i];
} else {
a[i] = "";
counter++;
}
}
String[] result = new String[a.length - counter];
for (int i = 0; counter2 < counter; i++){
if (a[i].equals("")) {
counter2++;
}
} else {
result[i-counter2] = a[i];
}
return result;
}
I guess you assume that your array of strings is sorted, otherwise your killDuplicate method wouldn't make sense at all.
The problem with your code is that in the second for loop in killDuplicate method you iterate with condition counter2 < counter which says iterate until all found duplicates are passed. So when you find your last duplicate you exit without filling the rest of the array. Try with example: new String[]{"A", "A", "B", "C"} you'll get [A, null, null].
There are numerous things that can be improved but the simplest modification of your code below. (I've changed only the second for loop)
public String[] killDuplicate(String[] a) {
String temp = "";
int counter = 0, counter2 = 0;
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(temp))
temp = a[i];
else {
a[i] = "";
counter++;
}
}
String[] result = new String[a.length - counter];
for (int i = 0; i < a.length; i++) {
if (a[i].equals("")) continue;
result[counter2] = a[i];
counter2++;
}
return result;
}
I have 5 float arrays all of the same length. At any given time: all, none or some of the arrays may be null (uninitialized).
I am trying to create a function which will add up the values of the arrays and produce a final array with the summed up values in position.
Is there a way to only include the values from the populated arrays?
Thanks,
m
You'd have to check for it. Something like:
/**
* Assumes that all rows are the same length as the first row.
*/
public float[] addValues(float[][] values){
float[] result = new float[values[0].length];
for(float[] row : values){
if(row != null){
for(int i = 0; i < row.length; i++){
result[i] += row[i];
}
}
}
return result;
}
public float[] addUp(float[][] yourArrays) {
if(yourArrays == null)
return null;
int i, j;
int arrayLength = 0;
float[] toReturn = null;
//get the length of the array that will be returned
for(i = 0; i < yourArrays.length; i++) {
if((yourArrays[i] != null) && yourArrays[i].length > arrayLength)
arrayLength = yourArrays[i].length;
}
//now build the array that will be returned, but only if there
//have been any values at all
if(arrayLength != 0) {
//create the array
toReturn = new float[arrayLength];
//fill it
for(i = 0; i < yourArrays.length; i++) {
for(j = 0; j < arrayLength; j++) {
if((yourArrays[i] != null)
&& (j < yourArrays[i].length)
toReturn[j] += yourArrays[i][j];
}
}
}
return toReturn;
}
This should do what you want; it selects only values from arrays that have been initialized, only up until the last element of each array (so you won't have an ArrayOutOfBoundsException) and only if there where any values at all.
Runtime is in O([length of the longest array] * [number of arrays]).
Return values arenull if none of the arrays were initialized or if the longest array that was initialized had a length of 0;
a float[] holding in each cell the sum of all values for which any of your initial arrays had something set.
First of all, array objects have a length, but array references don't. Only a reference can be null (which means that it refers to no object). Your initial problem description is therefore somewhat in error.
But in any case, you can trivially check if an array reference is null:
if (theArray != null) {
// add in contribution from theArray
...
Can you use Float ?
List<Float> newArr = new ArrayList<Float>();
for (float[] arr : arrays)
{
if (arrf != null)
{
for (float number : arr) { newArr.add(number); }
}
}
newArr.toArray(new Float[0]);
yes you can create a final array by the sum size of all the arrays
then you start a for for each array
then if the value is not null you add it to the final
String[] a = new String[5];
String[] b = new String[5];
String[] c = new String[5];
String[] d = new String[5];
String[] e = new String[5];
String[] finalarray = new String[a.length + b.length + c.length + d.length + e.length];
int count = 0;
for (int i = 0; i < a.length; i++) {
if(a[i] != null){
finalarray[count] = a[i];
count++;
}
}
for (int i = 0; i < b.length; i++) {
if(b[i] != null){
finalarray[count] = b[i];
count++;
}
}
for (int i = 0; i < c.length; i++) {
if(c[i] != null){
finalarray[count] = c[i];
count++;
}
}
for (int i = 0; i < d.length; i++) {
if(d[i] != null){
finalarray[count] = d[i];
count++;
}
}
for (int i = 0; i < e.length; i++) {
if(e[i] != null){
finalarray[count] = e[i];
count++;
}
}