How to get the top M values from a Map? - java

So I am writing this program, which calculates different things about the Collatz-conjucture.
So basically for a number I calculate a cycle and its length, like this:
For 8: [8, 4, 2, 1]
Length: 4
Now I want to calculate until 1000.
And for every number the length of the cycle is different.
So for example the length of the cycle for number 43 can be bigger than that for 45.
And I want to get the biggest lengths in ascending order.
Like this:
Number 1 2 3 6 7 9 1825 27 54 73 97 129 171 231 313 327 649 703 871
Length(N) 0 1 7 8 16 19 20 23 111 112 115 118 121 124 127 130 143 144 170 178
I put the numbers in HashMap with the numbers as keys and the lengths as values.
Now I have no clue how to get the biggest lengths in ascending order.
Is there a function that helps me with that?
Do I have to use a loop and more lists?
The Collections.Max is of no help, because it gets only one value, but I need more than one.

You should use any sorting algorithm, (like merge) and then pick the amount you'd like to get from the sorted map.

This amounts to essentially sorting a list composed of the map's values.
Returns the top m values of your Map, ascending:
public static List<Integer> topMValuesAscending(Map<?, Integer> map, int m){
final List<Integer> values = new ArrayList<Integer>(map.values());
Collections.sort(values);
final int valuesCount = values.size();
return values.subList(valuesCount - m, valuesCount);
}
I believe this is optimal, and is O[s*Log(s)] log-linear, where s is the size of the map.

Related

How to get an element from a 2D array without looping the entire array?

I have a simple class:
public class XYPoint {
public int x, y;
}
And a 2D array that contains arrays of Point objects:
(-2, 2)(-1, 2)(0, 2)(1, 2)(2, 2)
(-2, 1)(-1, 1)(0, 1)(1, 1)(2, 1)
(-2, 0)(-1, 0)(0, 0)(1, 0)(2, 0)
(-2, -1)(-1, -1)(0, -1)(1, -1)(2, -1)
(-2, -2)(-1, -2)(0, -2)(1, -2)(2, -2)
The correspond ids are:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
Let's say I want to get the element at id 0, then it will return -2, 2. If I want to get from 6, it will return -1, 1 and so on.
Is there any way I can get an element without looping the entire array?
you essentially imagine a 1d array, structured in a 2d manner. with that in mind you can map the 1d coordinate (in your case 7 for instance) onto 2d like this:
[1d/width][1d mod width]
1d being your "id" and width being the 2d array length
1d/width results in the corresponding "row" of your id, and 1d mod width in the corresponding "column"

Array Shuffle (With same Start and end Value)

I'm currently working on a Travelling salesman problem and i'm having trouble generating random paths with the same start and end value
This is my current path(path of cities visited)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 38 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 14 39 40 41 42 43 44 45 46 47 48 49 50 51 0
See how the last node arrives back at 0(TSP logic)
Now i'm trying to shuffle this array randomly because random start points generate better results then others However I know how to shuffle the array using Collections but that would shuffle every value randomly
Basically i'm trying to create a method to shuffle an array randomly WITH THE EXCEPTION THE START and END VALUES must be the same and every number must be distinct 0-51
This is my current code, it basically shuffles the array and sets the last index to the first index
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
ar[ar.length-1]=ar[0];
}
however this is giving me duplicate values for some reason
Could you not remove the start and end position, shuffle the array, and then add the start and end position again?

Java: Sorting an array from least to greatest

This is my first question on the site. I am in a CS class and part of one of my assignments involved sorting the scores column of an array from least to greatest and printing out the array in its new least-to-greatest form. I cannot seem to get the scores from the array to do so, for whatever reason, and I am very confused as to why it will not work. If any of you could help me, that would be awesome. Thanks! Here is the array I am working with. The two columns are the id (on the left) and the score (on the right):
365 265
222 223
306 262
003 559
004 560
203 224
113 243
208 242
213 229
115 257
302 242
223 230
001 599
311 256
323 245
321 245
123 253
104 239
002 513
112 239
207 228
325 246
116 246
218 243
110 238
And here is my code so far:
import java.io.*;
import java.util.*;
public class RankingTestScoresDriver
{
public static void main(String args[])
{
System.out.println("ID Score");
File file = new File("prog408a.dat");
int[] id = new int[24];
int[] score = new int[24];
try
{
Scanner kbReader = new Scanner(file);
while (kbReader.hasNextInt())
{
for (int i = 0; i < 25; i++)
{
id[i] = kbReader.nextInt();
score[i] = kbReader.nextInt();
}
}
}
catch (Exception e)
{
}
//From here down is the part which is giving me trouble.
int max;
max = score[0];
int index;
int maxScoreIndex = 0;
for (int k = 0; k < 25; k++)
{
for (index = 0; index < score.length; index++)
{
if (score[index] > max)
{
max = score[index];
maxScoreIndex = index;
}
}
System.out.println(maxScoreIndex + " " + max);
score[maxScoreIndex] = ((-1)*(max));
}
}
}
Currently it is producing this as the output:
ID Score
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
The final output should be the scores of the array but in least-to-greatest order.
Any help would be greatly appreciated in helping me fix the bit of code I am struggling on.
You can write a class that implements Comparable to do it simple.
class Score implements Comparable<Score> {
private int id, score;
Score(int id, int score) {
this.id = id;
this.score = score;
}
#override
public int compareTo(Score o) {
return score - o.score;
}
}
then after you create an array of Score, you can use sort() method.
Score[] scores = /* put data */
Arrays.sort(scores);
will work
In the section where you are trying to sort, I'd recommend calling Arrays.sort() on your array like this:
Arrays.sort(score);
Once you have the array sorted, print out each element from the beginning using a loop of some kind:
for(int i = 0; i < 25; i++)
{
System.out.println(i + " " + score[i]);
}
That should do the trick for you. If you don't need a fancy new sorting algorithm, just use one that's already coded for you :)
You need to sort the array. Right now your code doesn't do it, it just keeps track of the biggest value.
I'm assuming you don't have to worry about execution time here. In other words, if the algorithm is going to take a long time to execute for a large input it doesn't matter to your professor.
There are many ways to sort an array. One way to do it called Bubble Sort. It is not very effective but will do the trick for you, and it's probably what your professor wants for now.
The idea is pretty simple: you discover the lowest value you hold on the entire array and swap the value with your current position. Imagine you have the following array:
[2, 4, 3, 5, 1]
Your current index is 0. You're going to go through the entire array to find the lowest value of them all. You will find out that the index 4, that holds the value 1 contains the lowest value. So you swap your current index (index 0, value 2). Now the array looks like this:
[1, 4, 3, 5, 2]
Now you move on to the next index, which is 1. You don't need to look at index 0 anymore since you already found out he is the lowest value and now you want the second lowest value. You do the same thing you did before: find the lowest value from index 1 to index 4 and swap them. You're going to do it until you get to the last index, where, you can guess by now, it will always be the biggest value.
Start by making sure you get the first value right. Once you get it, then move to the loop that iterates through the other values.
Working code : sort a two-dimensional array on column values in java.
Here we are using overloaded sort method in java.util.Arrays class which takes two arguments : the array to sort and a java.util.Comparator object.
import java.util.Arrays;
import java.util.Comparator;
public class SortArray {
Integer array[][] = { { 365, 265 }, { 222, 223 }, { 306, 262 },
{ 003, 559 }, { 004, 560 }, { 203, 224 }, { 113, 243 },
{ 208, 242 }, { 213, 229 }, { 115, 257 }, { 302, 242 },
{ 223, 230 }, { 001, 599 }, { 311, 256 }, { 323, 245 },
{ 321, 245 }, { 123, 253 }, { 104, 239 }, { 002, 513 },
{ 112, 239 }, { 207, 228 }, { 325, 246 }, { 116, 246 },
{ 218, 243 }, { 110, 238 } };
SortArray() {
System.out.println("Before sorting");
// show the contents of array
displayArray();
// sort array on score(second column)
Arrays.sort(array, new Comparator<Integer[]>() {
#Override
public int compare(Integer[] o1, Integer[] o2) {
Integer v1 = o1[1];
Integer v2 = o2[1];
// reverse sort on quantity
return v1.compareTo(v2);
}
});
// display array after sort
System.out.println("After sorting on score in ascending order");
displayArray();
}
public void displayArray() {
System.out.println("-------------------------------------");
System.out.println(" Index \t\t score");
for (int i = 0; i < array.length; i++) {
Integer[] sorted = array[i];
System.out.println(sorted[0] + "\t\t" + sorted[1]);
}
System.out.println("-------------------------------------");
}
public static void main(String[] args) {
new SortArray();
}
}
Explanation
A two dimensional array named array is created and initialized with default values.
First column of the array consists of Index values and second column is its Score.
For sorting the array, sort method of java.util.Arrays is used which takes 2 arguments : the array to be sorted and a java.util.Comparator object.
We pass an anonymous Comparator object(anonymous object means an object which has no name and which is created at its place of use only).
As 2d array in java is an array of arrays, thus, for sorting a 2d array on a column, we have to sort an integer array, therefore the generic type of this Comparator object should be Integer[ ].
Inside Comparator object, we implement its compare method which takes two objects of Integer[ ] type. These Integer objects represent the arrays to be compared.
For sorting the array on second column(score), the values at index 1 of the Integer[ ] objects are retrieved and compared.
Also read about Comparators and sort()
public static <T> void sort(T[] a,
Comparator<? super T> c)
Sorts the specified array of objects according to the order induced by the specified comparator. All elements in the array must be mutually comparable by the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the array).
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
Implementation note: This implementation is a stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when the input array is partially sorted, while offering the performance of a traditional mergesort when the input array is randomly ordered. If the input array is nearly sorted, the implementation requires approximately n comparisons. Temporary storage requirements vary from a small constant for nearly sorted input arrays to n/2 object references for randomly ordered input arrays.
The implementation takes equal advantage of ascending and descending order in its input array, and can take advantage of ascending and descending order in different parts of the the same input array. It is well-suited to merging two or more sorted arrays: simply concatenate the arrays and sort the resulting array.
The implementation was adapted from Tim Peters's list sort for Python ( TimSort). It uses techiques from Peter McIlroy's "Optimistic Sorting and Information Theoretic Complexity", in Proceedings of the Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, January 1993.
Parameters:
a - the array to be sorted
c - the comparator to determine the order of the array. A null value indicates that the elements' natural ordering should be used.

java random generator without repeat

Im trying to generate a 2d array using a random generator. basically, each column should contain a random value between 1-50 that is not repeated but the problem is, I can't get a repeat value on the same row, or any other row or column in the program. In other words, each I integer should only display once. My objects were created via linked list and I will probably integrate the algorthim in there once I figure it out but for now, heres what I did.
int[] array = new int[50];
for(int i=1;i<=9;i++)
{
int[] grades = new int[5];
for(int j=0;j<=4;j++)
{
int unique = gen.nextInt(50)+1;
grades[j] = unique;
}
list.add(new Student(i, grades));
}
System.out.println(list);
My output:
Student1: 20 49 45 16 13
Student2: 28 10 11 30 6
Student3: 13 25 37 31 49
Student4: 8 23 8 12 32
Student5: 22 18 35 2 7
Student6: 35 8 16 23 36
Student7: 35 3 15 42 2
Student8: 43 12 44 2 35
Student9: 12 21 36 23 12
So my issue is this. How can I implement the random gen without repeating values. Normally I would try a collection list by now, but I'm trying to do this using java.util.Random Personally, I would do this a different way but I'm instructed. Thank you
Here's what I would do:
Take an ArrayList of numbers 1-50, then use Collections.shuffle on the list.
You could check if the number is unique before accepting it. For example you could try something like the following:
int count=0;
List<Integer> list=new ArrayList<Integer>();
while(count<50){
int num=random.nextInt(50);
if(!list.contains(num)){
list.add(num);
++count;
}
}

Java Program for Prime numbers

Problem
In this project you will write a Java program that reads a positive integer n from standard input, then
prints out the first n prime numbers. We say that an integer m is divisible by a non-zero integer d if there
exists an integer k such that m = k d , i.e. if d divides evenly into m. Equivalently, m is divisible by d if
the remainder of m upon (integer) division by d is zero. We would also express this by saying that d is a
divisor of m. A positive integer p is called prime if its only positive divisors are 1 and p. The one
exception to this rule is the number 1 itself, which is considered to be non-prime. A positive integer that
is not prime is called composite. Euclid showed that there are infinitely many prime numbers. The prime
and composite sequences begin as follows:
Primes: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, …
Composites: 1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, …
There are many ways to test a number for primality, but perhaps the simplest is to simply do trial
divisions. Begin by dividing m by 2, and if it divides evenly, then m is not prime. Otherwise, divide by 3,
then 4, then 5, etc. If at any point m is found to be divisible by a number d in the range 2 d m−1, then
halt, and conclude that m is composite. Otherwise, conclude that m is prime. A moment’s thought shows
that one need not do any trial divisions by numbers d which are themselves composite. For instance, if a
trial division by 2 fails (i.e. has non-zero remainder, so m is odd), then a trial division by 4, 6, or 8, or any
even number, must also fail. Thus to test a number m for primality, one need only do trial divisions by
prime numbers less than m. Furthermore, it is not necessary to go all the way up to m−1. One need only
do trial divisions of m by primes p in the range 2 p m . To see this, suppose m >1 is composite.
Then there exist positive integers a and b such that 1 < a < m, 1 < b < m, and m = ab . But if both
a > m and b > m , then ab > m, contradicting that m = ab . Hence one of a or b must be less than
or equal to m .
To implement this process in java you will write a function called isPrime() with the following
signature:
static boolean isPrime(int m, int[] P)
This function will return true or false according to whether m is prime or composite. The array
argument P will contain a sufficient number of primes to do the testing. Specifically, at the time
isPrime() is called, array P must contain (at least) all primes p in the range 2 p m . For instance,
to test m = 53 for primality, one must do successive trial divisions by 2, 3, 5, and 7. We go no further
since 11 > 53 . Thus a precondition for the function call isPrime(53, P) is that P[0] = 2 , P[1] = 3 ,
P[2] = 5, and P[3] = 7 . The return value in this case would be true since all these divisions fail.
Similarly to test m =143 , one must do trial divisions by 2, 3, 5, 7, and 11 (since 13 > 143 ). The
precondition for the function call isPrime(143, P) is therefore P[0] = 2 , P[1] = 3 , P[2] = 5, P[3] = 7 ,
and P[4] =11. The return value in this case would be false since 11 divides 143. Function isPrime()
should contain a loop that steps through array P, doing trial divisions. This loop should terminate when
2
either a trial division succeeds, in which case false is returned, or until the next prime in P is greater
than m , in which case true is returned.
Function main() in this project will read the command line argument n, allocate an int array of length n,
fill the array with primes, then print the contents of the array to stdout according to the format described
below. In the context of function main(), we will refer to this array as Primes[]. Thus array Primes[]
plays a dual role in this project. On the one hand, it is used to collect, store, and print the output data. On
the other hand, it is passed to function isPrime() to test new integers for primality. Whenever
isPrime() returns true, the newly discovered prime will be placed at the appropriate position in array
Primes[]. This process works since, as explained above, the primes needed to test an integer m range
only up to m , and all of these primes (and more) will already be stored in array Primes[] when m is
tested. Of course it will be necessary to initialize Primes[0] = 2 manually, then proceed to test 3, 4, …
for primality using function isPrime().
The following is an outline of the steps to be performed in function main().
Check that the user supplied exactly one command line argument which can be interpreted as a
positive integer n. If the command line argument is not a single positive integer, your program
will print a usage message as specified in the examples below, then exit.
Allocate array Primes[] of length n and initialize Primes[0] = 2 .
Enter a loop which will discover subsequent primes and store them as Primes[1] , Primes[2],
Primes[3] , ..., Primes[n −1] . This loop should contain an inner loop which walks through
successive integers and tests them for primality by calling function isPrime() with appropriate
arguments.
Print the contents of array Primes[] to stdout, 10 to a line separated by single spaces. In other
words Primes[0] through Primes[9] will go on line 1, Primes[10] though Primes[19] will go
on line 2, and so on. Note that if n is not a multiple of 10, then the last line of output will contain
fewer than 10 primes.
Your program, which will be called Prime.java, will produce output identical to that of the sample runs
below. (As usual % signifies the unix prompt.)
% java Prime
Usage: java Prime [PositiveInteger]
% java Prime xyz
Usage: java Prime [PositiveInteger]
% java Prime 10 20
Usage: java Prime [PositiveInteger]
% java Prime 75
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379
%
3
As you can see, inappropriate command line argument(s) generate a usage message which is similar to
that of many unix commands. (Try doing the more command with no arguments to see such a message.)
Your program will include a function called Usage() having signature
static void Usage()
that prints this message to stderr, then exits. Thus your program will contain three functions in all:
main(), isPrime(), and Usage(). Each should be preceded by a comment block giving it’s name, a
short description of it’s operation, and any necessary preconditions (such as those for isPrime().) See
examples on the webpage.
Attempted Solution
class Prime {
public static void main(String[] args) {
int num1 = 0;
int num2 = 0;
int num3;
for (num1 = 1; num1 < 101; num1++)
System.out.println(num1);
for (num2 = 1; num2 < 101; num1++)
System.out.println(num2);
num3 = num2 % num1;
if (num3 == 0)
System.out.println("The prime numbers are " + num1);
else
System.out.println("The prime numbers are " + (num1 += 1));
}
}
Ben, it looks like you are attempting something that is far beyond your current capability. Start with some much simpler problems. Talk to your teacher and consider taking a more rudimentary course. You don't appear to understand either what the program is supposed to do, or how to write a program that might satisfy the requirements, and nothing we say here can overcome that - you have to develop more understanding of math and programming. We're happy to help with that, but just writing your program here won't help you, and you are too far away from a solution for suggestions to help. I'm sorry if this sounds harsh; honestly, I mean it constructively. Please stay with it - but start simpler.
Your example solution doesn't really follow the problem's specification at all. You should focus first on writing the static boolean isPrime(int m, int[] P) method. All that method needs to do is:
Iterate over the contents of P
If an element evenly divides m, m is composite -- return false
If an element's square is greater than m, m is prime -- return true. It sounds like from the problem description this won't ever happen, P will only have the primes from 2 to the one just before crossing the sqrt(m) boundary
If all the elements of P have been tested, m is prime -- return true
After that you can write main to make the primes array and build it up using the described loop, and finally do argument checking and implement the static void Usage() function to call if the arguments are invalid

Categories