I am a computer science student in high school, and I was given a project where I have to create a program that can add the values of an integer array, count the number of values contained in the array, and remove every instance of a value in that array.
Here is the code, separated into three methods for each function described above:
import java.lang.System;
import java.lang.Math;
import java.util.Arrays;
public class ArrayFunHouse
{
//instance variables and constructors could be used, but are not really needed
//getSum() will return the sum of the numbers from start to stop, not including stop
public static int getSum(int[] numArray, int start, int stop)
{
int count = start;
int output = 0;
while(count<=stop)
{
output = output + numArray[count];
count++;
}
return output;
}
//getCount() will return number of times val is present
public static int getCount(int[] numArray, int val)
{
int x = 0;
int count = 0;
while(x<numArray.length)
{
if(val==numArray[x])
count++;
x++;
}
return count;
}
public static int[] removeVal(int[] numArray, int val)
{
int[] newArray = new int[ numArray.length - getCount(numArray, val) ];
int x = 0;
for(int position = 0; position < numArray.length; position++)
{
x = numArray[position];
if(x!=val)
{
newArray[position] = numArray[position];
}
}
return newArray;
}
}
And here is the runner designed to execute the code, including the sample data we were instructed to use:
import java.util.Arrays;
public class ArrayFunHouseRunner
{
public static void main( String args[] )
{
int[] one = {7, 4, 10, 0, 1, 7, 6, 5, 3, 2, 9, 7};
ArrayFunHouse test = new ArrayFunHouse();
System.out.println(Arrays.toString(one));
System.out.println("sum of spots 3-6 = " + ArrayFunHouse.getSum(one,3,6));
System.out.println("sum of spots 2-9 = " + ArrayFunHouse.getSum(one,2,9));
System.out.println("# of 4s = " + ArrayFunHouse.getCount(one,4));
System.out.println("# of 9s = " + ArrayFunHouse.getCount(one,9));
System.out.println("# of 7s = " + ArrayFunHouse.getCount(one,7));
System.out.println("new array with all 7s removed = " + test.removeVal(one,7));
System.out.println("# of 7s = " + ArrayFunHouse.getCount(ArrayFunHouse.removeVal(one,7),7));
int[] two = {4,2,3,4,6,7,8,9,0,10,0,1,7,6,5,3,2,9,9,8,7};
//add test cases
}
}
When I run the code, the following is output:
[7, 4, 10, 0, 1, 7, 6, 5, 3, 2, 9, 7]
sum of spots 3-6 = 14
sum of spots 2-9 = 34
# of 4s = 1
# of 9s = 1
# of 7s = 3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at ArrayFunHouse.removeVal(ArrayFunHouse.java:49)
at ArrayFunHouseRunner.main(ArrayFunHouseRunner.java:21)
Process completed.
As shown above, the code runs smoothly until it reaches the third method. What do I need to fix in order to get the code to run smoothly, as indicated by the error message?
In your removeVal function you are trying to set the index of the new array as the same index it had in the old array. As arrays get smaller, it can't place key 9 in an 8 item array.
Change it to this:
int newPosition = 0;// outside of loop
x = numArray[position];
if(x!=val)
{
newArray[newPosition] = numArray[position];
newPosition++;
}
for(int position = 0; position < numArray.length; position++)
{
x = numArray[position];
if(x!=val)
{
newArray[position] = numArray[position];
}
}
You can't use position to access both the target array and the source array. You need two variables, one of which isn't incremented if x == val.
I think it's because of this line: newArray[position] = numArray[position];. Since newArray is shorter than numArray, numArray will have position indices that are out of bounds for numArray. You'd probably want two position values, say "newArPos" and "numArPos", and you don't increment "newArPos" if you're excluding a value.
In your removeVal method you create a new array that is smaller then the original one. But in your for loop you loop through a number of times equal to the original larger array. Make sure in your loop you don't access the new smaller array in a spot that only exists in the original array.
Related
Sorry for bad expression to make people confused, i edit my question again.
There is Integer array , it contains 29 numbers, These 29 numbres are made up of 0 to 10.
For example: Integer [ ] num ={ 0,3,4,5,6,1,3,10,4,3,1,0,2,2,3,4,1,0,8,7,6,6,5,8,9,0,5,10,8} I want to realign these numbers into Jtable(limits 6 rows,10 columns).
if 0 <= number < 5,i will call them "Small" number;
if 5 <= number < 10,i will call them “Big" number;
if number = 10, i will call them "P"number.
In a word, the 29 numbers are made up of 3 type number("Samll","Big","P").
In the array num, we can see first three number is belong to "Small" number,so they show one by one in c1,the fourth is 5,it is "Big"number,so it jump to next column, it goes c2,the remaining cells of c1 will not be used again. if the same type number is over 6,it wil turn right to next nearest cell to contiune showing(See 2nd sample image).others array numbers are the same logic,loop the array num and then show the numbers according to the number type in jtable.
The final result what i want in Jtable ,you can see below sample images i post. Anybody posts sample code will be very helpful to me,Thanks in advance!
Below sencond sample image, the red underline number total 10 "Small" numbers over 6, so turn to the right nearest cell to contiune showing. The green underline total 7 "Big" numbers ,because the sixth cell in c6 has been occupied, so it turns right to contiune showing after fifth cell
I wrote code just to create the 6 x 10 int matrix.
Here's the output from one of my many tests.
0 5 1 10 4 8 0 5 10 8
3 6 3 3 7
4 1 6
0 6
2 5 8 9
2 3 4 1 0
Oracle has a helpful tutorial, Creating a GUI With JFC/Swing, that will help you learn how to create a Swing GUI. Skip the Netbeans section.
You will want to use a JTable to display your matrix.
When tackling a problem like creating your matrix, it helps to break it down into steps. Keep breaking it down into steps until you can code each step.
This task was so complicated, I had to print debug output to make sure I was making progress. Don't be afraid to put many System.out.print and System.out.println statements in your code. You can use a DEBUG boolean like I did to turn the extra print statements off.
Here's the complete runnable code to create the 6 x 10 matrix. I didn't check for more than 10 subsets of values. I left that for you.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class RealignNumbers {
private static final boolean DEBUG = false;
public static void main(String[] args) {
RealignNumbers rn = new RealignNumbers();
int[] numbers = { 0, 3, 4, 5, 6, 1, 3, 10, 4, 3, 1, 0, 2, 2, 3, 4, 1, 0,
8, 7, 6, 6, 5, 8, 9, 0, 5, 10, 8 };
int[][] matrix = rn.realignNumbers(numbers);
printMatrix(matrix);
}
private static void printMatrix(int[][] matrix) {
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix[row].length; column++) {
if (matrix[row][column] >= 0) {
String display = String.format("%3d", matrix[row][column]);
System.out.print(display);
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
public int[][] realignNumbers(int[] numbers) {
List<List<Integer>> matrixList = splitInput(numbers);
printList(matrixList);
int[][] matrix = fillMatrix(matrixList);
return matrix;
}
private List<List<Integer>> splitInput(int[] numbers) {
List<List<Integer>> matrixList = new ArrayList<>();
int number = numbers[0];
boolean isSmall = number < 5;
List<Integer> numberList = new ArrayList<>();
numberList.add(Integer.valueOf(number));
for (int index = 1; index < numbers.length; index++) {
if (numbers[index] == 10) {
// Finish prior List if exists
if (numberList.size() > 0) {
matrixList.add(numberList);
numberList = new ArrayList<>();
}
// Create numberList for 10
numberList.add(Integer.valueOf(numbers[index]));
matrixList.add(numberList);
// Start new List
numberList = new ArrayList<>();
} else {
boolean small = numbers[index] < 5;
if (isSmall == small) {
// Add number to List
numberList.add(Integer.valueOf(numbers[index]));
} else {
// Number is different; end list and start new List
matrixList.add(numberList);
numberList = new ArrayList<>();
numberList.add(Integer.valueOf(numbers[index]));
isSmall = small;
}
}
}
if (numberList.size() > 0) {
matrixList.add(numberList);
}
return matrixList;
}
private void printList(List<List<Integer>> matrixList) {
if (DEBUG) {
int count = 1;
for (List<Integer> numberList : matrixList) {
String display = String.format("%2d", count++);
System.out.print("List " + display + " ");
for (int number : numberList) {
display = String.format("%3d", number);
System.out.print(display);
}
System.out.println();
}
}
}
private int[][] fillMatrix(List<List<Integer>> matrixList) {
int masterColumn = -1;
int length = 6;
boolean firstTimeSwitch = true;
int[][] matrix = new int[length][10];
for (int[] row : matrix) {
Arrays.fill(row, -1);
}
for (List<Integer> numberList : matrixList) {
masterColumn++;
int column = masterColumn;
int row = 0;
for (int number : numberList) {
if (DEBUG) {
System.out.println("row " + row + " column " + column);
}
matrix[row][column] = number;
// Check if we hit the last row
// If so, increment columns
if (row < (length - 1)) {
row++;
} else {
if (firstTimeSwitch) {
length--;
firstTimeSwitch = false;
}
column++;
}
}
if (length < 6) {
firstTimeSwitch = true;
}
}
return matrix;
}
}
If you really want to do this, then think of a jTable much like a 2D array, for example, int[][] yourArray = new int[6][10];.
So the first number in your list goes at yourArray[0][0] = 0, and the next two go on the same column yourArray[1][0] = 3 and yourArray[2][0] = 4, and the next number 5 goes into a new column yourArray[0][1] = 5 and so on.
So when it comes to turning you could do something like this inside the loop that places numbers into the jTable:
if(row > rowCount) {
col++;
yourTableModel.setValueAt(number, row, col);
}
But to make sure that nothing overlaps when turning also use:
//Insert value if able
if(yourTableModel.getValueAt(row, col) != null){
row++;
yourTableModel.setValueAt(number, row, col);
}
//Move to next col if not able to fit the number within the row
else{
col++;
yourTableModel.setValueAt(number, row, col);
}
I have a 2D array in which are some indexes null and some of indexes have value.
I want to select a random index that contains null.
example
5,0,0,5,0
4,0,0,4,7
9,0,4,8,9
0,8,4,0,1
i want to choose random index from these which are zero
thx for reply
Or you can try this : put index of '0' as key/value on a map, then :
Random random = new Random();
Map x= new HashMap();
x.put(0,1);
....
List keys = new ArrayList<Integer>(x.keySet());
Integer randomX = keys.get( random.nextInt(keys.size()) );
Integer value = x.get(randomX );
//Init array
int array[][] = { { 5, 0, 0, 5, 0 }, { 4, 0, 0, 4, 7 },
{ 9, 0, 4, 8, 9 }, { 0, 8, 4, 0, 1 } };
//Init vector for indices of elements with 0 value
ArrayList<int[]> indices = new ArrayList<int[]>();
//Find indices of element with 0 value
for (int i = 0; i < array.length; i++)
{
for (int j = 0; j < array[i].length; j++)
{
if (array[i][j] == 0)
{
indices.add(new int[] { i, j });
}
}
}
//Just print the possible candidates
for (int[] index : indices)
{
System.out.println("Index = (" + index[0] + ", " + index[1] + ")");
}
System.out.println();
//Select a random index and print the result
Random rand = new Random();
int ri = rand.nextInt(indices.size());
int[] index = indices.get(ri);
System.out.println("Selected index = (" + index[0] + ", " + index[1] + ")");
The solution is based that it is easy to select a random value in a 1D array. Therefore as the first step all the indices belongs to elements with value 0 are collected in a ArrayList object, then the select of a random element in this ArrayList object results the searched indices.
You could use simple trick - just map your zero values to array.
Or better solution is only count the number of zero values, so, you should iterate through your 2D array and compare values - if you want find zero, then it should be:
int count = 0;
for(int i=0;i< array.length;i++)
for(int j=0;j< array[i].length;j++)
if(array[i][j] == 0)
count++;
After that you can get random number from your interval 1-count and then iterate your 2D array and choose the zero number with random position.
int randomPosition = (int )(Math.random() * (count-1));
int now=0;
if(randomPosition > -1)
for(int i=0;i< array.length;i++)
for(int j=0;j< array[i].length;j++)
if(array[i][j]==0){
now++;
if(now == randomPosition){
rowPosition = i;
columnPosition = j;
}
}
This is not really the correct way how to do it and if you can, you should not use null values - or zeros as null values in your design, better think about another solution to save values in 2D arrays. Do you really need null values or zero values there?And why do you need return random null position?
From your question, I understand you want to select a random element (that contains 0) in a 2-dimensional array in Java. First of all, you should understand that since most numbers are value-based, 0 != null. This will help to make your question clearer.
Now, you will first have to loop through your array to determine which elements are 0, recording the positions where each 0 element is placed. Then, you generate a random number to determine which 0 element should be picked:
//determines amt of 0s in array
ArrayList<ArrayList<int>> keys = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
ArrayList<int> inner = new ArrayList<int>();
for (int j = 0; j < array[i].length; j++) {
if (i == 0) { inner.add(j); }
}
keys.add(inner);
}
Random r = new Random();
//TODO: generate random number, determine which element to pick
Hope this helps.
This solution is maybe a bit long, but effective. I tried to solve this with java streams:
First what you need is to convert 2D array into a simple IntStream. The simplest way could be something like:
Arrays.stream(arr).flatMapToInt(intArr -> Arrays.stream(intArr));
Our stream now looks like this:
{5,0,0,0,5,0,4,0,0,4,7,9...}
Next you need to get stream with values like key-value (index-value in this case). This is quite hard with streams and there is maybe an easier solution, but I created a KeyValue class with auto-incrementation of index:
class KeyValue {
int index;
int value;
static int nextIndex;
public KeyValue(int v) {
this.index = nextIndex;
nextIndex++;
this.value = v;
}
public static void restart() {
nextIndex = 0;
}
}
Now it is easy to convert our stream to index-value items. Call:
.mapToObj(KeyValue::new)
Now our stream looks like this:
{KeyValue[i=0 v=5], KeyValue[i=1 v=0], KeyValue[i=2 v=0], KeyValue[i=3 v=0]...}
Now filter zeros and collect stream to an array:
.filter(kv -> kv.value == 0).toArray(KeyValue[]::new);
Whole code to create an array is:
KeyValue[] zeros = Arrays
.stream(arr)
.flatMapToInt(intArr -> Arrays.stream(intArr))
.mapToObj(KeyValue::new)
.filter(k -> k.value == 0)
.toArray(KeyValue[]::new);
Now it is pretty easy to get a random value from the array:
int ourResult = zeros[random.nextInt(zeros.length)].index;
Whole code will look like this:
int[][] arr = new int[][]
{
{5, 0, 0, 5, 0},
{4, 0, 0, 4, 7},
{9, 0, 4, 8, 9},
{0, 8, 4, 0, 1}
};
Random random = new Random();
KeyValue.restart();
KeyValue[] zeros = Arrays
.stream(arr)
.flatMapToInt(intArr -> Arrays.stream(intArr))
.mapToObj(KeyValue::new)
.filter(k -> k.value == 0)
.toArray(KeyValue[]::new);
int ourResult = zeros[random.nextInt(zeros.length)].index;
Happy coding :)
I was looking for this answer, and come up with this in processing:
// object to hold some info
class Point {
// public fields fine for Point object
public int i, j, count;
// constructor
public Point (int i, int j) {
this.i = i;
this.j = j;
this.count = 0;
}
public String toString() {
return i + " , " + j;
}
}
int[][] grid;
// processing needs to init grid in setup
void setup() {
// init grid
grid = new int[][] {
{5,1,2},
{3,4,4},
{4,0,1}
};
println(getRandomZero(new Point(0,0)));
}
// recursion try for 300 random samples
Point getRandomZero(Point e) {
// base case
Point p = e;
if (grid[p.i][p.j] != 0 && p.i < grid.length && p.j < grid[p.i].length) {
p.i = randomInt(0,grid.length);
p.j = randomInt(0,grid[p.i].length);
p.count++;
// if can't find it in 300 tries return null (probably not any empties)
if (p.count > 300) return null;
p = getRandomZero(p);
}
return p;
}
// use Random obj = new Random() for Java
int randomInt(int low, int high) {
float random = random(1);
return (int) ((high-low)*random)+low;
}
I'll edit for Java specifically tomorrow.
Given an array of integers ranging from 1 to 60, i'm attempting to find how many times the numbers 1-44 appear in the array. Here is my method
public static void mostPopular(int[] list, int count)
{
int[] numbers;
numbers = new int[44];
for (int i = 0; i<count;i++)
{
if (list[i]<45 )
{
numbers[i-1]=numbers[i-1]+1; //error here
}
}
for (int k=0; k<44;k++)
{
System.out.println("Number " + k + " occurs " + numbers[k-1]+ "times");
}
}
I'm trying to iterate through the array, list, that contains over 5000 numbers that are between 1-60, then test if that number is less than 45 making it a number of interest to me, then if the integer is 7 for example it would increment numbers[6] By 1. list is the array of numbers and count is how many total numbers there are in the array. I keep getting an ArrayIndexOutOfBoundsException. How do I go about fixing this?
Replace this line numbers[i-1]=numbers[i-1]+1;
with numbers[list[i] - 1] = numbers[list[i] - 1] + 1;
Now it will update the count of correct element.
You need to increment numbers[list[i]] because that's your value which is smaller than 45. i goes up to 5000 and your array numbers is too small.
You should really start using a debugger. All the modern IDE have support for it (Eclipse, IntelliJ, Netbeans, etc.). With the debugger you would have realized the mistake very quickly.
If your initial value is less than 45, it will add 1 to numbers[i-1]. However, since you start with i=0, it will try to add 1 to the value located at numbers[-1], which doesn't exist by law of arrays. Change i to start at 1 and you should be okay.
Very close, but a few indexing errors, remember 0-1 = -1, which isn't an available index. Also, this isn't c, so you can call list.length to get the size of the list.
Try this (you can ignore the stuff outside of the mostPopular method):
class Tester{
public static void main(String args[]){
int[] list = new int[1000];
Random random = new Random();
for(int i=0; i<list.length; i++){
list[i] = random.nextInt(60) + 1;
}
mostPopular(list);
}
public static void mostPopular(int[] list)
{
int[] numbers = new int[44];
for (int i = 0; i< list.length ;i++)
{
int currentInt = list[i];
if(currentInt<45 )
{
numbers[currentInt - 1] = (numbers[currentInt -1] + 1);
}
}
for (int k=0; k<numbers.length; k++)
{
System.out.println("Number " + (k+1) + " occurs " + numbers[k]+ "times");
}
}
}
When i is 0, i-1 is -1 -- an invalid index. I think that you want the value from list to be index into numbers. Additionally, valid indices run from 0 through 43 for an array of length 44. Try an array of length 45, so you have valid indices 0 through 44.
numbers = new int[45];
and
if (list[i] < 45)
{
// Use the value of `list` as an index into `numbers`.
numbers[list[i]] = numbers[list[i]] + 1;
}
numbers[i-1]=numbers[i-1]+1; //error here
change to
numbers[list[i]-1] += 1;
as list[i]-1 because your number[0] store the frequency of 1 and so on.
we increase the corresponding array element with index equal to the list value minus 1
public static void mostPopular(int[] list, int count)
{
int[] numbers = new int[44];
for (int i = 0; i<count;i++)
{
//in case your list value has value less than 1
if ( (list[i]<45) && (list[i]>0) )
{
//resolve error
numbers[list[i]-1] += 1;
}
}
//k should start from 1 but not 0 because we don't have index of -1
//k < 44 change to k <= 44 because now our index is 0 to 43 with [k-1]
for (int k=1; k <= 44;k++)
{
System.out.println("Number " + k + " occurs " + numbers[k-1]+ "times");
}
}
I'm trying to create a method that takes in 3 int arrays and prints out one element from each array until all the elements of all three arrays have been printed at least once. The first array has 10 elements, the second has 7, and the third has 2. The elements are selected and printed at random. Any help would be appreciated. The idea is to see how many iterations it would take to print out all the elements at least once. I don't know the conditions to set for
a large scale iteration like this. My code so far (with just one array as a parameter):
import java.util.*;
public class calculateAverage{
private static int[] x = new int[]{1,2,3,4,5,6,7,8,9,10};
private static int[] y = new int[]{1,2,3,4,5,6,7};
private static int[] z = new int[]{1,2};
public static void main(String[] args){
calculate(x);
}
public static void calculate(int a[]){
Random random = new Random();
for(int i = 0;i < a.length; i++){
System.out.print(a[random.nextInt(a.length)] + " ");
}
System.out.println();
}
}
code output:
7 2 4 1 8 10 3 10 7 3
Solution for one array:
public static int calculate(int a[]){
Random random = new Random();
HashSet<Integer> remaining = new HashSet<Integer>();
for (int i = 0; i < a.length; i++) {
remaining.add(i);
}
int i = 0;
while (!remaining.isEmpty()) {
int index = random.nextInt(a.length);
System.out.print(a[index] + " ");
remaining.remove(index);
i++;
}
System.out.println();
System.out.println("Finished after " + i + " iterations.");
return i;
}
You could use a collection like Set to keep track of indexes that were already picked. Each time you generate a random number you would first check if it already exist in the Set. If not, print the value in array and add the index number to the set.
Your loop would end when size of that set equals size of the array.
int a[] = {4, 6, 3, 2, 9, 1, 5};
Set<Integer> set = new TreeSet<Integer>();
int counter = 0;
Random rand = new Random();
while(set.size() != a.length){
set.add(a[rand.nextInt(a.length)]);
counter ++;
}
System.out.println("Total Iterations : "+counter);
return counter;
I am currently trying to remove the "noise" from a Vector and Can't find an elegant way to do it. I currently have a Vector of strings, and another vector representing the number of times in a row those strings occur.
For some reason I just can't seem to get it working. The method I created to do this is shown below.
public static void correctDisturbance(Vector<String> names, Vector<Integer> lengths, int lengthGuard){
int guard = lengths.size();
int total = 0;
for(int i = 0; i < guard; i++)
{
if(lengths.elementAt(i) <= lengthGuard)
{
int newTotal = total + lengths.elementAt(i);
while(total < newTotal)
{
System.out.println("Removing: " + names.elementAt(newTotal));
names.removeElementAt(newTotal);
newTotal--;
}
lengths.removeElementAt(i);
guard--;
}
else
{
total += lengths.elementAt(i);
}
}
It removes some of the ones I need but not others. I have the threshold set to 5.
An example of the contents of the lengths vector is this:
[15, 15, 1, 15, 2, 1, 1, 2, 1, 3, 1, 2, 1, 5, 1, 4, 1, 1, 3]
Thanks in advance for any help.
Use a Hash instead of a Vector to keep the count. The key is the line and the value is the count.
And btw use ArrayList instead Vector, if you need you can make it thread safe.
There was very little wrong with your method. Here is the debugged version:
public static void correctDisturbance(List<String> names,
List<Integer> lengths, int lengthGuard) {
int guard = lengths.size();
int total = 0;
for(int i = 0;i < guard;i++) {
if (lengths.get(i) <= lengthGuard) {
int newTotal = total + lengths.get(i);
while( total < newTotal ) {
newTotal--; // LINE MOVED
System.out.println("Removing: " + names.get(newTotal));
names.remove(newTotal);
}
lengths.remove(i);
i--; // LINE ADDED
guard--;
} else {
total += lengths.get(i);
}
}
}
As you can see only two changes were required. First the newTotal had to be decremented before used because Java arrays and lists are zero based. Second when you removed an item from the lengths list, you had to decrement i as well so you would not miss an entry.