Constant stepped values in a new array - java

I would like to create a new array, based on minimum and maximum values in constant intervals. For example, suppose my min = 5 and max = 50 and steps = 5, how can I create a new array that starts at min and goes to max increments of steps?
So that my array can look like this : [5, 10, 15, 20...., 50]
I tried the following but it does not seem to work:
int myArr[] = {};
myArr[0] = min;
for(int i = min, i <= max; i++){
myArr[i] = min + step;
}
Any help or advice will be highly appreciated.

You didn't specify the size of the array. You should do as follows:
public class SOTest {
public static void main(String[] args) {
int min = 5; // use whatever you prefer
int max = 50; // use whatever you prefer
int step = 5; // use whatever you prefer
// now, determine size
// its a simple calculation, that
// determines how many elements would there be from min to
// max if we jump by step
int size = (max + step - min) / step;
int[] myArr = new int[size]; // while creating array you need to specify
// the size of the array, i.e. how many elements the array could hold
int val = min;
for(int i = 0; i <size; i++){
myArr[i] = val;
val = val + step;
}
for(int i=0; i<size; i++) {
System.out.print(myArr[i] + " ");
}
System.out.println();
}
}
And the output is:
5 10 15 20 25 30 35 40 45 50
[P.S.]: If anything is unclear, just ask me in the comment section...

Related

How to get the top 5 numbers from a 2D array of random numbers

I am pretty new to java and am just learning 2D arrays. I am trying to get the top 5 numbers to display from a random list. I think this could work but am not sure why I am getting an error. One other thing is that I cannot use the sort function.
Code here:
public static void main(String[] args) {
//Random Number stuff
Random rand = new Random();
int[] large = new int [5];
int max = 0, index;
int[][] arrSize = new int [4][5];
for (int i = 0; i < arrSize.length; i++) {
for (int j=0; j< arrSize[i].length; j++) {
arrSize[i][j] = rand.nextInt(89) + 10;
System.out.print(arrSize[i][j] + " ");
}
System.out.println();
}
// Top 5
for (int p = 0; p < 5; p++) {
max = arrSize [0][0];
index = 0;
for (int i = 0; i < arrSize.length; i++) {
for (int j = 0; j < arrSize[i].length; j++) {
if (max < arrSize[i][j]) {
max = arrSize[i][j];
index = i;
}
}
}
large[p] = max;
arrSize[index] = Integer.MIN_VALUE; //Error here
System.out.println("Highest Number: " + large[p]);
}
}
}
Error text:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from int to int[]
at secondAssignment.BiggestNumbersRectangular.main(BiggestNumbersRectangular.java:47)
I am not sure why I am getting an error, any help would appreciated. If anyone else has any answers for how I could get the top 5 in a different way that would also be appreciated.
You declare your arrSize here
int[][] arrSize = new int [4][5];
and try to set it's value here
arrSize[index] = Integer.MIN_VALUE;
The Object at arrSize[index] is an array.
Remember that a 2D array basically looks like this:
arrSize
- arrSize[0]
- arrSize[0][0]
- arrSize[0][1]
- arrSize[1]
- arrSize[1][0]
- arrSize[1][1]
- arrSize[2]
- arrSize[2][0]
- arrSize[2][1]
- arrSize[3]
- arrSize[3][0]
- arrSize[3][1]
Because index is a single int, you are assentially calling arrSize[0], which contains arrSize[0][0] and arrSize[0][1].
The Integer.MIN_VALUE is not an array of integers. It is an int. You cannot assign int to int[].
As you can see in other parts of the code, to access values in 2D array arrSize, you need 2 indexes in your case (and usually) i and j.
You need to save both i and j after you find the highest number.
if (max < arrSize[i][j]) {
max = arrSize[i][j];
indexI = i;
indexJ = j;
}
and then
arrSize[indexI][indexJ] = Integer.MIN_VALUE;
As to why you got the error, arrSize[i] gets you a 1D array. It's still an array and you cannot set an array to an integer (Integer.MIN_VALUE). in Java represented as int[] in the error message.
The algorithm could be improved, instead of using a single integer max for saving the highest value, you could use a maxArr of the same size as the number of highest numbers you want (in your case 5) and check against all of the numbers in maxArr using a for in place of
if (max < arrSize[i][j]) {
max = arrSize[i][j];
index = i;
}
That would mean you could remove the index (or indexI and indexJ) and topmost for cycle (for (int p = 0; p < 5; p++)). But that's another topic, and one you should learn yourself.

Multiplication array using methods

I'm new to coding and have been set a challenge of creating an method that prints out a multiplication array.
My code is as follows...
public class TimesTableArray
{
public static void main(String[] args)
{
int size = 12;
int number = 3;
}
private static int [] getTimesTable(int size, int number)
{
int[] timesTable = new int[size];
for (int i = 0; i < size; i++)
{
timesTable[i] = number * (i +1);
}
return timesTable;
}
}
I get the following output...
3
6
9
12
15
18
21
24
27
30
33
0
I need the 12th item to read 36, not 0. I know it's to do with the index reads from 0 to 11, but I don't know how to amend my code to make this so.
Please could someone guide me on how to do this?
You have a classic "off by one" error.
If you start at 1, then you INCLUDE the size, and have to subtract one to get the Index:
for (int i = 1; i <= size; i++)
{
timesTable[i - 1] = number * i;
}
If you start at 0, then you EXCLUDE the size, and have to add one when you multiply:
for (int i = 0; i < size; i++)
{
timesTable[i] = number * (i + 1);
}
You're going to have people swear up and down that one is correct and the other is wrong. This is down to preference. Do what "makes sense" to you.
In the population loop, you are iterating from 1 rather than 0 but you do not offset the terminal condition. I would rewrite you loop to follow the standard pattern rather than trying to bake in the offset. So...
for (int index = 0 ; index < size ; ++index) { ... }
This will allow the index to line up naturally in the assignment. Apply the offset in the calcuation.
timesTable[index] = number * (index + 1);
So you get...
private static int[] getTimesTable(int size, int number) {
int[] timesTable = new int[size];
for (int i = 0; i < size; i++) {
timesTable[i] = number * (i+1);
}
return timesTable;
}
You are having an off-by-one error. Since you want to have an array of 12 answers, starting with 1, your loop range has to be from 1 to 12 inclusive. Therefore:
private static int [] getTimesTable(int size, int number)
{
int[] timesTable = new int[size];
for (int i = 1; i <= (size); i++)
{
timesTable[i-1] = number * i;
}
return timesTable;
}
The reason why your last index was zero, is because numeric array indexes are initialized to zero after instantiation (new int[size]).

Find the most frequent value in an array of double in Java (without hashmaps or sorting)

Write a full Java program that does the following:
Creates an array of 100 double.
Reads in an unknown number of doubles from a file named values.txt .
There will be at least 2 distinct values, and no more than 100 distinct values in the file. The values will be in unsorted order. Values will be no smaller than 0, and no larger than 99.
Outputs the most frequently occurring value in the file.
Outputs the least frequently occurring value in the file. The value must occur at least once in order to be output.
Outputs the average of all array values.
You must create and use separate methods for each of the items #2-5.
This is what I have so far. I cannot for the life of me figure out how to get this right:
import java.util.*;
import java.io.*;
public class arrayProgram2 {
static Scanner console = new Scanner(System.in);
static final int ARRAY_SIZE = 100;
static int numOfElements = 0;
public static void main(String[] args) throws FileNotFoundException {
Scanner inFile = new Scanner(new FileReader("values.txt"));
double[] Arr1 = new double[ARRAY_SIZE];
while (inFile.hasNext()) {
Arr1[numOfElements] = inFile.nextDouble();
numOfElements++;
}
System.out.println("There are " + numOfElements + " values.");
System.out.printf("The average of the values is %.2f%n", avgArray(Arr1));
System.out.println("The sum is " + sumArray(Arr1));
inFile.close();
} //end main
//Method to calculate the sum
public static double sumArray(double[] list) {
double sum = 0;
for (int index = 0; index < numOfElements; index++) {
sum = sum + list[index];
}
return sum;
}
//Method to calculate the average
public static double avgArray(double[] list) {
double sum = 0;
double average = 0;
for (int index = 0; index < numOfElements; index++) {
sum = sum + list[index];
}
average = sum / numOfElements;
return average;
}
} //end program
Notice I am required to make an array of double even though it is not necessary.
If all values are int than you should use int array instead of double. As all values in range 0-99. So, you can increase input value frequency. Look at below logic:
int[] freqArr= new int[100];
while (inFile.hasNext()){
int value = inFile.nextInt();
freqArr[value]++; // count the frequency of selected value.
}
Now calculate the maximum frequency from freqArr
int maxFreq=0;
for(int freq : freqArr){
if(maxFreq < freq){
maxFreq = freq;
}
}
Note: If double array is mandatory than you can also use double array like:
double[] freqArr= new double[100];
while (inFile.hasNext()){
freqArr[(int)inFile.nextDouble()]++;
}
It's possible to find a most-occurring value without sorting like this:
static int countOccurrences(double[] list, double targetValue) {
int count = 0;
for (int i = 0; i < list.length; i++) {
if (list[i] == targetValue)
count++;
}
}
static double getMostFrequentValue(double[] list) {
int mostFrequentCount = 0;
double mostFrequentValue = 0;
for (int i = 0; i < list.length; i++) {
double value = list[i];
int count = countOccurrences(list, value);
if (count > mostFrequentCount) {
mostFrequentCount = count;
mostFrequentValue = value;
}
}
return mostFrequentValue;
}
Pham Thung is right : -
You read in integer inFile.nextInt(), why do you need to use double array to store them? – Pham Thung
You can achieve your first functionality in n time if its integer array.
you question says,
Values will be no smaller than 0, and no larger than 99.
So,
1. Make an array of size 100.(Counter[])
2. Iterate through values of your current array and add count to Counter array.
eg:
if double array contains
2 3 2 5 0 0 0
Our counter array will be like
location : 0 1 2 3 4 5 6 ...........100
values : 3 0 1 1 0 1 0 ..............
and so on.
You can use below algorithm for this
Sort the array (you only need to read unsorted array, but you can sort the array once read from the file)
Make double var : num, mostCommon, count = 0, currentCount = 1
Assign Arr1[0] to num
for i from 1 to length of Arr1
i. if(Arr1[i] == num)
a. Increment currentCount
ii. else
a. if(count > currentCount)
A. Assign currentCount to count
B. Assign num to mostCommon
C. Assign Arr1[i] to num
D. Assign 1 to currentCount
At the end of this loop, you will have most common number in mostCommon var and it's number of occurrence in count.
Note : I don't know how to format the algo

How to generate 6 different random numbers in java

I want to generate 6 different random numbers by using Math.random and store them into an array.
How can I make sure that they are different? I know I need to use for-loop to check the array but how...
This is the range. I only need numbers between 1 and 49.
( 1 + (int) (Math.random() * 49) )
In Java 8:
final int[] ints = new Random().ints(1, 50).distinct().limit(6).toArray();
In Java 7:
public static void main(final String[] args) throws Exception {
final Random random = new Random();
final Set<Integer> intSet = new HashSet<>();
while (intSet.size() < 6) {
intSet.add(random.nextInt(49) + 1);
}
final int[] ints = new int[intSet.size()];
final Iterator<Integer> iter = intSet.iterator();
for (int i = 0; iter.hasNext(); ++i) {
ints[i] = iter.next();
}
System.out.println(Arrays.toString(ints));
}
Just a little messier. Not helped by the fact that it's pretty tedious to unbox the Set<Integer> into an int[].
It should be noted that this solution should be fine of the number of required values is significantly smaller than the range. As 1..49 is quite a lot larger than 6 you're fine. Otherwise performance rapidly degrades.
Create a list containing the numbers 1 to 49.
Create a random number x between 0 and the size of the list, take the number being at index x in the list, and remove it from the list.
Repeat the previous step 5 times. And you're done. Note that java.util.Random has a nextInt(int max) method that you should use instead of Math.random().
Note regarding performance: this solution has an advantage compared to the "try until you get 6 different numbers" various solutions: it runs in a O(n) time. It doesn't matter much for 6 unique numbers out of 50, but if you want to get 48 or 49 unique random numbers out of 50, you'll start seeing a difference, because you might have to generate many random numbers before getting one that isn't already in the set.
EDIT:
to reduce the cost induced by the removal of the elements in the list, you could instead simply replace the element at index x with the last element of the list (and at the second iteration, with the element at size - 2, etc.)
You can use a Set.
Set<Integer> s = new HashSet<>();
while(s.size() != 6){
s.add(1 + (int) (Math.random() * 49));
}
Integer[] arr = s.toArray(new Integer[s.size()]);
This is enough to do this in your case because the number of distinct random numbers is relatively small compared to the size of the range you generate them.
Otherwise I would go with #JBNizet approach.
Generate any 6 numbers (not necessarily different). Order them.
a1 <= a2 <= a3 <= a4 <= a5 <= a6
Now take these 6 numbers
a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5
These 6 are different and random.
The idea of this construct comes from some combinatorial proofs.
Its advantage is that it's simple, fast, and deterministic.
I think the time complexity is O(count*log(count)).
I wonder if it can be improved.
import java.util.TreeMap;
public class Test005 {
public static void main(String[] args) {
int count = 6;
int min = 1;
int max = 49;
// random number mapped to the count of its occurrences
TreeMap<Integer, Integer> mp = new TreeMap<Integer, Integer>();
for (int i=0; i<count; i++){
int d = ( min + (int) (Math.random() * (max-count+1)) );
if (!mp.containsKey(d)){
mp.put(d, 0);
}
mp.put(d, mp.get(d) + 1);
}
// now ensure the output numbers are different
int j = 0;
for (int num : mp.keySet()){
int cnt = mp.get(num);
for (int i=0; i<cnt; i++){
System.out.println(num + j);
j++;
}
}
}
}
I've just came up with a small idea for Java 8-.
Set<Integer> set = new LinkedHashSet<>();
while(set.size() != 6)
set.add(rnd.nextInt(49) + 1);
Instead of checking that the array has no duplicates, you can use a bit more smartness while generating the numbers, such that uniqueness is enforced at the outset.
Create a boolean[] as long as your range (49 entries);
generate a random number from the full range;
put that number into your output array;
"cross out" the corresponding index in the boolean[];
now generate another random number, but curtail the range by one (now 48);
instead of directly using that number as output, scan your boolean[], counting all the non-crossed entries. Stop when you reach the count equal to the random number generated in step 5. The number corresponding to that entry is your output number;
go to step 4.
in your case n=6
public static int[] chooseAny(int n){
int[] lottery = new int[n];
int[] chooseFrom = new int[49];
for(int i=1 ; i <= 49 ; i++)
chooseFrom[i-1] = i;
Random rand = new Random();
int N = 49;
int index;
for(int i=0 ; i < n ; i++){
//pick random index
index = rand.nextInt(N);
lottery[i] = chooseFrom[index];
chooseFrom[index] = chooseFrom[N-1];
N--;
}
return lottery;
}
Just keep generating numbers and adding them to the array as long as they are unique; psuedocode:
num = genNextRand()
For (array length)
If (num not in array)
addToArray()
Repeat while length not equal 6
Create a variable last; initialize it to 0.
Next, in a loop x from 0 to 5, create a random number between last+1 and 49-6+x. Store this number in a list, and set last to the number generated this way.
You will end up with an ordered list of 6 random numbers in the range of 1..49 with no repeats.
That code generate numbers from 6 to 0 and save in ArrayList.
If generated number was duplicated the program generate numbers again.
If generated number is different that number is added.
Code:
private ArrayList<Integer> arraylist = new ArrayList<Integer>();
private Random rand = new Random();
public void insertNumber() {
while (true) {
int i = generateNumber();
if(!isGenerateNumberExists(i)){
addNumber(i);
break;
}
}
}
//Generate numbers
private int generateNumber() {
return rand.nextInt(6);
}
//Confirm if that number exists
private boolean isGenerateNumberExists(int y) {
for (int num : arraylist) {
if (num == y) {
return true;
}
}
return false;
}
//Add number to arrayList
private void addNumber(int x) {
arraylist.add(x);
}

Generating Random Permutation Uniformly in Java

Anyone know of a fast/the fastest way to generate a random permutation of a list of integers in Java. For example if I want a random permutation of length five an answer would be 1 5 4 2 3, where each of the 5! possibilities is equally likely.
My thoughts on how to tackle this are to run a method which generates random real numbers in an array of desired length and then sorts them returning the index i.e. 0.712 0.314 0.42 0.69 0.1 would return a permutation of 5 2 3 4 1. I think this is possible to run in O(n^2) and at the moment my code is running in approximately O(n^3) and is a large proportion of the running time of my program at the moment. Theoretically this seems OK but I'm not sure about it in practice.
Have you tried the following?
Collections.shuffle(list)
This iterates through each element, swapping that element with a random remaining element. This has a O(n) time complexity.
If the purpose is just to generate a random permutation, I don't really understand the need for sorting. The following code runs in linear time as far as I can tell
public static int[] getRandomPermutation (int length){
// initialize array and fill it with {0,1,2...}
int[] array = new int[length];
for(int i = 0; i < array.length; i++)
array[i] = i;
for(int i = 0; i < length; i++){
// randomly chosen position in array whose element
// will be swapped with the element in position i
// note that when i = 0, any position can chosen (0 thru length-1)
// when i = 1, only positions 1 through length -1
// NOTE: r is an instance of java.util.Random
int ran = i + r.nextInt (length-i);
// perform swap
int temp = array[i];
array[i] = array[ran];
array[ran] = temp;
}
return array;
}
And here is some code to test it:
public static void testGetRandomPermutation () {
int length =4; // length of arrays to construct
// This code tests the DISTRIBUTIONAL PROPERTIES
ArrayList<Integer> counts = new ArrayList <Integer> (); // filled with Integer
ArrayList<int[]> arrays = new ArrayList <int[]> (); // filled with int[]
int T = 1000000; // number of trials
for (int t = 0; t < T; t++) {
int[] perm = getRandomPermutation(length);
// System.out.println (getString (perm));
boolean matchFound = false;
for(int j = 0; j < arrays.size(); j++) {
if(equals(perm,arrays.get(j))) {
//System.out.println ("match found!");
matchFound = true;
// increment value of count in corresponding position of count list
counts.set(j, Integer.valueOf(counts.get(j).intValue()+1));
break;
}
}
if (!matchFound) {
arrays.add(perm);
counts.add(Integer.valueOf(1));
}
}
for(int i = 0; i < arrays.size(); i++){
System.out.println (getString (arrays.get (i)));
System.out.println ("frequency: " + counts.get (i).intValue ());
}
// Now let's test the speed
T = 500000; // trials per array length n
// n will the the length of the arrays
double[] times = new double[97];
for(int n = 3; n < 100; n++){
long beginTime = System.currentTimeMillis();
for(int t = 0; t < T; t++){
int[] perm = getRandomPermutation(n);
}
long endTime = System.currentTimeMillis();
times[n-3] = (double)(endTime-beginTime);
System.out.println("time to make "+T+" random permutations of length "+n+" : "+ (endTime-beginTime));
}
// Plotter.plot(new double[][]{times});
}
There is an O(n) Shuffle method that is easy to implement.
Just generate random number between 0 and n! - 1 and use
the algorithm I provided elsewhere (to generate permutation by its rank).

Categories