I am trying to find the smallest value in an array of integers, but when I do I get an arrayindexoutofbounds on a place which, as far as I know, there shouldn't be a counting of array-index, only a comparison of the index and a min-value.
Part of code in question underneath:
}
System.out.println(sum);
int minste=tall[0];
for (int i : tall){
if(tall[i]<tall[0]){ //This is where the exception is made. But why?
minste=tall[i];
}
}
System.out.println(minste);
}
}
i is already an element, just use it. No need to tall[i]:
if(i < minste) {
This loop means: "For each int in tall".
In order to better understand the enhanced loop, think about it this way:
for(int i = 0; i < tall.length; i++) {
System.out.println(tall[i]);
}
Will print the same thing as:
for(int i : tall) {
System.out.println(i);
}
That's why it's recommended to use a meaningful name for the variable, instead of i, use item, so it'll be like "for each item in tall"...
Alternative solution to find the smallest value:
Use Arrays#sort
Return the first element in the array
When you're using the for-each loop, why use the indexes?
if(tall[i]<tall[0]){
tall[i] - gives the ArrayIndexOutOfBoundsException because i is an element in your array and not an index value. And that value i is definitely more than the length of your array.
All you need to do is thi
int minste = tall[0];
for (int i : tall) {
if(i < minste) {
minste = i;
}
}
You are using for-each loop, but try to use i as a index.
To work properly change your code to
int minste = tall[0];
for (int i : tall)
{
if(i < minste)
{
minste = i;
}
}
or
int minste = tall[0];
for (int i = 0; i<tall.length; i++)
{
if(tall[i] < minste)
{
minste = tall[i];
}
}
Related
I'm given an array of doubles, all numbers are equal except for one. My task is to find that unique number. My code returns the correct output and now I'm wondering how will I further optimize it.
This is my code:
public static double findUnique(double array[]) {
double unique = 0;
double common = 0;
for(int i=0; i<array.length; i++) {
for(int j=i+1; j<array.length; j++) {
if(array[i]==array[j]) {
common = array[i];
}
}
if(common!=array[i]) {
unique = array[i];
}
}
return unique;
}
The only thing I could think of is storing the length of the array first, but after some testing it actually took longer. Thanks.
public static double findUnique(double array[]) {
if(array.length < 3) {
throw new IllegalArgumentException("wrong array");
}
double common;
if(array[0] == array[1]) {
common = array[0];
} else {
return array[0] != array[2]? array[0]: array[1];
}
for(int i=2; i<array.length; i++) {
if(common != array[i]) {
return array[i];
}
}
throw new IllegalArgumentException("wrong array");
}
I belive that it is uneccesary to grab two new numbers in everey iteration.
Instead we could just start by grabbing the two first numbers of the array and then if those numbers are the same, we may compare the rest of the numbers to their value. So we define our common above the for loops, that way we will avoid the for loop and if statement containing: common= array[i] in every iteration. I belive this should make a difference in speed, at least if the array is crazy big.^^
Also, put the return inside the for loops so that you don't iterate the entire list even though you really found that piece of gold :):). (returning something always breaks the entire method.)
Hope I din't missunderstand anything :). Here's some code for you aswell. :)
public static double findUnique(double array[]) {
double common = 0;
if(array.length<3){
throw new IllegalArgumentException("Only two numbers exsists");
}
// Set up the common number seperately here.
if(array[0] == array[1]){
common = array[0];
}
else if(array[1] == array[2]){
return array[0];
}else{
return array[1];
}
// Now we iterate with return inside the for loop.
for(int i=2; i<array.length; i++) {
if(common!=array[i]) {
return array[i];
}
}
throw new IllegalArgumentException("All numbers are identical");
}
What if you sort the entire array first. Then just look at the first two and one last elements of the array.
So I am having trouble trying to find duplicates in an array where a user enters the numbers. I want to display a dialog when they enter a number that is already in the array. It sounds simple but is confused on how to go on about this.
//Convert the string into an int
num = Integer.parseInt(inputField.getText());
// Add it to the an index
array[index] = num;
// Increment the index variable
index++;
// If the the duplicate exists
for(int i = 0; i < array.length;i++){
if(array[index] == num){
if(array[i - 1] == num){
JOptionPane.showMessageDialog(null,"Array may not contain duplicates ","Array Duplicate",JOptionPane.ERROR_MESSAGE );
break;
}
}
}
Trying to fix your code here
//Convert the string into an int
num = Integer.parseInt(inputField.getText());
boolean exsist = false;
// If the the duplicate exists
for(int i = 0; i < array.length;i++){
if(array[i] == num){
exsist = true;
JOptionPane.showMessageDialog(null,"Array may not contain duplicates ","Array Duplicate",JOptionPane.ERROR_MESSAGE );
break;
}
}
if(!exsist)
{
// Add it to the an index
array[index] = num;
// Increment the index variable
index++;
}
something like this should work
The reasoning is
not using the variable i from the for loop, this results in checking the same value all the time
the checks in the if statements are broken, the checks simply don't make sense, try to use the ior other variables that change each loop to check multiple values
there is no need to add the value before testing if it exsist, if you do so you will have to remove it after, doing it after therefore result in a faster code (even if only very very little) and a safer code since you can't fail to delete the value
After some thinking and some suggestion. I managed to solve it.
// Set orginal to true
boolean orginal = true;
//Convert the string into an int
num = Integer.parseInt(inputField.getText());
// Loop to find the duplicate
for(int i = 0; i < array.length; i++){
// Check if there's a duplicate
for(int j = 0; j < array.length; j++){
// Check if the num is equal to any of the numbers in the array
if(array[j] == num){
// Set orginal to false
orginal = false;
// Throw the duplicate exception
throw new DuplicateValueException(result);
}
}
// If there is no duplicates
if(orginal){
// Add the number to the array
array[index] = num;
// Break out the loop
break;
}
}
// Print the message
System.out.println("array["+index+"] = "+ num);
// Increment the index variable
index++;
for(int i = 0; i < array.length-1;i++){
if(array[i] == num){
JOptionPane.showMessageDialog(null,"Array may not contain duplicates ","Array Duplicate",JOptionPane.ERROR_MESSAGE );
break;
}
}
Try this!
But your code will add that number to array anyway as you are adding it before checking it.
This code makes no sense :
// Add it to the an index
array[index] = num;
// Increment the index variable
index++;
for(int i = 0; i < array.length;i++){
if(array[index] == num){
You add the num int at the index index of the array and then in the loop you want to check if index+1 == num.
In your logic you should rather check if index == num.
And anyway it is useless, you have done : array[index] = num;.
So if(array[index] == num) can be only true.
I want to display a dialog when they enter a number that is already in
the array
You should rather do the check of duplication number before adding it in the array.
The general idea would be iterating the array and if during the iteration, a element of the array is equals to num, you have not add num.
In the contrary case, if no element is equals to num, you have to add it.
It seems to be a school working, so I will not detail further the solution.
I think this will work for sure even for the case of [5->5]
index++;
// If the the duplicate exists
if (index > 0) {
for (int i = 0; i < array.length; i++) {
if (array[i] == num) {
JOptionPane.showMessageDialog(null, "Array may not contain duplicates ", "Array Duplicate", JOptionPane.ERROR_MESSAGE);
break;
}
}
}
I would like to use list.negativeNumbers(); to call out the part of a code, which counts how many negative numbers are in a list.
public void negativeNumbers(){
int negative = 0;
for (int i = 0; i <= size; i++){
if (i < 0) {
negative = negative + 1;
}
System.out.println("There are "+ negative +" negative elements in the list!");
}
}
Can you help me in creating a method, that could count negative numbers in the list the correct way?
public void negativeNumbers(){
int negative = 0;
for (int i = 0; i <= size; i++){
if (i < 0) {
negative = negative + 1;
}
System.out.println("There are "+ negative +" negative elements in the list!");
}
}
You will learn better by working out the solution for yourself.
Your code as presented is a good start but lacks:
a defined list of values to test.
a definition of the size of the list (use list.size()).
proper indexing of the list to access values to test (use list.get(i) or list[i]).
a test of each element in the list to determine its negativity. Your code tests whether the list increment variable is < 0.
negative = negative + 1 is ok, but simpler to write ++negative.
Here's a simple example:
import java.util.ArrayList;
public class negnum {
public static void main(String [] args) {
ArrayList<Integer> nums = new ArrayList();
nums.add(0);
nums.add(10);
nums.add(-10);
nums.add(20);
nums.add(-20);
nums.add(30);
nums.add(-30);
nums.add(40);
nums.add(-40);
nums.add(50);
int negs = 0;
for (int i = 0; i < nums.size(); i++){
int n = nums.get(i);
if (n < 0) {
++negs;
System.out.println(n);
}
}
System.out.println(negs +" negatives");
}
}
c:\dev>java negnum
-10
-20
-30
-40
4 negatives
If it is a list of integers you should not be doing "i < 0" but rather the number at index of i. If you were to do that, you would also want to do "< size" rather than "<= size" or else you would run into an IndexArrayOutOfBounds.
It depends on how your double linked list is implemented, but if it extends the normal List<Integer> interface it would look like:
final Integer ZERO = Integer.valueOf(0);
int countNegativeElements() {
return stream().filter(MyList::isNegative).count();
}
static boolean isNegative(Integer i) {
return i.compareTo(ZERO) < 0;
}
with streams. More traditionally with an collection for-each (or an iterator for-each):
int countNegativeElements() {
int count = 0;
for(Integer i : this) { // or iterator()
if (isNegative(i)) count++;
}
return count;
}
This does not expect concurrent modifications and is optimized for collections where iterating is the fastest access. If you have a simple type list then you can replace isNegative with a simple < 0.
This article here talks about different ways to iterate a collection.
In my code I assumed you will add the method directly to your list implementation class. Replace this or this.iterator() or this.stream() with your actual list instance if it is external.
Update:
I just saw your link to the actual linked list you are using, this would look like this (hand made iteration):
int countNegativeElements() {
Node n = start;
int count = 0;
while(n != null) {
if (n.getData() < 0) count++;
n = n.getLinkNext();
}
return count;
}
Using null since there is no hasLinkNext() which would be typical for homework :)
I don't think it is a particular good idea to work with implementations which do not fit in the Collections framework, but maybe it is required to keep the lessons simple.
Hi I am new to java and am trying to understand the arraylist. I am using Arraylist theList and dummyValues. I read the values from theList and update the float values in dummyValues. My code snippet is as follows
`
public static void generateValues(ArrayList<Float> theList) {
for (int j = 0; j < theList.size(); j++) {
if (dummyValues.size()==0)
dummyValues.add(j, theList.get(j));
else
dummyValues.set(j, theList.get(j));
}
}
I trying add the values to the ArrayList dummyValues in the first condition and in the second condition if the size dummyValues is greater than 0 just update the values of dummyValues. I have considered this method to avoid duplicate copies.
But, when I execute it I get the following error :
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
The error occurs here dummyValues.set(j, theList.get(j));
I know this is a trivial concept, any kind of help is appreciated
I would suggest this improvement. Change your method to this:
public static void generateValues(ArrayList<Float> theList) {
for (int j = 0; j < theList.size(); j++) {
if (dummyValues.size()==0){
dummyValues.add(j, theList.get(j));
}
else if(dummyValues.size()==theList.size()){
dummyValues.set(j, theList.get(j));
}
else{
dummyValues.add(theList.get(j));
}
}
Check for size of both lists, if lists aren't same size it will add new element to dummy list instead of try to set element on nonexisting index.
In this case its possible that lists wont have same order.
EDIT: This is not right answer!!! Sorry I'm writting faster than thinking. :(
It works only if theList.size() > dummyValues.size(). I'll try to imprvove my answer ;)
EDIT2: Hello again.
Did some work and I'm back. I reworked your method and have second, in my opinion better, solution for you. Check this:
public static void generateValues(List<Float> theList) {
if (dummyValues.size() >= theList.size()) {
for (float value : theList) {
dummyValues.set(theList.indexOf(value), value);
}
}
else {
for (float value : theList) {
dummyValues.add(dummyValues.size(), value);
}
}
}
Try it out and let me know if it fits your needs.
Consider that if dummyList is empty, when j is 0 it adds one element from theList to it, but when j is 1 you are trying to set the element on position 1 from dummyList. But at that moment, dummyList only has one element, which is on position 0. This is why you're getting the error.
One solution would be to ensure that you create dummyList with the initial capacity (or size if you prefer) as theList's size.
public static void generateValues(ArrayList<Float> theList) {
for (int j = 0; j < theList.size(); j++) {
if (dummyValues.size()==0){
dummyValues = new ArrayList<>(theList.size());
dummyValues.add(j, theList.get(j));
} else
dummyValues.set(j, theList.get(j));
}
}
You haven't accounted for the fact that if dummyValues only has 1 element in it, it will pass dummyValues.size()==0) but will only have an index of 0 since ArrayList begins counting at 0. So if we're at index 1 of theList it will throw you the exception in question.
You may have to add another condition for dummyValues.size()==1) that's all :)
Make sure the variables and initialised.
dummyValues = new ArrayList<Float> ();
Then you can do this checking before doing anything in code -
public void generateValues(ArrayList<Float> theList) {
if (theList.size() > 0) {
for (int j = 0; j < theList.size(); j++) {
if (dummyValues.size() == 0) {
dummyValues.add(theList.get(j));
} else {
try {
if (dummyValues.get(j) != null) {
dummyValues.set(j, theList.get(j));
}
} catch (IndexOutOfBoundsException e) {
//no element present here .
}
}
}
}
}
This will check if theList has any value at all then start the loop. if the dummyValues is empty then add the 0th element or go on replacing the dummyValues with the theList values.
Give this a try and let me know if it works for you.
Let's say I have an array in the length of n, and the only values that can appear in it are 0-9. I want to create a recursive function that returns the number of different values in the array.
For example, for the following array: int[] arr = {0,1,1,2,1,0,1} --> the function will return 3 because the only values appearing in this array are 0, 1 and 2.
The function receives an int array and returns int
something like this:
int numOfValues(int[] arr)
If you are using Java 8, you can do this with a simple one-liner:
private static int numOfValues(int[] arr) {
return (int) Arrays.stream(arr).distinct().count();
}
Arrays.stream(array) returns an IntStream consisting of the elements of the array. Then, distinct() returns an IntStream containing only the distinct elements of this stream. Finally, count() returns the number of elements in this stream.
Note that count() returns a long so we need to cast it to an int in your case.
If you really want a recursive solution, you may consider the following algorithm:
If the input array is of length 1 then the element is distinct so the answer is 1.
Otherwise, let's drop the first element and calculate the number of distinct elements on this new array (by a recursive call). Then, if the first element is contained in this new array, we do not count it again, otherwise we do and we add 1.
This should give you enough insight to implement this in code.
Try like this:
public int myFunc(int[] array) {
Set<Integer> set = new HashSet<Integer>(array.length);
for (int i : array) {
set.add(i);
}
return set.size();
}
i.e, add the elements of array inside Set and then you can return the size of Set.
public int f(int[] array) {
int[] counts = new int[10];
int distinct = 0;
for(int i = 0; i< array.length; i++) counts[array[i]]++;
for(int i = 0; i< counts.length; i++) if(counts[array[i]]!=0) distinct++;
return distinct;
}
You can even change the code to get the occurrences of each value.
You can try following code snippet,
Integer[] arr = {0,1,1,2,1,0,1};
Set<Integer> s = new HashSet<Integer>(Arrays.asList(arr));
Output: [0, 1, 2]
As you asked for a recursive implementation, this is one bad way to do that. I say bad because recursion is not the best way to solve this problem. There are other easier way. You usually use recursion when you want to evaluate the next item based on the previously generated items from that function. Like Fibonacci series.
Ofcourse you will have to clone the array before you use this function otherwise your original array would be changed (call it using countDistinct(arr.clone(), 0);)
public static int countDistinct(int[] arr, final int index) {
boolean contains = false;
if (arr == null || index == arr.length) {
return 0;
} else if (arr.length == 1) {
return 1;
} else if (arr[index] != -1) {
contains = true;
for (int i = index + 1; i < arr.length; i++) {
if (arr[index] == arr[i]) {
arr[i] = -1;
}
}
}
return countDistinct(arr, index + 1) + (contains ? 1 : 0);
}
int numOfValues(int[] arr) {
boolean[] c = new boolean[10];
int count = 0;
for(int i =0; i < arr.length; i++) {
if(!c[arr[i]]) {
c[arr[i]] = true;
count++;
}
}
return count;
}