Trying to Print Array without Repeating Numbers - java

I have a programming assignment where I am tasked with the following:
I am taking two int values (x and y) and creating two different arrays: the first (size x) will print an array starting from x and descending down to 1. The second (size y) will take random values from the first array (size x) and store it in its own array. I will then print out the second array. However, the second array cannot have any repeating values. For example, if the array was size 10, it could not have two of the same digit within its 10 individual indexes. I am attempting to store unique elements in my second array by creating two arrays, one boolean to check for unique elements and another one to store those unique elements. Here is my code:
/*
* user will enter desired size x for first array labeled arr_1
* arr_1 will contain values descending from x down to 1
* user will enter desired size y for second array labeled arr_2
* arr_2 will contain random values taken from arr_1 w/o repeating numbers
*/
import java.util.Arrays;
// import java.util.Arrays;
import java.util.Random;
// import java.util.Scanner;
public class Prog1B
{
public static void main(String[] args)
{
System.out.println("Program 1B, Christopher Moussa, masc1574");
// Scanner scnr = new Scanner(System.in);
int x = 20;
int v = x;
int[] arr_1 = new int[x];
for (int i = x-1; i >= 0; i--)
{
arr_1[i] = v; // System.out.print(i+1 + " "); prints 20, 19, ... , 1
v--; // System.out.print(arr_1[i] + " "); prints 20, 19, ... , 1
}
// int[] b = unique(arr_1);
System.out.println(Arrays.toString(unique(arr_1)));
}
public static int[] unique (int[] n)
{
boolean[] seen = new boolean[n.length];
int[] unique = new int[n.length];
Random rand = new Random(123L);
for (int i = 0; i < n.length; i++)
{
int index = rand.nextInt(n.length);
while (seen[index])
{
index = rand.nextInt(n.length);
}
unique[i] = n[index];
}
return unique;
}
}
The code compiles and runs, but it still prints out an array with repeating values. I am trying to write the program so that it does not print out an array with repeating values, only unique values. Do you have any suggestions as to where the problem lies? I am pretty sure it lies within the "unique" method, more specifically when the boolean array is checking for unique values (I noticed while trying to debug that even if the random index it generated was not unique, it still skipped the while condition and printed it out). I am a beginning programmer (a freshman at San Diego State studying computer science) and any feedback/advice will be greatly appreciated. Thanks you very much.

I found the problem in your code. You never update your "seen" Boolean array. See the code below for fix:
public static int[] unique (int[] n){
boolean[] seen = new boolean[n.length];
int[] unique = new int[n.length];
Random rand = new Random(123L);
for (int i = 0; i < n.length; i++)
{
int index = rand.nextInt(n.length);
while (seen[index])
{
index = rand.nextInt(n.length);
}
seen[index] = true; //boolean array updated
unique[i] = n[index];
}
return unique;
}
Using this fix, I was able to get the output below (which has no repeats):
[3, 11, 17, 10, 16, 18, 15, 6, 14, 20, 7, 13, 1, 19, 9, 2, 5, 4, 12, 8]

You need to even set your array seen[index] = true;
public static int[] unique (int[] n)
{
boolean[] seen = new boolean[n.length];
int[] unique = new int[n.length];
Random rand = new Random(123L);
for (int i = 0; i < n.length; i++)
{
int index = rand.nextInt(n.length);
while (seen[index])
{
index = rand.nextInt(n.length);
}
unique[i] = n[index];
seen[index] = true;
}
return unique;
}

Unless you specifically have to do it this way, I suggest you take a step back and try a totally different approach, something like this:
Set<int> mySet = new HashSet<int>(Arrays.asList(someArray));
NOTE: You will want to adjust the return type of unique() to be Set
The rest of the implementation is left as an excercise for the reader. Basically you take the array and convert it to a set as the example above.
(Credit where credit is due)
I just wanted to steer you in the right direction per https://meta.stackexchange.com/questions/10811/how-do-i-ask-and-answer-homework-questions
Good luck, I would say the biggest lesson here is how to walk away from code that has become inefficient when a better solution exists. Good luck!

Heres is how to do this using java8 lambdas
ArrayList<Integer> arrayli = new ArrayList<Integer>(Arrays.asList(arr_1));//converted array to list
System.out.println();
List<Integer> distinctIntegers = arrayli.stream().
.distinct()
.boxed()
.collect(Collectors.toList());
distinctIntegers.foreach(System.out::println);

Related

How to create a list of random numbers with no duplicates?

I need to create random numbers that will run through an array without duplicates.
The problem is the duplication and I can't use any of the utils except the Scanner for input (teacher instruction) like java.util.Random or java.util.ArrayList.
I use a function called random that my teacher wrote to us and the function newNum(int num) is where I need what I have asked - random numbers.
package exercise;
import java.util.Scanner;
public class Bingo {
static int size = 10;
static int num;
static int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
private static Scanner sc;
public static void main(String[] args) {
System.out.print("Press Enter to start: ");
sc = new Scanner(System.in);
sc.nextLine();
System.out.println("");
// int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// int[] tempArray = arr;
int num = random();
// int num = sc.nextInt();
// System.out.println(num);
while (size > 0) {
System.out.println(num);
size--;
newArray(num);
num = random();
newNum(num);
// System.out.println(num);
}
}
public static int random() {
int max = 10;
double r = Math.random();
int num = (int) (r * max + 1);
return num;
}
public static int newNum(int num) {
// Here should go the code for the function for getting only new
// random number without duplications
return num;
}
public static int newArray(int num) {
int[] tempArray = arr;
arr = new int[size];
int x = num - 1;
for (int i = 0; i < x; i++) {
if (i < size) {
arr[i] = tempArray[i];
}
}
for (int i = num; i < size; i++) {
if (i < size) {
int y = i - 1;
arr[y] = tempArray[i];
} else {
int a = size - 1;
arr[a] = tempArray[size];
}
}
return num;
}
}
First of all, you write that you can't use shuffle, but that doesn't mean that you are prohibited from implementing it. It's not that hard, actually.
If you want to do that, use the Fisher-Yates shuffle, as found on wikipedia: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
(by the way, since you are going to school, if you find such a wikipedia article - or any other article - to be interesting, you might propose to your teacher to hold an essay on that, easily earned additional good grade)
Of course, this assumes that you have a vector to shuffle, which is inefficient for large vectors ("random numbers within zero to one billion"). In this case you might want to go with:
To find n random numbers within 0..m
1. Initialize an empty list of already used random numbers which is ordered, called "numbers"
2. for i = 0..n-1
2a: r = random(0..m-i) (uniform distribution)
2b: for every entry in numbers
if entry <= r, r++
2c: sort r into numbers (maybe by using a single bubblesort step)
This shifts the complexity from the size of the vector as before to the amount of generated numbers.
Explanation: In every iteration, we want to find an unused number. We find the rth unused number (there is a range of 0..m-i of unused numbers in iteration i). Now we only need to find out which number is the rth unused one. This is done by the inner iteration. We need numbers to be sorted because of this example: current state: numbers = {5, 1}, r = 4. r < 5 -> do nothing. r >= 1 -> r++. End up with r = 5, got a double entry.
If sorting is not wanted for the resulting list, simply go with two lists.

remove duplicates inside random generated arrays [duplicate]

I'm trying to get random numbers between 0 and 100. But I want them to be unique, not repeated in a sequence. For example if I got 5 numbers, they should be 82,12,53,64,32 and not 82,12,53,12,32
I used this, but it generates same numbers in a sequence.
Random rand = new Random();
selected = rand.nextInt(100);
Add each number in the range sequentially in a list structure.
Shuffle it.
Take the first 'n'.
Here is a simple implementation. This will print 3 unique random numbers from the range 1-10.
import java.util.ArrayList;
import java.util.Collections;
public class UniqueRandomNumbers {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<11; i++) list.add(i);
Collections.shuffle(list);
for (int i=0; i<3; i++) System.out.println(list.get(i));
}
}
The first part of the fix with the original approach, as Mark Byers pointed out in an answer now deleted, is to use only a single Random instance.
That is what is causing the numbers to be identical. A Random instance is seeded by the current time in milliseconds. For a particular seed value, the 'random' instance will return the exact same sequence of pseudo random numbers.
With Java 8+ you can use the ints method of Random to get an IntStream of random values then distinct and limit to reduce the stream to a number of unique random values.
ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random also has methods which create LongStreams and DoubleStreams if you need those instead.
If you want all (or a large amount) of the numbers in a range in a random order it might be more efficient to add all of the numbers to a list, shuffle it, and take the first n because the above example is currently implemented by generating random numbers in the range requested and passing them through a set (similarly to Rob Kielty's answer), which may require generating many more than the amount passed to limit because the probability of a generating a new unique number decreases with each one found. Here's an example of the other way:
List<Integer> range = IntStream.range(0, 100).boxed()
.collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Create an array of 100 numbers, then randomize their order.
Devise a pseudo-random number generator that has a range of 100.
Create a boolean array of 100 elements, then set an element true when you pick that number. When you pick the next number check against the array and try again if the array element is set. (You can make an easy-to-clear boolean array with an array of long where you shift and mask to access individual bits.)
Use Collections.shuffle() on all 100 numbers and select the first five, as shown here and below.
Console:
59 9 68 24 82
Code:
private static final Random rnd = new Random();
private static final int N = 100;
private static final int K = 5;
private static final List<Integer> S = new ArrayList<>(N);
public static void main(String[] args) {
for (int i = 0; i < N; i++) {
S.add(i + 1);
}
Collections.shuffle(S, rnd);
for (int i = 0; i < K; i++) {
System.out.print(S.get(i) + " ");
}
System.out.println();
}
I feel like this method is worth mentioning.
private static final Random RANDOM = new Random();
/**
* Pick n numbers between 0 (inclusive) and k (inclusive)
* While there are very deterministic ways to do this,
* for large k and small n, this could be easier than creating
* an large array and sorting, i.e. k = 10,000
*/
public Set<Integer> pickRandom(int n, int k) {
final Set<Integer> picked = new HashSet<>();
while (picked.size() < n) {
picked.add(RANDOM.nextInt(k + 1));
}
return picked;
}
I re-factored Anand's answer to make use not only of the unique properties of a Set but also use the boolean false returned by the set.add() when an add to the set fails.
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class randomUniqueNumberGenerator {
public static final int SET_SIZE_REQUIRED = 10;
public static final int NUMBER_RANGE = 100;
public static void main(String[] args) {
Random random = new Random();
Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);
while(set.size()< SET_SIZE_REQUIRED) {
while (set.add(random.nextInt(NUMBER_RANGE)) != true)
;
}
assert set.size() == SET_SIZE_REQUIRED;
System.out.println(set);
}
}
I have made this like that.
Random random = new Random();
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while (arrayList.size() < 6) { // how many numbers u need - it will 6
int a = random.nextInt(49)+1; // this will give numbers between 1 and 50.
if (!arrayList.contains(a)) {
arrayList.add(a);
}
}
This will work to generate unique random numbers................
import java.util.HashSet;
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random rand = new Random();
int e;
int i;
int g = 10;
HashSet<Integer> randomNumbers = new HashSet<Integer>();
for (i = 0; i < g; i++) {
e = rand.nextInt(20);
randomNumbers.add(e);
if (randomNumbers.size() <= 10) {
if (randomNumbers.size() == 10) {
g = 10;
}
g++;
randomNumbers.add(e);
}
}
System.out.println("Ten Unique random numbers from 1 to 20 are : " + randomNumbers);
}
}
One clever way to do this is to use exponents of a primitive element in modulus.
For example, 2 is a primitive root mod 101, meaning that the powers of 2 mod 101 give you a non-repeating sequence that sees every number from 1 to 100 inclusive:
2^0 mod 101 = 1
2^1 mod 101 = 2
2^2 mod 101 = 4
...
2^50 mod 101 = 100
2^51 mod 101 = 99
2^52 mod 101 = 97
...
2^100 mod 101 = 1
In Java code, you would write:
void randInts() {
int num=1;
for (int ii=0; ii<101; ii++) {
System.out.println(num);
num= (num*2) % 101;
}
}
Finding a primitive root for a specific modulus can be tricky, but Maple's "primroot" function will do this for you.
I have come here from another question, which has been duplicate of this question (Generating unique random number in java)
Store 1 to 100 numbers in an Array.
Generate random number between 1 to 100 as position and return array[position-1] to get the value
Once you use a number in array, mark the value as -1 ( No need to maintain another array to check if this number is already used)
If value in array is -1, get the random number again to fetch new location in array.
I have easy solution for this problem,
With this we can easily generate n number of unique random numbers,
Its just logic anyone can use it in any language.
for(int i=0;i<4;i++)
{
rn[i]= GenerateRandomNumber();
for (int j=0;j<i;j++)
{
if (rn[i] == rn[j])
{
i--;
}
}
}
Choose n unique random numbers from 0 to m-1.
int[] uniqueRand(int n, int m){
Random rand = new Random();
int[] r = new int[n];
int[] result = new int[n];
for(int i = 0; i < n; i++){
r[i] = rand.nextInt(m-i);
result[i] = r[i];
for(int j = i-1; j >= 0; j--){
if(result[i] >= r[j])
result[i]++;
}
}
return result;
}
Imagine a list containing numbers from 0 to m-1. To choose the first number, we simply use rand.nextInt(m). Then remove the number from the list. Now there remains m-1 numbers, so we call rand.nextInt(m-1). The number we get represents the position in the list. If it is less than the first number, then it is the second number, since the part of list prior to the first number wasn't changed by the removal of the first number. If the position is greater than or equal to the first number, the second number is position+1. Do some further derivation, you can get this algorithm.
Explanation
This algorithm has O(n^2) complexity. So it is good for generating small amount of unique numbers from a large set. While the shuffle based algorithm need at least O(m) to do the shuffle.
Also shuffle based algorithm need memory to store every possible outcome to do the shuffle, this algorithm doesn’t need.
Though it's an old thread, but adding another option might not harm. (JDK 1.8 lambda functions seem to make it easy);
The problem could be broken down into the following steps;
Get a minimum value for the provided list of integers (for which to generate unique random numbers)
Get a maximum value for the provided list of integers
Use ThreadLocalRandom class (from JDK 1.8) to generate random integer values against the previously found min and max integer values and then filter to ensure that the values are indeed contained by the originally provided list. Finally apply distinct to the intstream to ensure that generated numbers are unique.
Here is the function with some description:
/**
* Provided an unsequenced / sequenced list of integers, the function returns unique random IDs as defined by the parameter
* #param numberToGenerate
* #param idList
* #return List of unique random integer values from the provided list
*/
private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) {
List<Integer> generatedUniqueIds = new ArrayList<>();
Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new);
Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new);
ThreadLocalRandom.current().ints(minId,maxId)
.filter(e->idList.contains(e))
.distinct()
.limit(numberToGenerate)
.forEach(generatedUniqueIds:: add);
return generatedUniqueIds;
}
So that, to get 11 unique random numbers for 'allIntegers' list object, we'll call the function like;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
The function declares new arrayList 'generatedUniqueIds' and populates with each unique random integer up to the required number before returning.
P.S. ThreadLocalRandom class avoids common seed value in case of concurrent threads.
try this out
public class RandomValueGenerator {
/**
*
*/
private volatile List<Double> previousGenValues = new ArrayList<Double>();
public void init() {
previousGenValues.add(Double.valueOf(0));
}
public String getNextValue() {
Random random = new Random();
double nextValue=0;
while(previousGenValues.contains(Double.valueOf(nextValue))) {
nextValue = random.nextDouble();
}
previousGenValues.add(Double.valueOf(nextValue));
return String.valueOf(nextValue);
}
}
This isn't significantly different from other answers, but I wanted the array of integers in the end:
Integer[] indices = new Integer[n];
Arrays.setAll(indices, i -> i);
Collections.shuffle(Arrays.asList(indices));
return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
you can use boolean array to fill the true if value taken else set navigate through boolean array to get value as per given below
package study;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Created By Sachin Rane on Jul 18, 2018
*/
public class UniqueRandomNumber {
static Boolean[] boolArray;
public static void main(String s[]){
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
integers.add(i);
}
//get unique random numbers
boolArray = new Boolean[integers.size()+1];
Arrays.fill(boolArray, false);
for (int i = 0; i < 10; i++) {
System.out.print(getUniqueRandomNumber(integers) + " ");
}
}
private static int getUniqueRandomNumber(List<Integer> integers) {
int randNum =(int) (Math.random()*integers.size());
if(boolArray[randNum]){
while(boolArray[randNum]){
randNum++;
if(randNum>boolArray.length){
randNum=0;
}
}
boolArray[randNum]=true;
return randNum;
}else {
boolArray[randNum]=true;
return randNum;
}
}
}
This is the most simple method to generate unique random values in a range or from an array.
In this example, I will be using a predefined array but you can adapt this method to generate random numbers as well. First, we will create a sample array to retrieve our data from.
Generate a random number and add it to the new array.
Generate another random number and check if it is already stored in the new array.
If not then add it and continue
else reiterate the step.
ArrayList<Integer> sampleList = new ArrayList<>();
sampleList.add(1);
sampleList.add(2);
sampleList.add(3);
sampleList.add(4);
sampleList.add(5);
sampleList.add(6);
sampleList.add(7);
sampleList.add(8);
Now from the sampleList we will produce five random numbers that are unique.
int n;
randomList = new ArrayList<>();
for(int i=0;i<5;i++){
Random random = new Random();
n=random.nextInt(8); //Generate a random index between 0-7
if(!randomList.contains(sampleList.get(n)))
randomList.add(sampleList.get(n));
else
i--; //reiterating the step
}
This is conceptually very simple. If the random value generated already exists then we will reiterate the step. This will continue until all the values generated are unique.
If you found this answer useful then you can vote it up as it is much simple in concept as compared to the other answers.
Check this
public class RandomNumbers {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 5;
int A[] = uniqueRandomArray(n);
for(int i = 0; i<n; i++){
System.out.println(A[i]);
}
}
public static int[] uniqueRandomArray(int n){
int [] A = new int[n];
for(int i = 0; i< A.length; ){
if(i == A.length){
break;
}
int b = (int)(Math.random() *n) + 1;
if(f(A,b) == false){
A[i++] = b;
}
}
return A;
}
public static boolean f(int[] A, int n){
for(int i=0; i<A.length; i++){
if(A[i] == n){
return true;
}
}
return false;
}
}
Below is a way I used to generate unique number always. Random function generates number and stores it in textfile then next time it checks it in file compares it and generate new unique number hence in this way there is always a new unique number.
public int GenerateRandomNo()
{
int _min = 0000;
int _max = 9999;
Random _rdm = new Random();
return _rdm.Next(_min, _max);
}
public int rand_num()
{
randnum = GenerateRandomNo();
string createText = randnum.ToString() + Environment.NewLine;
string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + #"\Invoices\numbers.txt";
File.AppendAllText(file_path, createText);
int number = File.ReadLines(file_path).Count(); //count number of lines in file
System.IO.StreamReader file = new System.IO.StreamReader(file_path);
do
{
randnum = GenerateRandomNo();
}
while ((file.ReadLine()) == randnum.ToString());
file.Close();
return randnum;
}
You can use the Collections class.
A utility class called Collections offers different actions that can be performed on a collection like an ArrayList (e.g., search the elements, find the maximum or minimum element, reverse the order of elements, and so on). One of the actions it can perform is to shuffle the elements. The shuffle will randomly move each element to a different position in the list. It does this by using a Random object. This means it's deterministic randomness, but it will do in most situations.
To shuffle the ArrayList, add the Collections import to the top of the program and then use the Shuffle static method. It takes the ArrayList to be shuffled as a parameter:
import java.util.Collections;
import java.util.ArrayList;
public class Lottery {
public static void main(String[] args) {
//define ArrayList to hold Integer objects
ArrayList numbers = new ArrayList();
for(int i = 0; i < 100; i++)
{
numbers.add(i+1);
}
Collections.shuffle(numbers);
System.out.println(numbers);
}
}
You can generate n unique random number between 0 to n-1 in java
public static void RandomGenerate(int n)
{
Set<Integer> st=new HashSet<Integer>();
Random r=new Random();
while(st.size()<n)
{
st.add(r.nextInt(n));
}
}

Comparing Two Arrays & Get the Percent that Match - Java

Background: Very new at Java, have little understanding. Would prefer a "point in the right direction" with explanation, if possible, than a copy/paste answer without explanation. If I want to stop being a novice, I need to learn! :)
Anyway, my goal is, as simply as possible, to be given 2 arrays numberList and winningNumbers, compare them, and return the percentage that numberList matches winningNumbers. Both array lengths will always be 10.
I have no idea where to start. I have been googling and going at this for 2 hours. My idea is to write a for loop that compares each individually integer in a string to one in the other, but I am not sure how to do that, or if there is a simpler method. I have little knowledge of arrays, and the more I google the more confused I become.
So far the only thing I have is
public double getPercentThatMatch(int[] winningNumbers) {}
numberList is preset.
one way you could approach it is to:
1) convert both lists to sets.
2) subtract one from the other. ie if 4 are the same, the resulting set will have the 6 values not the same
3) 10 - (size of resulting set) * 100 = %
Here's a runnable example of how you would compare the two arrays of ints to get a percent match.
public class LotteryTicket {
int[] numberList;
LotteryTicket(int... numbers) {
numberList = numbers;
}
public int getPercentThatMatch(int[] winningNumbers) {
Arrays.sort(numberList);
Arrays.sort(winningNumbers);
int i = 0, n = 0, match = 0;
while (i < numberList.length && n < winningNumbers.length) {
if (numberList[i] < winningNumbers[n]) {
i++;
} else if (numberList[i] > winningNumbers[n]) {
n++;
} else {
match++;
i++;
n++;
}
}
return match * 100 / winningNumbers.length;
}
public static void main(String[] args)
{
int[] winningNumbers = { 12, 10, 4, 3, 2, 5, 6, 7, 9, 1 };
LotteryTicket ticket = new LotteryTicket(5, 2, 6, 7, 8, 4, 3, 1, 9, 0);
int percentMatching = ticket.getPercentThatMatch(winningNumbers);
System.out.println(percentMatching + "%");
}
}
Output:
80%
Since you wanted to be pointed in the right direction, rather than havving proper code, and assuming you want to use arrays to solve the problem, try to put something like this in your method:
(loop through arrayA){
(loop through arrayB){
if (current arrayA number is equal to current arrayB number){
then increase match counter by one, since this exists.
also break out of current arrayB loop. (Check next arrayA now.)
}
}
}
When done: return 100*matchCount/totalCount, as a double
So for every index in one array, you check against every other index of the other array. Increase a counter each time there's a match, and you'll be able to get a ratio of matches. If you use an integer as a counter, remember that division with integers acts funky, so you'd need to throw to a double:
double aDoubleNumber = (double) intNumber / anotherIntNumber
The problem would be easier if we consider them set. Let you have two set -
Set<Integer> s1 = //a HashSet of Integer;
Set<Integer> s2 = //a HashSet of Integer;
Now make a copy of s1 for example s11 and do the following thing -
s1.retainAll(s2);
Now s1 contains only element of both sets - that is the intersection.
After that you can easily calculate the percentage
Edit: You can convert the array to a set easily by using the following code snippet (I am assuming you have array of int) -
Set<Integer> s1 = new HashSet<Integer>(Arrays.asList(somePrimiteiveIntArray));
I think this trick will works for other primitive type also.
Hope this will help.
Thanks a lot.
I am going to attempt to beat a dead horse and explain the easiest (conceptual) way to approach this problem I will include some code but leave a lot up to interpretation.
You have two arrays so I would change the overall method to something like this:
public double getPercentage(int[] arrayA, int[] arrayB) {
double percentage=0;
for(/*go through the first array*/) {
for(/*go through second array*/) {
if(arrayA[i]==arrayB[j]) { /*note the different indices*/
percentage++; /*count how many times you have matching values*/
/* NOTE: This only works if you don't have repeating values in arrayA*/
}
}
}
return (percentage/arrayA.length)*100; /*return the amount of times over the length times 100*/
}
You are going to move through the first array with the first loop and the second array with the second loop. So you go through every value in arrayB for each value in arrayA to check.
In my approach I tried storing the winning numbers in a Hashset (one pass iteration, O(n) )
And when iterating on the numberList, I would check for presence of number in Hashset and if so, I will increment the counter. (one pass iteration, so O(n) )
The percentage is thus calculated by dividing the counter with size of array.
See if the sample code makes sense:
import java.util.HashSet;
public class Arraycomparison {
public static void main(String ... args){
int[] arr0 = {1,4,2,7,6,3,5,0,3,9,3,5,7};
int[] arr1 = {5,2,4,1,3,7,8,3,2,6,4,4,1};
HashSet set = new HashSet();
for(int j = 0; j < arr1.length; j++){
set.add(arr1[j]);
}
double counter = 0;
for(int i = 0; i < arr0.length; i++){
if(set.contains(arr0[i])){
counter++;
}
}
System.out.println("Match percentage between arrays : " + counter/arr0.length*100);
}
}
You should use List over array, because that's a convenient way, but with array:
public class Winner {
public static void main(String... args) {
double result = getPercentThatMatch(new int[]{1,2,3,4,5}, new int[]{2,3,4,5,6});
System.out.println("Result="+result+"%");
}
public static double getPercentThatMatch(int[] winningNumbers,
int[] numberList) { // it is confusing to call an array as List
int match = 0;
for (int win : winningNumbers) {
for (int my : numberList ){
if (win == my){
System.out.println(win + " == " + my);
match++;
}
}
}
int max = winningNumbers.length; // assume that same length
System.out.println("max:"+max);
System.out.println("match:"+match);
double devide = match / max; // it won't be good, because the result will be intm so Java will trunc it!
System.out.println("int value:"+devide);
devide = (double) match / max; // you need to cast to float or double
System.out.println("float value:"+devide);
double percent = devide * 100;
return percent;
}
}
Hope this helps. ;)
//For unique elements
getpercentage(arr1, arr2){
res = arr1.filter(element=>arr2.includes(element))
return res.lenght/arr2.lenght * 100;
}
//For duplicate elements
getpercentage(arr1, arr2){
const setA = Set(arr1);
const setB = Set(arr2);
Let res = [ ];
for(let i of setB){
if(setA.has(i)){
res.push(i);
}
}
return res.lenght/setA.size* 100;

Rearrange int array, sort into groups with a sum maximum in Java

I know most people don't like writing methods for people but i was hoping someone could help me convert my algorithm into Java code. I hope my algorithm is good and actually works.
Sort a given array of ints into ascending order. Set Group Limit to 15 (that means that the sum of the group is not greater than 15).
Take the first element of the sorted array and insert into a Group (new array/list) eg. Group A.
Take the second element of the sorted array and insert unless it will make it exceed the group limit. If it exceeds, create a new Group B and insert there.
Take third element and try to insert into next available group.
Repeat until all ints have been checked and grouped.
Input:
egArray = [1,3,4,6,6,9,12,14]
Output:
Group A: [1,3,4,6], Group B: [6,9], Group C: [12], Group D: [14]
I have tried to do this, but failed epically, not even worth me posting my code. :-(
This is an example data and an algorithm I've made up for self learning, so please keep the criticism to a minimum. I genuinely learn from a lot of Stackoverflow posts people have written over the last few months, unfortunately I couldn't find one like this example. Thanks.
Try this:
public static void main(String[] arguments) {
int limit = 15;
int[] egArray = new int[] { 14, 1, 3, 4, 6, 6, 9, 12 };
ArrayList<ArrayList<Integer>> a = grouping(limit, egArray);
System.out.println(a);
}
public static ArrayList<ArrayList<Integer>> grouping(int limit, int[] array) {
// Sort the input array.
Arrays.sort(array);
// Copy the int[] to an ArrayList<Integer>
ArrayList<Integer> input = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
input.add(array[i]);
}
// Initialize the groups
ArrayList<ArrayList<Integer>> groups = new ArrayList<>();
groups.add(new ArrayList<Integer>());
// Initialize the sums of the groups, to increase performance (I guess).
ArrayList<Integer> sums = new ArrayList<>();
sums.add(0);
// Iterate through the input array until there is no number
// left in it (that means we just added all the numbers
// into our groups array).
while (!input.isEmpty()) {
int n = input.get(0); // Store the number to 'n', to shortcut.
if (n > limit) {
String msg = "number is greater than the limit; cannot add number";
throw new IllegalArgumentException(msg);
// Or whatever to do if the number is larger than the limit.
}
boolean match = false;
// Search the next groups and check if our current
// number ('n') fits.
for (int i = 0; i < sums.size(); i++) {
if (sums.get(i) + n <= limit) {
// If it fits, then add the number to the group.
sums.set(i, sums.get(i) + n);
groups.get(i).add(n);
match = true;
break;
}
}
// If 'n' doesn't fit in any group, create a new one.
if (!match) {
ArrayList<Integer> e = new ArrayList<>();
e.add(n);
groups.add(e);
sums.add(n);
}
// Remove our number.
input.remove(0);
}
return groups;
}
Notice that the method returns an ArrayList<ArrayList<Integer>> instead of an int[][], but the effect is the same. In order to check the values of the groups, just run the main(String).
How about this method?
public static ArrayList group(ArrayList<Integer> arr, Integer groupLimit) {
ArrayList<ArrayList> result = new ArrayList<ArrayList>();
ArrayList<Integer> temp = new ArrayList<Integer>();
for (Integer x : arr) {
if (sumElements(temp) + x < groupLimit) {
temp.add(x);
} else {
result.add(temp);
temp = new ArrayList<Integer>();
temp.add(x);
}
}
if (temp.size() > 0) {
result.add(temp);
}
return result;
}
public static int sumElements(ArrayList<Integer> arr) {
Integer result = 0;
for(Integer x:arr) result += x;
return result;
}

Count how many times an element occurs in an array - Java

I recently made a very simple practice program in Python, that takes user input and rolls dice. The code is:
import random
import sys
import math
def roll(rolls, sides, results):
for rolls in range(1, rolls + 1):
result = random.randrange(1, sides + 1)
print result
results.append(result)
def countf(rolls, sides, results):
i = 1
print "There were", rolls, "rolls."
for sides in range(1, sides + 1):
if results.count(i) != 1:
print "There were", results.count(i), i,"s."
else:
print "There was", results.count(i), i
i = i + 1
if i == sides:
break
rolls = input("How many rolls? ")
sides = input("How many sides of the die? ")
results = []
roll(rolls, sides, results)
countf(rolls, sides, results)
(actually this is part of a larger program, so I had to cut'n'paste bits, and I might have missed something out).
And so I decided to translate that to Java. Notice the algorithm here: get random number, print it, append it to an array, then count the amount of each number in the array at the end, and print out that value. Problem is, I don't know how to do the equivalent of someArray.count(someIndex) in Java syntax. So my Java program looks like this so far:
import java.util.*;
public class Dice {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
final static int TIMES_TO_ROLL = getInt("Times to roll?");
Random flip = new Random();
int[] results = new int[TIMES_TO_ROLL];
for (int i = 0; i < TIMES_TO_ROLL; i++) {
int result = flip.nextInt(6);
System.out.println(result);
results[i] = result;
}
}
public static int getInt(String prompt) {
System.out.print(prompt + " ");
int integer = input.nextInt();
input.nextLine();
return integer;
}
}
So can someone help me with the array counting code? I understand that this might not be a defined method, since Python is higher level after all, so I could make my own array counting method, but I was wondering if Java, like Python, has a predefined one.
EDIT: I managed something like this:
public static int arrayCount(int[] array, int item) {
int amt = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == item) {
amt++;
}
else {
amt = amt;
}
}
return amt;
}
EDIT: Just out of interest, assuming I use Command prompt to run my Java program and Python.exe (command prompt console for Python), which one will be faster (in other words, for the same code, which language has better performance?)?
You could use a HashMap to store the result.
If the new number is not in your map you add it with "1" as initial value.
If it exists your put "+1" to the current map value.
To display the values you just have to iterate on you entries in a for each loop.
The solution is to transform your array to a List and then use the Collections.frequency method:
List<Integer> resultList = Arrays.asList(results);
int freq = Collections.frequency(resultList, 4);
Also you could use ArrayList from the very beginning saving you the transformation:
List<Integer> result = new ArrayList<Integer>();
// add results
int freq = Collections.frequency(result, 4);
See the Collections documentation here
EDIT: If performance is an issue (as suggested in the comments) then maybe you want to use each index of the array as a counter, as follows:
Random flip = new Random(SIDES);
int[] counters = new int[SIDES];
for (int i = 0; i < TIMES_TO_ROLL; i++) {
int result = flip.nextInt;
counters[result] = counters[result]+1;
}
Notice that you no longer need to count at the end since you've already got all the counters in the array and there is no overhead of calculating the hash.
There are a couple libraries that will do this for you:
Google Guava's MultiSet
Apache Common's Bag
But for something so simple, you may consider an extra library a bit excessive.
You can also do this yourself with an int[]. Assuming your dice is using whole numbers, have the number rolled refer to the index into the array, and then increment the value at that index. When you need to retrieve the value for a given number, look up its value by the index.
private static final int NUMBER_DICE_SIDES = 6;
public static void main(String[] args) {
final static int TIMES_TO_ROLL = getInt("Times to roll?");
Random flip = new Random(NUMBER_DICE_SIDES);
int[] results = new int[NUMBER_DICE_SIDES];
for (int i = 0; i < TIMES_TO_ROLL; i++) {
int result = flip.nextInt;
System.out.println(result);
results[result]++;
}
for(int i = 0; i < NUMBER_DICE_SIDES; ++i) {
System.out.println((i+1)+"'s: " + arraysCount(results, i));
}
}
public static int arrayCount(int[] array, int item) {
return array[item];
}
There's a frequency method in collections
int occurrences = Collections.frequency(listObject, searchItem);
Java doc for collections
As far as I am aware, there is no defined method to return the frequency of a particular element in an array. If you were to write a custom method, it would simply be a matter of iterating through the array, checking each value, and if the value matches the element you're after, incrementing a counter.
So something like:
// in this example, we assume myArray is an array of ints
private int count( int[] myArray, int targetValue) {
int counter = 0;
for (int i = 0 ; i < myArray.length; i++ ) {
if (myArray[i] == targetValue) {
counter++;
}
}
return counter;
}
Of course, if you want to find the frequency of all the unique values in your array, this has the potential of being extremely inefficient.
Also, why are you using a 7-sided die? The Random nextInt() will return a number from 0 up to but not including the max. So your die will return values from 0 through 6. For a six-sided die, you'd want a new Random(6); and then increment your roll by one to get a value from one through six: flip.nextInt() +1;.
class FindOccurrence {
public static void main (String[]args) {
int myArray[] = {5, 8, 5, 12, 19, 5, 6, 7, 100, 5, 45, 6, 5, 5, 5};
int numToFind = 5;
int numberOfOccurrence = 0;
for (int i=0; i < myArray.length; i++) {
if (numToFind == myArray[i]) {
numberOfOccurrence++;
}
}
System.out.println("Our number: " + numToFind);
System.out.println("Number of times it appears: " + numberOfOccurrence);
}
}

Categories