Related
This question already has answers here:
Enhanced 'for' loop causes an ArrayIndexOutOfBoundsException
(2 answers)
Closed 4 years ago.
I am getting an array out of marks from this section, this section calculates the total mark by multiplying the weight of each assessment by the marks of each assessment. Any marks that gets a -1 is automatically set as 0 and not counted.
public double totalMark(){
int [] assessments = {2,2,2,2,1,1,1,1,2,2,1,3,70}; //Weight of each assessment
int totalMark = 0;
int overallmark = 0;
for (int i : marks) //marks of each assignment
if (marks[i] == -1) {
assessments[i] = 0;
}
for (int i : marks) {
totalMark =+ assessments[i] * marks[i];
}
for (int i : assessments) {
overallmark =+ assessments[i];
}
return totalMark/overallmark;
}
This is my main method:
public static void main(String args[]) {
int[] samsMarks = {50, 60, 65, 60, 65, 70, 55, 66, 60, 73, 65, 45, 68, 54};
int[] billysMarks = {50, 60, -1, 60, 65, 70, 55, 66, 60, 73, 65, 45, 68, 54};
Student sam = new Student("1111111", samsMarks);
Student billy = new Student("1111112", billysMarks);
System.out.println(billy.totalMark);
}
Replace all your
for (int i : marks)
with
for (int i = 0; i < marks.length; i++)
and
for (int i : assessments)
with
for (int i = 0; i < assessments.length; i++)
When you use
for (int i : marks)
i is not the index of marks but the elements that marks contains:
50, 60, 65, 60, 65, 70, 55, 66, 60, 73, 65, 45, 68, 54
As mentioned in the first answer you are using the for in this way:
for(element : list)
but since you need the index you should use it in the following form
for(initialization; termination; increment)
also a suggestion for the code instead of doing 3 loops through the element i suggest you do it in one iteration and you code can be as the following(since the number of element of both marks and assignment are the same)
for (int i = 0; i < marks.length; i++) {
if (marks[i] == -1) {
assessments[i] = 0;
}
totalMark =+ assessments[i] * marks[i];
overallMark =+ assessments[i];
}
You are iterating assessments array with a marks iterator and they might not be the same length. Check that.
These 2 loops are very problematic (both are accessing assessments and worry only about marks length:
for (int i : marks) //First problematic loop
if (marks[i] == -1) {
assessments[i] = 0;
}
for (int i : marks) { //Second problematic loop
totalMark =+ assessments[i] * marks[i];
The question is to write a program which takes two arrays of 10 integers each, a and b. c is an array with 20 integers. The program should put array a and b into the array c, the first 10 integers of c from array a, the latter 10 from b. Then the program should display c. This is the code i have so far. It prints the values from arrayA into arrayC but i dont know how to print the values from arrayB into arrayC without overriding the information already in arrayC (arrayB).
public class questionTwo
{
public static void main(String[] args)
{
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [20];
for (int i = 0; i < arrayA.length; i++)
arrayC[i] = arrayA[i];
for (int i = 0; i < arrayB.length; i++)
{
int element = 9;
arrayC[element] = arrayB[i];
element++;
}
System.out.println("The values of ArrayC are: ");
for(int val : arrayC)
{
System.out.println(val);
}
}
}
Before explaining how you might fix your current code, I would first suggest you create arrayC using the lengths of arrayA and arrayB (here that has the same practical result, but it has the advantage that you can add more elements to arrayA or arrayB without modifying the code). Next, in real code, I would use System.arraycopy to perform the copies. And use Arrays.toString(int[]) for printing. Like,
int[] arrayA = { 31, 14, 5, 12, 50, 80, 100, 29, 58, 57 };
int[] arrayB = { 9, 13, 156, 78, 36, 46, 86, 98, 63, 2 };
int[] arrayC = new int[arrayA.length + arrayB.length];
System.arraycopy(arrayA, 0, arrayC, 0, arrayA.length);
System.arraycopy(arrayB, 0, arrayC, arrayA.length, arrayB.length);
System.out.println(Arrays.toString(arrayC));
As for your original code, use arrayA.length and i to get the correct offset. Like,
int[] arrayC = new int[arrayA.length + arrayB.length];
for (int i = 0; i < arrayA.length; i++) {
arrayC[i] = arrayA[i];
}
for (int i = 0; i < arrayB.length; i++) {
arrayC[i + arrayA.length] = arrayB[i];
}
You were really close! Your second loop initializes element to 9 every time, while you should only assign it to 10 once at the beginning:
int element = 10;
for (int i = 0; i < arrayB.length; i++)
{
arrayC[element] = arrayB[i];
element++;
}
Make your function dynamic while you need to add more item into your arrays. I did not test yet, but I hope it work.
public class questionTwo
{
public static void main(String[] args)
{
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [arrayA.length + arrayB.length];
for (int i = 0; i < arrayA.length; i++)
arrayC[i] = arrayA[i];
int element = arrayA.length;
for (int i = 0; i < arrayB.length; i++)
{
arrayC[element+i] = arrayB[i];
}
System.out.println("The values of ArrayC are: ");
for(int val : arrayC)
{
System.out.println(val);
}
}
}
The second loop is wrong. You can use the follow code:
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [20];
System.arraycopy(arrayA, 0, arrayC, 0, arrayA.length);
System.arraycopy(arrayB, 0, arrayC, arrayA.length, arrayB.length);
System.out.println("The values of ArrayC are: ");
for(int val : arrayC) {
System.out.println(val);
}
Your second loop is incorrect because you are setting element to 9 within the loop each time; thus, its value is always reset upon beginning the next iteration. You could move it outside the loop to achieve the result you're looking for. Also, I'd recommend constructing arrayC based on the lengths of arrayA and arrayB, that way you can combine array's of any length.
In addition, I'd also recommend moving the code to combine the arrays to a method to keep things clean and reusable for future endeavors.
public class questionTwo {
private static int[] combineArrays(int[] arrayA, int[] arrayB) {
int[] arrayC = new int[arrayA.length + arrayB.length];
int idx = 0;
for (int x : arrayA) {
arrayC[idx] = x;
idx++;
}
for (int x : arrayB) {
arrayC[idx] = x;
idx++;
}
return arrayC;
}
public static void main(String[] args) {
int[] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int[] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int[] arrayC = combineArrays(arrayA, arrayB);
System.out.println("The values of ArrayC are: ");
for(int val : arrayC) {
System.out.println(val);
}
}
}
Also, it is often considered a poor practice to use Java's primitive arrays. Check out List and related objects for more flexible and full-featured options.
I have 3 arrays iX, iY, and iZ with each holding 20 integers.
iX goes up by 5, iY goes up by 3, and iZ is the sum of both.
for (int i=5; i <=iX.length; i+=5)
{
iX[i] = i;
System.out.print (i + "\n");
}
for (int j=3; j <iY.length; j+=3)
{
iY[j] = j;
}
for (int k=0; k < iZ.length; k++)
{
iZ[k] = iX[k]+iY[k];
}
When I run it I get:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at Quiz10RTN.main(Quiz10RTN.java:61)"
Line 61 is : iX[i] = i;
I can't seem to get it to even print out 20 numbers, because it seems to be treating my limit of 20 integers as a range to stop at. Any help would be great, Thanks.
Issue is here
for (int i=5; i <=iX.length; i+=5)
^
There is no index match with iX.length in your array.
index of array start with 0, So if size of array is n, then you only have indexes from 0 to n-1.
You can use following to avoid the exception. But you need to think some other way to archive your goal.
for (int i=5; i <iX.length; i+=5)
Edit: for your comment I was trying to print out "5, 10, 15, 20, 25...etc"
You can try something like following
for (int i=0; i <iX.length; i++) {
iX[i]=(i+1)*5; // now your array become 5,10,15,...
}
You are confusing your array indices with the values you are storing in the arrays.
So, for example, if you want your iX array to contain the 20 integers 5, 10, 15,...100, your first loop should look like:
for (int i=0; i < iX.length; ++i)
{
iX[i] = (i + 1) * 5;
System.out.print (iX[i] + "\n");
}
You aren't using the array indexes properly (they must be incremental). You might also use Arrays.toString(int[]) to print your arrays. I believe you wanted something like
int[] iX = new int[20];
int[] iY = new int[20];
int[] iZ = new int[20];
int valfive = 5; // <-- our five increments.
int valthree = 3; // <-- the three increments.
for (int i = 0; i < iX.length; i++) {
iX[i] = valfive;
iY[i] = valthree;
iZ[i] = valfive + valthree;
valfive += 5; // <-- add 5
valthree += 3; // <-- add 3
}
System.out.println("Multiples of five: " + Arrays.toString(iX));
System.out.println("Multiples of three: " + Arrays.toString(iY));
System.out.println("Sums of fives and threes: " + Arrays.toString(iZ));
Output is (formatted for SO)
Multiples of five: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70,
75, 80, 85, 90, 95, 100]
Multiples of three: [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42,
45, 48, 51, 54, 57, 60]
Sums of fives and threes: [8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96,
104, 112, 120, 128, 136, 144, 152, 160]
I have an arrayList filled with integers and I need to iterate through this arrayList, add the numbers up until a threshold is reached, then put the resulting sum into a second arrayList slot, and move back to where I left off in the original arrayList, keep iterating and summing until the threshold is reached and then put that in the second slot, and so on until all 40 original items have been summed and put into a smaller arrayList.
I've thought of using two nested loops but I can't get the two loops to work together.
I'm very new to Java and don't know how to do this. Any suggestions will be helpful.
This is what I have so far:
int threshold = 12;
int sumNum = 0;
int j = 0;
int arr1[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
for (int i = 0; i < arr1.length; i++) {
while (sumNum <= threshold) {
sumNum += arr[j];
j++
}//end while
}//end for
You can actually do this with just one loop. You don't need to move back, just stay where you are and keep going on the sum.
public static ArrayList<Integer> sums(ArrayList<Integer> arr, int threshold){
ArrayList<Integer> sumArr = new ArrayList<Integer>();
int s = 0; //Sum thus far, for the current sum
for(int i : arr){
s += i; //Add this element to the current sum
if(s >= threshold){ //If the current sum has reached/exceeded the threshold
sumArr.add(s); //Add it to the sumArray, reset the sum to 0.
s = 0;
}
}
return sumArr;
}
You can change the input param from ArrayList to int[] or Integer[] without any trouble whatsoever. Hooray for for-each loops!
Code to use the above:
public static void main(String[] args){
ArrayList<Integer> i = new ArrayList<Integer>();
//create arraylist 1..20
for(int x = 1; x <= 20; x++){
i.add(x);
}
System.out.println(sums(i).toString());
}
package com.test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
int threshold = 12;
int sumNum = 0;
int j = 0;
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
List myList = new ArrayList();
for (int i = 0 ; i < arr1.length ; i++) {
sumNum += i;
if (sumNum >= threshold) {
myList.add(sumNum);
sumNum = 0;
}
}
for (int a = 0 ; a < myList.size() ; a++) {
System.out.println(myList.get(a));
}
}
}
output
15
13
17
21
12
13
14
How about something like this:
/**
* Sequentially adds numbers found in the source array until the sum >= threshold.
* <p/>
* Stores each threshold sum in a separate array to be returned to the caller
* <p/>
* Note that if the last sequence of numbers to be summed does not meet the threshold,
* no threshold sum will be added to the result array
*
* #param numbersToSum The source number list
* #param threshold The threshold value that determines when to move on to
* the next sequence of numbers to sum
*
* #return An array of the calculated threshold sums
*/
public static Integer[] sumWithThreshold(int[] numbersToSum, int threshold)
{
List<Integer> thresholdSums = new ArrayList<Integer>();
if (numbersToSum != null)
{
int workingSum = 0;
for (int number: numbersToSum)
{
workingSum = workingSum + number;
if (workingSum >= threshold)
{
thresholdSums.add(workingSum);
workingSum = 0;
}
}
}
return thresholdSums.toArray(new Integer[thresholdSums.size()]);
}
public static void main(String[] args)
{
int[] testNumbers =
{
1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40};
int[] thresholds = {1, 42, 100, 200};
for (int threshold: thresholds)
{
System.out.println("Threshold sums for threshold = " + threshold + ":\n" + Arrays.toString(sumWithThreshold(testNumbers, threshold)));
}
}
That produces the following output:
Threshold sums for threshold = 1:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
Threshold sums for threshold = 42:
[45, 46, 45, 54, 63, 47, 51, 55, 59, 63, 67, 71, 75, 79]
Threshold sums for threshold = 100:
[105, 105, 115, 110, 126, 105, 114]
Threshold sums for threshold = 200:
[210, 225, 231]
I'm new to Java, and was given a question to solve as a weekend project. I ran into some troubles, and would like your help. Please understand I am a beginner. If I'm wrong somewhere, please explain it to me. I hope to be a good programmer too some day.
I did a through search, and found answers with things like "heatmaps" or "arraylists", something I probably won't be allowed to use since I haven't learned it yet.
Ok, so the question given to me was:
Find: 1) Mode, the most frequently occurring marks in the class. If 2 or more marks occur equally frequently, then the highest of these marks is the mode.
2) Mode Frequency: Frequency of mode.
It is assumed that the class has 10 students and marks are between 0 to 100.You are not allowed to sort the marks.
This is my code for finding the mode:
void mode()
{
int c[]=new int[10];
int arr[]=new int[10];
for (int i=0;i<10;i++)
{
for (int j=i+1;j<10;j++)
{
for (int k=0;k<10;k++)
{
if (marks[i]!=arr[k])
{
if (marks[i]==marks[j])
{
c[i]++;
break;
}
}
}
arr[i]=marks[i];
}
}
for (int k=0;k<10;k++)
{
System.out.println();
System.out.println(c[k]);
}
}
Where marks[] is the int array where I take the input, c[] is to count the number of times the number is occurring, and arr[] is an array to cross check if the number has previously occurred or not.
Let's assume the 10 numbers inputted are 99, 95, 97, 92, 80, 95, 73, 80, 95, 80. As you can see 95 and 80 occur three times.
So my c[] should have {0, 2, 0, 0, 2, 0, 0, 0, 0, 0}, but when I run it, it comes as {0, 2, 0, 0, 2, 1, 0, 1, 0, 0}, which means my program isn't cross checking with arr[].
I think I've made a mess using three for-loops. I can't seem to figure out how to solve it.
One solution would be to have an array of length 101 initialized to zero. This array would represent the number of times a specific mark had occurred. each time you encounter a specific mark you increment the count. Then to find the mode, you simple find the index with the highest count.
public class Loader
{
// We suppose that the parameter is not null
public static void mode_frequency(long collection[])
{
long frequencies[] = new long[collection.length];
for (int i = 0, l = collection.length; i < l; i++)
{
for (int j = i; j < l; j++)
{
if (collection[i] == collection[j])
{
++frequencies[i];
}
}
}
// With your example {99, 95, 97, 92, 80, 95, 73, 80, 95, 80}
// You should have somthing like {1, 3, 1, 1, 3, 2, 1, 2, 1, 1}
//
// As you can see, you just have to find the MAX frequency and then, print corresponding values from initial array
long frequency = 0;
for (int i = 0, l = frequencies.length; i < l; i++)
{
if (frequency < frequencies[i])
{
frequency = frequencies[i];
}
}
// Print each mode
for (int i = 0, l = collection.length; i < l; i++)
{
if (frequencies[i] == frequency)
{
System.out.println(collection[i]);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
mode_frequency(new long[]
{
99,
95,
97,
92,
80,
95,
73,
80,
95,
80
});
}
}
You may want to use an algorithm in which you use secondary arrays to accumulate the counts for individual marks, and then search through those secondary arrays for the mark with the highest frequency with largest value. Consider:
package com.example.mode;
public class Mode {
public static void main(String[] args) {
int[] marks = { 99, 95, 97, 92, 80, 95, 73, 80, 95, 80};
//One algorithm .. insert marks and add occurances, keeping in order
int[] unique = new int[marks.length];
int[] count = new int[marks.length];
int maxUnique = 0;
for (int i=0; i < marks.length ; i++) {
int loc = -1;
for (int j=0; j < maxUnique; j++) {
if (marks[i] == unique[j]) {
loc = j;
break;
}
}
if (loc == -1) {
loc = maxUnique;
unique[loc] = marks[i];
count[loc] = 0;
maxUnique++;
}
count[loc] = count[loc]+1;
}
int maxValue = unique[0];
int maxCount = count[0];
for (int j=1; j < maxUnique; j++) {
if (count[j] > maxCount || (count[j] == maxCount && maxValue < unique[j]) ) {
maxValue = unique[j];
maxCount = count[j];
}
}
System.out.println("Mode = " + maxValue + ", frequency = " + maxCount);
}
}