I have a function 'generateRan' that generates random numbers. This function can not be changed.
int generateRan() {
Random num = new Random();
return (1 + num.nextInt(100));
}
I have to write code that will:
Print numbers 1-20 randomly.
Print numbers 1-200 randomly.
Each number should be printed only once.
The function can be used any number of times. But it is a bit heavy so I want to make the code more optimized.
Here is what I've coded:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList();
Test t = new Test();
iniList(list, 20);
for (Integer i = ((t.generateRan()) % 20); list.size() > 0; i = 1+((t
.generateRan()) % 20)) {
if (list.contains(i.toString())) {
list.remove(i.toString());
System.out.println(i);
}
}
System.out.println("********");
iniList(list, 200);
for (Integer i = ((t.generateRan()%2)*100 + t.generateRan()) ; list.size() > 0; i = ((t.generateRan()%2)*100 + t.generateRan())) {
if (list.contains(i.toString())) {
list.remove(i.toString());
System.out.println(i);
}
}
}
private static void iniList(List list, int i) {
for (Integer k = 1; k <= i; k++) {
list.add(k.toString());
}
}
int generateRan() {
Random num = new Random();
return (1 + num.nextInt(100));
}
}
Currently the code for 1-200 is incorrect.
Each numbers should print only once
Then all you need to to is create a List<Integer> of the entire range, then call Collections.shuffle.
private static void displayNumbers(int minInclusive, int maxInclusive) {
List<Integer> list = new ArrayList<Integer>();
for (int i = minInclusive; i <= maxInclusive; i++) {
list.add(i);
}
Collections.shuffle(list);
for (int value : list) {
System.out.println(value);
}
}
Personally I'd normally use parameters of minInclusive, maxExclusive or minInclusive, count, but it looks like it may be more readable this way for your situation.
Assuming you have to use your generateRan() function, otherwise use Collections.shuffle as indicated.
public static void main(String[] args) {
List<Integer> list = new ArrayList();
initList(list, 200);
while (list.size() > 0) {
int index = generateRan() % list.size();
System.out.println(list.remove(index));
}
}
public static void initList(List<Integer> s, int size) {
for (int i = 1; i <= size; i ++)
s.add(i);
}
public static int generateRan() {
Random num = new Random();
return (1 + num.nextInt(100));
}
You add all the ints you want to print to your list, then only use random to choose which one of these to print. Your function is called n times.
I would recomment using a Set rather than a List, for it's faster in searching for duplicates
Set<Integer> set = new HashSet<Integer>();
for(int i = 0; i < 20;) {
Integer r = generateRan();
if(set.add(r)) {
System.out.println(r);
++i;
}
}
Related
I am trying to implement the top-down merge sort algorithm in Java, using the pseudocode from Wikipedia.
My problem is that my code sometimes throws a StackOverflowError, but not always. I have checked that my code matches the pseudocode several times and cannot find what is wrong with it.
Here is my Java code:
import java.util.ArrayList;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random r = new Random();
ArrayList<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 15; i++) {
numbers.add(r.nextInt(100));
}
numbers = mergeSort(numbers);
System.out.println(numbers);
}
public static ArrayList<Integer> mergeSort(ArrayList<Integer> m) {
if (m.size() <= 1) {
return m;
}
ArrayList<Integer> left = new ArrayList<Integer>();
ArrayList<Integer> right = new ArrayList<Integer>();
for (Integer x : m) {
if (m.indexOf(x) < (m.size()) / 2)
left.add(x);
else {
right.add(x);
}
}
left = mergeSort(left);
right = mergeSort(right);
return merge(left, right);
}
private static ArrayList<Integer> merge(ArrayList<Integer> l, ArrayList<Integer> r) {
ArrayList<Integer> result = new ArrayList<Integer>();
while (l.size() > 0 && r.size() > 0) {
if (l.get(0) <= r.get(0)) {
result.add(l.get(0));
l.remove(0);
}
else {
result.add(r.get(0));
r.remove(0);
}
}
while (l.size() > 0) {
result.add(l.get(0));
l.remove(0);
}
while (r.size() > 0) {
result.add(r.get(0));
r.remove(0);
}
return result;
}
}
Your algorithm encounters issues when there are duplicate elements, as indexOf will only return the index of the first one. Use a index-based for loop instead. Demo
for (int i = 0; i < m.size(); i++) {
if (i < (m.size()) / 2)
left.add(m.get(i));
else {
right.add(m.get(i));
}
}
In the mergeSort method need to change the for loop little bit and try again.
for (int i=0;i< m.size()/2;i++)
left.add(m.get(i));
for (int i=m.size()/2;i< m.size();i++)
right.add(m.get(i));
Okay, so i need to find all the negative numbers of array and return them.I found the negative number, but how do i return them all? P.S yes i am a beginner.
public static void main(String[] args) {
int [] array = {5,-1,6,3,-20,10,20,-5,2};
System.out.println(findNumber(array));
}
public static int findNumber(int[] sum) {
int num = 0;
for (int i = 0; i < sum.length ; i++) {
if(sum[i] < num) {
num = sum[i];
}
}
return num;
}
Java 8 based solution. You can use stream to filter out numbers greater than or equal to zero
public static int[] findNumber(int[] sum)
{
return Arrays.stream(sum).filter(i -> i < 0).toArray();
}
There are multiple ways of doing this, if you just want to output all of the negative numbers easily you could do this:
public static void main(String[] args) {
int [] array = {5,-1,6,3,-20,10,20,-5,2};
ArrayList<Integer> negativeNumbers = findNumber(sum);
for(Integer negNum : negativeNumbers) {
System.out.println(negNum);
}
}
public static ArrayList<Integer> findNumber(int[] sum) {
ArrayList<Integer> negativeNumbers = new ArrayList<>();
for (int i = 0; i < sum.length ; i++) {
if(sum[i] < 0) {
negativeNumber.add(sum[i]);
}
}
return negativeNumbers;
}
As you told you are beginner, i'm giving code in using arrays only.
Whenever you come across a negative number, just add it to the array and increment it's index number and after checking all the numbers, return the array and print it.
public static void main(String[] args)
{
int [] array = {5,-1,6,3,-20,10,20,-5,2};
int[] neg = findNumber(array);
for(int i = 0 ; i<neg.length; i++)
{
System.out.println(neg[i]);
}
}
public static int[] findNumber(int[] a)
{
int j=0;
int[] n = new int[a.length];
for(int i = 0; i<a.length ; i++)
{
if(a[i] <0)
{
n[j] = a[i];
j++;
}
}
int[] neg = new int[j];
for( int k = 0 ; k < j ; k++)
{
neg[k] = n[k];
}
return neg;
}
I hope it helps.
You can modify your method to iterate through the array of numbers, and add every negative number you encounter, to a List.
public static List<Integers> findNegativeNumbers(int[] num) {
List<Integers> negativeNumbers = new ArrayList<>();
for (int i = 0; i < num.length; i++) {
if(num[i] < 0) {
negativeNumbers.add(num[i]);
}
}
return negativeNumbers;
}
You could then print out the list of negative numbers from this method itself, or return the list with return to be printed in main.
You code is returning the sum of elements, but I understood that you wanted every negative number.
So, I assumed you want something like this:
public static void main(String[] args) {
int [] array = {5,-1,6,3,-20,10,20,-5,2};
Integer [] result = findNumbers( array );
for( int i : result )
{
System.out.println( i );
}
}
public static Integer[] findNumbers(int[] v) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < v.length ; i++) {
if(v[i] < 0) {
list.add(v[i]);
}
}
return list.toArray( new Integer[0] );
}
Is it?
Best regards.
public static int[] findNum(int[] array)
{
int negativeIntCount = 0;
int[] negativeNumbers = new int[array.length];
for(int i = 0; i < array.length; i++)
{
if(array[i] < 0)
{
negativeIntCount++;
negativeNumbers[i] = array[i];
}
}
System.out.println("Total negative numbers in given arrays is " + negativeIntCount);
return negativeNumbers;
}
To display as an array in output :
System.out.println(Arrays.toString(findNum(array)));
To display output as space gaped integers :
for(int x : findNum(array))
{
System.out.print(" " + x)
}
In this code I have found duplicates from an array and I want to remove them. The output then will be unique generated numbers. I am required to use math.random and modulo. Anyone have any clues? I tried to store them in an array but then the original array has 0's and 0 is part of my domain for the random number generation (from 0 to 52).
public class Decks {
public static void main(String[] args) {
generate();
}
public static void generate() {
int deckOfCard[] = new int[52];
for (int counts = 0; counts < 52; counts++) {
deckOfCard[counts] = (int) (Math.random() * 51);
}
for (int i = 0; i < deckOfCard.length - 1; i++) {
for (int j = i + 1; j < deckOfCard.length; j++) {
if ((deckOfCard[i] == (deckOfCard[j])) && (i != j)) {
System.out.println("DUPLICATE " + deckOfCard[i]);
}
}
}
for (int count = 0; count < deckOfCard.length; count++) {
System.out.print("\t" + deckOfCard[count]);
}
}
Why dont you try using HashSet instead of arrays ? As you know sets only store unique values so you wont have any duplicates.
You must validate the numbers generated during the random number generation like this:
import java.util.Random;
public class Decks {
public static void main(String[] args) {
Random myRandom = new Random();
int[] num = new int[53];
boolean[] check = new boolean[53];
int all = 0;
int ranNum;
while (all < 53) {
ranNum = myRandom.nextInt(53);
if (!check[ranNum]) {
check[ranNum] = true;
num[all] = ranNum;
all++;
}
}
for (int i = 0; i < 53; i++) {
System.out.println(num[i]);
}
}
}
I suggest not including number 0 because it does not exist in a real deck of cards (ACE being the lowest having the number value of 1). I just included it right here because in my understanding, 0 is included in your desired output.
Considering time complexity, you can sort them first, which at best case takes nlogn time, and then use O(1) to find duplicated elements out.
I want to generate unique random numbers from range 0 to 999,999.
In order to achieve that, I tried:
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 999999; i++) {
list.add(new Integer(i)); // Add numbers from 0 - 999,999 into ArrayList
}
Collections.shuffle(list); // shuffle them
for (int i = 0; i < 10; i++) {
System.out.println(list.get(i)); // printed unique numbers
}
The problem is the larger the number I want to generate, the longer the time it takes, for the above method, it took about 700ms.
But if I use Random() to generate them without filter duplicate numbers, it only takes 2ms
for(int i = 0; i<10; i++) {
int digit = 0 + new Random().nextInt((999999 - 0) + 1);
System.out.println(digit);
}
Is there other way to generate unique random numbers in a more efficient manner?
There is no need to create a list of 1000000 numbers and shuffle them all if you only need 10. There is also no need to write new Integer(i) (you can just use i).
In Java 8 there is a very short way to do this:
int[] arr = ThreadLocalRandom.current().ints(0, 1000000).distinct().limit(10).toArray();
System.out.println(Arrays.toString(arr));
If you are using Java 7 or below, you could do this:
Random rand = new Random(); // Only do this in Java 6 or below. Now you should use ThreadLocalRandom.current().
int[] arr = new int[10];
Set<Integer> set = new HashSet<Integer>();
for (int index = 0, a; index < 10;)
if (set.add(a = rand.nextInt(1000000)))
arr[index++] = a;
System.out.println(Arrays.toString(arr));
You could create a set of random integers like this:
Set<Integer> set = new HashSet<Integer>();
Random rand = new Random();
while (set.size() < 10) {
set.add(rand.nextInt((1000000)));
}
The idea is that the set data structure will remove duplicates.
here is my code
its work perfect
private int count;
private boolean in = true;
public static final Random gen = new Random();
int[] result;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void addUse() {
result = new int[getCount() + 10];
for (int i = 1; i < 10; i++) {
String setup = ("" + i + i + i + i + i);
result[getCount() + i] = Integer.valueOf(setup);
}
}
public boolean chechArray(int number) {
for (int i = 0; i < getCount() + 10; i++) {
if (result[i] == number) {
in = true;
break;
} else {
in = false;
}
}
return in;
}
public void printRandomNumbers() {
Random gen = new Random();
for (int i = 0; i < getCount(); i++) {
int get = gen.nextInt(100000 - 10000) + 10000;
if (chechArray(get) == false) {
result[i] = get;
} else {
i--;
}
}
}
public void viewArray() {
printRandomNumbers();
for (int i = 0; i < getCount(); i++) {
System.out.println((i + 1) + " Number is = " + result[i]);
}
}
public static void main(String[] args) {
RandomDemo3 rd2 = new RandomDemo3();
rd2.setCount(20);
rd2.addUse();
rd2.viewArray();
}
I'm trying to solve this problem:
"Write a program that reads in ten numbers and displays the number of distinct numbers and the distinct numbers separated by exactly one space."
My code at the moment does not save all distinct numbers and at time repeatedly display 0. If anyone can see where my logic has gone wrong, any tip will be helpful. Thank you!
public class PracticeProject
{
public static void main(String args[])
{
int[] number = new int[10];
int[] counter = new int[10];
int numcounter = 0;
numGen(number);
numcounter = distNum(number, counter, numcounter);
dispDist(counter, numcounter);
}
public static void numGen(int[] number)
{
Random rand = new Random();
for (int i = 0; i < number.length; i++)
{
number[i] = rand.nextInt(10);
System.out.print(number[i] + " ");
}
System.out.println();
}
public static int distNum(int[] number, int[] counter, int numcounter)
{
for (int i = 0; i < number.length; i++)
{
for (int j = 0; j <= i; j++)
{
if (counter[j] == number[i])
{
break;
}
if (j == i)
{
counter[j] = number[i];
numcounter++;
}
}
}
return numcounter;
}
public static void dispDist(int[] counter, int numcounter)
{
for (int i = 0; i < numcounter; i++)
{
System.out.print(counter[i] + " ");
}
}
}
The problem is with the logic in your distNum() method, which was not correctly removing all duplicates from the output array. Try using this version instead:
public static int distNum(int[] number, int[] counter, int numcounter) {
for (int i = 0; i < number.length; i++) {
boolean isUnique = true;
for (int j = 0; j < numcounter; j++) {
if (counter[j] == number[i]) {
isUnique = false;
break;
}
}
if (isUnique) {
counter[numcounter] = number[i];
numcounter++;
}
}
return numcounter;
}
I walk through the array of random numbers, and for each one I scan counter to see if the value has already been encountered. If it be a duplicate, then it does not get added to the unique list.
This method was tested along with the rest of your original code using IntelliJ, and it appears to be working correctly.
If you use array to store your counters, you need to set default value, otherwise if your array have multiple 0, it distinguish by equaling. because the int array default values is 0.
and you can use list or vector to store your counters.
public static void main(String args[]) {
int[] number = new int[10];
int[] counter = new int[10];
List<Integer> counters = new ArrayList<Integer>();
int numcounter = 0;
numGen(number);
numcounter = distNum(number, counters, numcounter);
dispDist(counters, numcounter);
}
public static void numGen(int[] number) {
Random rand = new Random();
for (int i = 0; i < number.length; i++) {
number[i] = rand.nextInt(10);
System.out.print(number[i] + " ");
}
System.out.println();
}
public static int distNum(int[] number, List<Integer> counters, int numcounter) {
for (int i : number) {
if (!counters.contains(i)){
counters.add(i);
}
}
return numcounter;
}
public static void dispDist(List<Integer> counter, int numcounter) {
for (Integer i : counter) {
System.out.print(i + " ");
}
}
Try put below function .... using Hashmap... Key will be no. and value will be the disctinct time it occured.
public void duplicate(int[] a) {
HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
for (int i = 0; i < a.length; i++) {
Integer j = (int) h.put(a[i], 1);
if (j != null) { // checking if already in hashmap
h.put(a[i], j + 1); // if there then incrementing value
}
}
Iterator it = h.entrySet().iterator(); // displaying value you can have you logic here
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}