I have an array including doubles:
double[] myArray = {1.23455, 1.23456, 2.45673, 6.45678, 8.12938}
The numbers in the array and the number of elements in array will vary. How can I create a histogram out of this array? I'm trying to create ranges by doing something like this:
double sizeOfRange = (max-min)/(numberOfRanges-1);
Where max and min are max and min values in myArray, but other than that I am completely lost regarding how to do this. I'm very new to java, hope the question is asked correctly.
I'm not sure this is what you want, but it certainly can help you if you are starter:
Double[] myArray = {1.23455, 1.23456, 2.45673, 6.45678, 8.56938, 3.65645, 5.65478, 2.54773, 9.63345};
int nRanges = 3;
int[] buckets = new int[nRanges];
double max = Collections.max(Arrays.asList(myArray));
double min = Collections.min(Arrays.asList(myArray));
double sizeOfRange = (max-min)/(nRanges - 1);
for (double elem : myArray){
for (int i = 0; i < nRanges; i++){
if ((elem >= sizeOfRange * i) && (elem < sizeOfRange * (i + 1)))
buckets[i]++;
}
}
for (int i = 0; i < nRanges; i++){
System.out.println(sizeOfRange * i + " - " + sizeOfRange * (i + 1) + ": " + buckets[i]);
}
Collections class provides a lot of useful method, just like max and min. Then the core of this code is from line 8 to 13: inside that for I am incrementing the frequency of the range in which the correspondent double value can be placed.
Related
I'm writing a code to find the mean, median and mode of an array of randomly generated ints (user inputs a size for the array and a range between which random numbers are to be generated it generate numbers between 3-22 randomly. I have not had too much trouble writing code for a mean or median but I cannot seem to be able to write code to calculate the mode (most commonly occurring number). Can anyone help or show/put code for how to calculate the mode of a randomly generated array of ints without having to create a method for yourself in the code? Thanks. Here is what I have so far (code that finds the mean and median):
public class ArraysIntsMeanMedianAndMode {
public static void main(String[] args) {
int ArraySize;
int min;
int max;
double x;
// To get the Size and range of numbers for the randomly genereated ints in the array.
Scanner sc = new Scanner(System.in);
System.out.println("What size should the array be?");
ArraySize = sc.nextInt();
System.out.println("Please enter a minimum value for the range of ints.");
min = sc.nextInt();
System.out.println("Please enter a maximum value for the range of ints.");
max = sc.nextInt();
//Making the array and filling it based on the user inputs
int[] MMMarray = new int[ArraySize];
int total = 0;
for (int i = 0; i < ArraySize; i++) {
x = (int) (Math.random() * ((max - min) + 1)) + min;
System.out.println(x);
int RandoNums = (int) x;
total = total + RandoNums;
MMMarray[i] = RandoNums;
}
//Finding mean/average
double Mean = (total + 0.0) / ArraySize;
System.out.println("The mean is: " + Mean);
//Finding Median/Middle number
Arrays.sort(MMMarray);
System.out.println(Arrays.toString(MMMarray));
if (ArraySize % 2 == 0) {
System.out.println("The median is: " + ((MMMarray[(ArraySize / 2)] + 0.0) + MMMarray[(ArraySize / 2) - 1]) / 2 + ".");
} else System.out.println("The median is: " + MMMarray[ArraySize / 2] + ".");
//How to find mode????????
Finding mode of unsorted array of int:
int freq = 0;
int value = 0;
int length = MMMArray.length;
for (int outer = 0; outer < length; outer++)
{
int tempFreq = 0;
for (int inner = 0; inner < length; inner++)
{
if (MMMArray[outer] == MMMArray[inner])
{
tempFreq++;
}
}
if (tempFreq > freq)
{
freq = tempFreq;
value = MMMArray[outer];
}
}
System.out.println("Mode is " + value + ", which appears " + freq + " times.");
Because you have already sorted the array to calculate the median, the problem of finding the mode(s) becomes equivalent to finding the longest consecutive streak of the same number. So, for example, if you have [1, 1, 2, 2, 2, 3, 5, 5, 21], there are three consecutive 2's, which is longer than any other run, so 2 is the mode.
To find the longest run, you can pass over the data once more, not reading any element twice. I'm adapting the code of Litvin and Litvin ever so slightly to use your array name, to count a run of 1 as a run, and to report what number the mode is rather than where it is in the array. You can drop this code in right where you ask your question, after the median has been calculated.
// at this point MMMArray is a sorted, nonempty array of int, because it was already sorted to find the median
int maxRunStart = 0, maxRunLength = 1;
int runStart = 0, runLength = 1;
for (int i = 1; i <= MMMArray.length; i++) //what they do here by using <=
//rather than < is worth reflecting upon
//it handles the case of the biggest run being at the end within the loop body
{
if (i < MMMArray.length && MMMArray[i] == MMMArray[i - 1])//notice how the boolean short-circuit prevents reading beyond the end of the array
{
runLength++;
}
else
{
if (runLength > maxRunLength)
{
maxRunStart = runStart;
maxRunLength = runLength;
}
runStart = i;
runLength = 1;
}
}
System.out.println("The mode is: " + MMMArray[maxRunStart] + ".");
}
Now here is something new to ponder. Suppose MMMArray contains [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3]. This code (or that of MarsAtomic) will report 1 is the only mode. But the data is bimodal, and 3 is the mode as much as 1 is. One way to adapt the code would be to store the mode(s) in an array list (or an array, because we know up front there cannot be more modes than numbers). I think it is simpler (not more efficient, just easier not to mess up and without introducing another non-simple type) to make one more pass over the data. If you want that, then after the first for loop, instead of the println of the one mode, insert the following:
runLength = 1;
runStart = 0;
for (int i = 1; i <= MMMArray.length; i++)
{
if (i < MMMArray.length && MMMArray[i] == MMMArray[i - 1])
{
runLength++;
}
else
{
if (runLength == maxRunLength)
{
System.out.println("The mode is: " + MMMArray[runStart] + ".");
}
runStart = i;
runLength = 1;
}
}
I'm working on making a program to roll 4 6 sided dice and do some simple math and logic with them. I was running a very rough draft of the program and started to notice that the number of rolls would be inconsistent. In particular I would sometimes wont get the smallest value or get two
If looked around for a solution online to no avail. I even copied the code from other examples on how to find the smallest value
public class test {
private static int dice(int s) {
int num = 0;
Random random = new Random();
num = random.nextInt(s);
num = num + 1;
return num;
}
public static void main(String[] args) {
List<Integer> rolls = new ArrayList<Integer>();
for (int i = 0; i != 4; i++) {
rolls.add(dice(6));
}
for (Integer roll : rolls) {
System.out.println(roll);
}
int min = rolls.get(0);
int index = 0;
for (int x = 0; x < rolls.size(); x++) {
if (rolls.get(x) < min) {
min = rolls.get(x);
index = x;
System.out.println("Smallest: " + min);
}
}
int sum = 0;
for (int x : rolls) {
sum += x;
}
System.out.println("Sum:" + sum);
}
}
This should generate 4 rolls of 6 sided dice. Then it should find the smallest value print that, then calculate the sum and print it
Check out this bit of code:
int min = rolls.get(0);
int index = 0;
for(int x = 0; x<rolls.size(); x++){
if(rolls.get(x) < min){
min=rolls.get(x);
index = x;
System.out.println("Smallest: " + min);
}
}
What happens if rolls.get(0); is your minimum roll? In that case, if(rolls.get(x) < min) will always be false, and you'll never print "Smallest...".
Also note that every time you find a roll that is smaller than the last one you looked at, you print out "Smallest..." again, so if you have multiple dice in descending size, you'll print that line out multiple times.
Set your initial min value to 7, so you're guaranteed to have a min value that is smaller than the initial state. And then, instead of printing inside your loop, save the min and print "Smallest..." once the loop is finished:
// Be aware that this code doesn't work correctly if your List is empty.
int min = 7; // You could also set this to rolls.get(0) and start your loop at 1
for (int x = 0; x < rolls.size(); x++) {
if (rolls.get(x) < min) {
min = rolls.get(x);
}
}
System.out.println("Smallest: " + min);
(I also removed index, because it's not being used anywhere in your code).
If you wanted to be a bit more modern with this (and also more robust), you could also do:
rolls.stream()
.min(Integer::compareTo)
.ifPresent(min -> System.out.println("Smallest: " + min));
That will handle the case of rolls being empty by just not printing anything.
Written this code, would like to get better approach using any algorithm to find missing numbers from an sorted or unsorted array. If its an unsorted array, i would sort and execute the following.
private static void identifyMissingValues(Integer[] ar) {
for(int i = 0; i < (ar.length - 1); i++) {
int next = ar[i + 1];
int current = ar[i];
if((next - current) > 1) {
System.out.println("Missing Value : " + (current + 1));
}
}
}
Any code faster or better than this, please suggest.
Any code faster or better than this, please suggest.
No there is no such thing - you cannot improve on an O(n) algorithm if every element must be visited.
Use BitSet instead of sorting.
int[] ar = {7, 2, 6, 8, 10, 4, 3, 2};
int min = IntStream.of(ar).min().getAsInt();
BitSet b = new BitSet();
for (int i : ar)
b.set(i - min);
int i = 0;
while ((i = b.nextClearBit(i + 1)) < b.length())
System.out.println(i + min);
result
5
9
Sorting the array would take O(n*log(n)).
You can do better if you add all the elements of the array to a HashSet (O(n)) running time, and then check for each number between 0 and ar.length - 1 (or whatever the relevant range is) whether the HashSet contains that number. This would take O(n) time.
Your approach is good, but I added something more for more than one numbers are missing..
eg : ar={1,2,4,6,10} // Sorted Array
private static void identifyMissingValues(Integer[] ar) {
for (int i = 0; i < (ar.length - 1); i++) {
int next = ar[i + 1];
int current = ar[i];
if ((next - current) > 1) {
for (int ind = 1; ind < next - current; ind++)
System.out.println("Missing Value : " + (current + ind));
}
}
}
Output is,
Missing Value : 3
Missing Value : 5
Missing Value : 7
Missing Value : 8
Missing Value : 9
Can I know the Input and Expected output number series ?
According to your code i feel the series should be a difference of 1,If i'm not wrong.
So you have an array of n elements which starts with an integer i and contains all integers from i to i+n is that right? Eg:
arr = [1,2,3,4,5]
So, the sum of all numbers in the array should be the sum of numbers from i to i+n.
Eg: sum(arr) = 1+2+3+4+5 = 15
The formula for the sum of numbers 1 to n is n(n+1)/2
So you can have a for loop as:
int counter = 0;
for(Integer i : integers)
counter += i
To get the sum of numbers in your array.
If your array starts at one, you check whether the counter variable equals n(n+1)/2, where n is the length of your array.
If your array doesn't start at one, for example arr = [78, 79, 80, 81] then you need to tweak this approach a little, but I'm sure you can figure it.
You can do:
Set<Integer> mySet = new TreeSet<Integer>(Arrays.asList(ar));
int min = mySet.first();
for (int i = 0; i < mySet.size(); i++) {
int number = min + i;
if (!mySet.contains(number)) {
System.out.println ("Missing: " + number);
i--;
}
}
Integer [] list = new Integer[]{1, 12, 85, 6, 10};
Integer previous = null;
Arrays.sort(list);
System.out.println(list);
for(int index = 0; index < list.length; index++){
if(previous == null){
previous = (Integer) list[index];
continue;
}
Integer next = previous + 1;
if(((Integer) list[index] - previous) > 1){
System.out.println("Missing value " + next);
index--;
}
previous = next;
}
Im using an array that lets the user choose a certain amount of of variables, and each one of these variables will become a random number. However, how can I take the biggest of those random numbers and store it in a variable? Im fairly new at Java, so a simple, understandable way to do this would be perfect. Thanks in advance!
int [] arr;
Scanner reader= new Scanner(System.in);
n = reader.nextInt();
array = new int [n];
for (n = 0; n < array.length; n++ )
{
x = (int)(Math.random() * 10) + 1;
System.out.println(x);
System.out.println("Biggest Value is: " + );
}
You may use an integer variable to keep track of the highest number. While iterating if you come across a number greater than highest variable, make that number as highest and continue iterating till the end of the loop.
int highest = Integer.MIN_VALUE;
for (n = 0; n < array.length; n++ ){
x = (int)(Math.random() * 10) + 1;
if(x > highest){
highest = x;
}
}
System.out.println("Highest number is " + highest);
I am trying to solve a classic Knapsack problem with huge capacity of 30.000.000 and it works well up until 20.000.000 but then it runs out of memory:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
I have tried to divide all values and capacity by 1.000.000 but that generates floats and I don't think that is the correct approach. I have also tried to make the arrays and matrix of type long but that does not help.
Perhaps another data-structure?
Any pointers welcome...
Code:
public class Knapsack {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]); // number of items
int W = Integer.parseInt(args[1]); // maximum weight of knapsack
int[] profit = new int[N+1];
int[] weight = new int[N+1];
// generate random instance, items 1..N
for (int n = 1; n <= N; n++) {
profit[n] = (int) (Math.random() * 1000000);
weight[n] = (int) (Math.random() * W);
}
// opt[n][w] = max profit of packing items 1..n with weight limit w
// sol[n][w] = does opt solution to pack items 1..n with weight limit w include item n?
int[][] opt = new int[N+1][W+1];
boolean[][] sol = new boolean[N+1][W+1];
for (int n = 1; n <= N; n++) {
for (int w = 1; w <= W; w++) {
// don't take item n
int option1 = opt[n-1][w];
// take item n
int option2 = Integer.MIN_VALUE;
if (weight[n] <= w) option2 = profit[n] + opt[n-1][w-weight[n]];
// select better of two options
opt[n][w] = Math.max(option1, option2);
sol[n][w] = (option2 > option1);
}
}
// determine which items to take
boolean[] take = new boolean[N+1];
for (int n = N, w = W; n > 0; n--) {
if (sol[n][w]) { take[n] = true; w = w - weight[n]; }
else { take[n] = false; }
}
// print results
System.out.println("item" + "\t" + "profit" + "\t" + "weight" + "\t" + "take");
for (int n = 1; n <= N; n++) {
System.out.println(n + "\t" + profit[n] + "\t" + weight[n] + "\t" + take[n]);
}
//Copyright © 2000–2011, Robert Sedgewick and Kevin Wayne. Last updated: Wed Feb 9 //09:20:16 EST 2011.
}
Here are a couple of tricks I've used for things like that that.
First, a variant of a sparse matrix. It's not really sparse, but instead of assuming that "non-stored entries" are zero, you assume they're the same as the entry before. This can work in either direction (in the direction of the capacity or in the direction of the items), afaik not (easily) in both directions at the same time. Good trick, but doesn't defeat instances that are huge in both directions.
Secondly, a combination of Dynamic Programming and Branch & Bound. First, use DP with only the "last two rows". That gives you the value of the optimal solution. Then use Branch & Bound to find the subset of items that corresponds to the optimal solution. Sort by value/weight, apply the relaxation value[next_item] * (capacity_left / weight[next_item]) to bound with. Knowing the optimal value ahead of time makes pruning very effective.
The "last two rows" refers to the "previous row" (a slice of the tableau that has the solutions for all items up to i) and the "current row" (that you're filling right now). it could look something like this, for example: (this is C# btw, but should be easy to port)
int[] row0 = new int[capacity + 1], row1 = new int[capacity + 1];
for (int i = 0; i < weights.Length; i++)
{
for (int j = 0; j < row1.Length; j++)
{
int value_without_this_item = row1[j];
if (j >= weights[i])
row0[j] = Math.Max(value_without_this_item,
row1[j - weights[i]] + values[i]);
else
row0[j] = value_without_this_item;
}
// swap rows
int[] t = row1;
row1 = row0;
row0 = t;
}
int optimal_value = row1[capacity];
Use a recursive method to solve the problem. see http://penguin.ewu.edu/~trolfe/Knapsack01/Knapsack01.html for further information.
Hope it will be of help.
Break your for loops down into method calls.
This will have the effect of making the local variables GC'able once the method itself has completed.
So instead of nested for loops within the same main method call a method with the same functionality, which then calls a second method and you are effectively breaking the code up into small packets of local variables which can be collected when out of scope.