Hello guys it might be a dumb question but I am stuck.
I am working on cyclic numbers code. After completing I put all the integers in the array however after that there are some empty cells at the beginning of array that have to be cleaned or put into another array with appropriate amount of elements. So how to get rid of 0 at the beginning.
Here is the code for my cyclic numbers:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int carry = 0;
int[] cyclic = new int[60];
int lastDigit = input.nextInt();
cyclic[cyclic.length - 1] = lastDigit;
for ( int i = cyclic.length - 2; i >= 0; i--) {
cyclic[i] = lastDigit * cyclic[i + 1];
cyclic[i] += carry;
if (cyclic[i] > 9) {
carry = cyclic[i] / 10;
cyclic[i] %= 10;
} else
carry = 0;
if (cyclic[i]==1 & cyclic[i+1]== 0)
break;
}
for (int j = 0; j < cyclic.length; j++)
System.out.print(cyclic[j]);
You are filling the array of 60 elements [0 to 59] in reverse order i.e. from 59 then 58 and then 57 and so on.
While printing you are printing it from indices 0,1,2 and so on.
This is the 1st thing that you should fix fill them from 0,1,2 or print them from 59,58 and so on.
The reason why you are getting 0 is when you say ,
int[] cyclic = new int[60];
cyclic has memory for 60 ints and all the 60 values are now initialized with 0.
Primitive data types are initialized with 0 when you allocate memory to it.
and that's why "the empty cells at the beginning of array" are showing 0 after printing.
Related
For part of an assignment, I have to create a method that merges 2 arrays into one sorted array in ascending order. I have most of it done, but I am getting a bug that replaces the last element in the array with 0. Has anyone ever run into this problem and know a solution? Heres my code:
public static OrderedArray merge(OrderedArray src1, OrderedArray src2) {
int numLength1 = src1.array.length;
int numLength2 = src2.array.length;
//combined array lengths
int myLength = (numLength1 + numLength2);
// System.out.println(myLength);
OrderedArray mergedArr = new OrderedArray(myLength);
//new array
long[] merged = new long[myLength];
//loop to sort array
int i = 0;
int j = 0;
int k = 0;
while (k < src1.array.length + src2.array.length - 1) {
if(src1.array[i] < src2.array[j]) {
merged[k] = src1.array[i];
i++;
}
else {
merged[k] = src2.array[j];
j++;
}
k++;
}
//loop to print result
for(int x = 0; x < myLength; x++) {
System.out.println(merged[x]);
}
return mergedArr;
}
public static void main(String[] args) {
int maxSize = 100; // array size
// OrderedArray arr; // reference to array
OrderedArray src1 = new OrderedArray(4);
OrderedArray src2 = new OrderedArray(5);
// arr = new OrderedArray(maxSize); // create the array
src1.insert(1); //insert src1
src1.insert(17);
src1.insert(42);
src1.insert(55);
src2.insert(8); //insert src2
src2.insert(13);
src2.insert(21);
src2.insert(32);
src2.insert(69);
OrderedArray myArray = merge(src1, src2);
This is my expected output:
1
8
13
17
21
32
42
55
69
and this is my current output:
1
8
13
17
21
32
42
55
0
While merging two arrays you are comparing them, sorting and merging but what if the length of two arrays is different like Array1{1,3,8} and Array2{4,5,9,10,11}. Here we will compare both arrays and move the pointer ahead, but when the pointer comes at 8 in array1 and at 9 in array2, now we cannot compare ahead, so we will add the remaining sorted array;
Solution:-
(Add this code between loop to sort array and loop to print array)
while (i < numLength1) {
merged[k] = src1.array[i];
i++;
k++;
}
while (j < numLength2) {
merged[k] = src2.array[j];
j++;
k++;
}
To answer your main question, the length of your target array is src1.array.length + src2.array.length, so your loop condition should be one of:
while (k < src1.array.length + src2.array.length) {
while (k <= src1.array.length + src2.array.length - 1) {
Otherwise, you will never set a value for the last element, where k == src1.array.length + src2.array.length - 1.
But depending on how comprehensively you test the code, you may then find you have a bigger problem: ArrayIndexOutOfBoundsException. Before trying to use any array index, such as src1.array[i], you need to be sure it is valid. This condition:
if(src1.array[i] < src2.array[j]) {
does not verify that i is a valid index of src1.array or that j is a valid index of src2.array. When one array has been fully consumed, checking this condition will cause your program to fail. You can see this with input arrays like { 1, 2 } & { 1 }.
This revision of the code does the proper bounds checks:
if (i >= src1.array.length) {
// src1 is fully consumed
merged[k] = src2.array[j];
j++;
} else if (j >= src2.array.length || src1.array[i] < src2.array[j]) {
// src2 is fully consumed OR src1's next is less than src2's next
merged[k] = src1.array[i];
i++;
} else {
merged[k] = src2.array[j];
j++;
}
Note that we do not need to check j in the first condition because i >= src1.array.length implies that j is a safe value, due to your loop's condition and the math of how you are incrementing those variables:
k == i + j due to parity between k's incrementing and i & j's mutually exclusive incrementing
k < src1.array.length + src2.array.length due to the loop condition
Therefore i + j < src1.array.length + src2.array.length
If both i >= src1.array.length and j >= src2.array.length then i + j >= src1.array.length + src2.array.length, violating the facts above.
A couple other points and things to think about:
Be consistent with how you refer to data. If you have variables, use them. Either use numLength1 & numLength2 or use src1.length & src2.length. Either use myLength or use src1.array.length + src2.array.length.
Should a merge method really output its own results, or should the code that called the method (main) handle all the input & output?
Is the OrderedArray class safe to trust as "ordered", and is it doing its job properly, if you can directly access its internal data like src1.array and make modifications to the array?
The best way to merge two arrays without repetitive items in sorted order is that insert both of them into treeSet just like the following:
public static int[] merge(int[] src1, int[] src2) {
TreeSet<Integer> mergedArray= new TreeSet<>();
for (int i = 0; i < src1.length; i++) {
mergedArray.add(src1[i]);
}
for (int i = 0; i < src2.length; i++) {
mergedArray.add(src2[i]);
}
return mergedArray.stream().mapToInt(e->(int)e).toArray();
}
public static void main(String[] argh) {
int[] src1 = {1,17,42,55};
int[] src2 = {8,13,21,32,69};
Arrays.stream(merge(src1,src2)).forEach(s-> System.out.println(s));
}
output:
1
8
13
17
21
32
42
55
69
I'm required to implement a programm that sorts numbers ranging from 0 to 99999 recursively (this is basically Radix sort). The process itself is kinda simpel: The user types in an array that contains those numbers in the main method. Then, the main method calls for the sort-method where I create a two-dimensional array named 'space' with 10 rows and 1 column. Then, I divide every number in the array by the digit, which would be 10.000 in the first run. So, for example, 23456 / 10000 = 2,3456 = 2 (in java), hence, the programm puts this number in space[2][0], so in the second row. Then, we take this entire row and extend it, which is done in the putInBucket-method. We do this in order to make sure that we can put another number into the same row.
We do this for every number that is inside the 'numbers'-array. Then, we want to work with these rows and sort them again by the same principle, but now we take a look at the second digit. We want to do this from left to right, not from right to left. So, if our second row would look like this
[23456, 24567],
we'd want to compare the 3 and the 4, which leads to 23456 < 24567.
We do this with the help of the recursive call at the end of the sort method. Now, this is where I am lost. I simply don't know how to manipulate the digit-variable in order to be able to work with the second, third, ... digit of each number. In the first run, as you see, this can be simply done by dividing through 10.000, but I didn't find a way to go further from here.
Please note: Yes, this is a homework question, hence, I'm only allowed to use primitives here. We didn't go through stuff like math.pow(...) yet. Thanks in advance!
public static int[] sort(int[] numbers, int digit) {
if (numbers.length == 0)
return numbers;
int[][]space = new int[10][1];
int i, j = 0;
for (j = 0; j < numbers.length; j++) {
i = numbers[j] / digit;
space[i][0] = numbers[j];
space[i] = putInBucket(space[i], numbers[j]);
}
for (i = 0; i < space[i].length; i++) {
sort(space[i], digit); //not sure how to work with digit here
}
return ... //not sure what to return here
}
private static int[] putInBucket(int[] bucket, int number) {
int[] bucket_new = new int[bucket.length+1];
for (int i = 1; i < bucket_new.length; i++) {
bucket_new[i] = bucket[i-1];
}
return bucket_new;
}
public static void main (String [] argv) {
int[] numbers = IO.readInts("Numbers: ");
int digit = 10000;
int[] bucket = sort(numbers, digit);
}
To extract the last digit, the remainder operator % is your friend:
123 % 10 == 3
if you haven't covered the % operator yet, you can use
123 % 10 == 123 - (123 / 10 * 10) == 3
To extract another digit, you can first move it to the end with /:
123 / 10 == 12
12 % 10 == 2
You can therefore extract an arbitrary digit using
(number / mask) % 10
where mask ∈ {..., 10000, 1000, 100, 10, 1}.
Extra credit
Radix sort is usually implemented in the binary number system instead because a binary digit (or a sequence thereof) can be extracted without performing a division, which is more efficient:
x % 16 == x & 15;
x \ 16 == x >> 4;
Also, if you are implementing this for real, you'd need a more efficient way to grow buckets (your implementation takes O(n) to add a single element to the bucket, adding n elements to the bucket therefore takes O(n^2), which makes your radix sort slower than insertion sort). Dynamic arrays are usually implemented with a more efficient geometric expansion.
This should work:
public static int[] sort(int[] numbers, int digit) {
if (numbers.length == 0 || digit <= 0)
return numbers;
int[][]space = new int[10][10];
int[] len = new int[10];
int i, j = 0;
for (j = 0; j < numbers.length; j++) {
i = (numbers[j] / digit) % 10;
len[i]++;
for (int k = len[i] - 1; k > 0; k--) {
space[i][k] = space[i][k - 1];
}
space[i][0] = numbers[j];
}
for (i = 0; i < 10; i++) {
int[] bucket = new int[len[i]];
for (int k = 0; k < len[i]; k++)
bucket[k] = space[i][k];
space[i] = sort(bucket, digit / 10);
}
int k = 0;
for (i = 0; i < 10; i++) {
for (j = 0; j < len[i]; j++) {
numbers[k] = space[i][j];
k++;
}
}
return numbers;
}
a) Firstly, space is allocated as having only one column. So, space[i] = bucket will not work.
Instead, you could declare it as int[10][10]. (Note: it will only support max of 10 values in one bucket). Or you may allocate new arrays programmatically. Or of course, a List might be better suited.
b) i = (numbers[j] / digit) % 10;
To get the required digit only. For eg: if the number is 12130, and digit = 1000, we want to set i to 2, not 12.
c) putInBucket replaced with an in-place loop.
d) For each bucket of space, we sort it by one digit lower by calling sort recursively.
e) Finally, the result to be returned (numbers), can be created by looping through space from digit 0 to 9.
Note:
This solution could probably be made better.
I'm trying to increment the following sequence in a for loop (Java):
1, 4, 9, 16, 25 etc the difference increasing by two each time. I tried using 'i+=3 + i' but I know that's wrong since it doesn't take into account that the variable i changes along the sequence.
Any help? Thanks
You could have an increment of i+=k and change k inside the loop in order to change the increment.
int k=1;
for (int i=1;i<1000;i+=k) {
k+=2;
}
If your i is changing, the simple logic is, use another variable that is declared outside the scope of the loop. This will make sure that it is not recreated everytime the loop runs.
int num = 1;
for(int i=1; i<maxValue; num+=2,i+=num){
//Use the value of `i` here, it will be as you wanted.
}
The sequence is to start with j=1 and k=4 and then derive next values of the series n times. The formula as follow:
Initial loop (i=0):
j = 1, k = 4;
Loop (i > 0 less than n):
Repeat below n times:
temp = k;
k = k + (k - j + 2);
j = temp;
print value of j being the series;
I assume that you take n as input from user and then generate the series nth times. Let's look at the following code example
int n = 10;
for(int i = 0, temp = 0, j = 1, k = 4; i < n; i++, temp = k, k += (k-j+2), j = temp) {
System.out.println(j);
}
Assuming that user inputs n = 10, the loop initializes i = 0 and continues until i < n is satisfied. It initializes j = 1 and k = 4 and then execute the body of the loop (printing j) followed by backing up the value of k, calculating new value for k and replacing the old value of j. The output for n = 10 is as follow:
1
4
9
16
25
36
49
64
81
100
Read Series number from the user and generate series based on given number.
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int ans;
for(int i = 1; i <= n; i++){
ans = i * i;
System.out.println(ans);
}
I want to generate 6 different random numbers by using Math.random and store them into an array.
How can I make sure that they are different? I know I need to use for-loop to check the array but how...
This is the range. I only need numbers between 1 and 49.
( 1 + (int) (Math.random() * 49) )
In Java 8:
final int[] ints = new Random().ints(1, 50).distinct().limit(6).toArray();
In Java 7:
public static void main(final String[] args) throws Exception {
final Random random = new Random();
final Set<Integer> intSet = new HashSet<>();
while (intSet.size() < 6) {
intSet.add(random.nextInt(49) + 1);
}
final int[] ints = new int[intSet.size()];
final Iterator<Integer> iter = intSet.iterator();
for (int i = 0; iter.hasNext(); ++i) {
ints[i] = iter.next();
}
System.out.println(Arrays.toString(ints));
}
Just a little messier. Not helped by the fact that it's pretty tedious to unbox the Set<Integer> into an int[].
It should be noted that this solution should be fine of the number of required values is significantly smaller than the range. As 1..49 is quite a lot larger than 6 you're fine. Otherwise performance rapidly degrades.
Create a list containing the numbers 1 to 49.
Create a random number x between 0 and the size of the list, take the number being at index x in the list, and remove it from the list.
Repeat the previous step 5 times. And you're done. Note that java.util.Random has a nextInt(int max) method that you should use instead of Math.random().
Note regarding performance: this solution has an advantage compared to the "try until you get 6 different numbers" various solutions: it runs in a O(n) time. It doesn't matter much for 6 unique numbers out of 50, but if you want to get 48 or 49 unique random numbers out of 50, you'll start seeing a difference, because you might have to generate many random numbers before getting one that isn't already in the set.
EDIT:
to reduce the cost induced by the removal of the elements in the list, you could instead simply replace the element at index x with the last element of the list (and at the second iteration, with the element at size - 2, etc.)
You can use a Set.
Set<Integer> s = new HashSet<>();
while(s.size() != 6){
s.add(1 + (int) (Math.random() * 49));
}
Integer[] arr = s.toArray(new Integer[s.size()]);
This is enough to do this in your case because the number of distinct random numbers is relatively small compared to the size of the range you generate them.
Otherwise I would go with #JBNizet approach.
Generate any 6 numbers (not necessarily different). Order them.
a1 <= a2 <= a3 <= a4 <= a5 <= a6
Now take these 6 numbers
a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5
These 6 are different and random.
The idea of this construct comes from some combinatorial proofs.
Its advantage is that it's simple, fast, and deterministic.
I think the time complexity is O(count*log(count)).
I wonder if it can be improved.
import java.util.TreeMap;
public class Test005 {
public static void main(String[] args) {
int count = 6;
int min = 1;
int max = 49;
// random number mapped to the count of its occurrences
TreeMap<Integer, Integer> mp = new TreeMap<Integer, Integer>();
for (int i=0; i<count; i++){
int d = ( min + (int) (Math.random() * (max-count+1)) );
if (!mp.containsKey(d)){
mp.put(d, 0);
}
mp.put(d, mp.get(d) + 1);
}
// now ensure the output numbers are different
int j = 0;
for (int num : mp.keySet()){
int cnt = mp.get(num);
for (int i=0; i<cnt; i++){
System.out.println(num + j);
j++;
}
}
}
}
I've just came up with a small idea for Java 8-.
Set<Integer> set = new LinkedHashSet<>();
while(set.size() != 6)
set.add(rnd.nextInt(49) + 1);
Instead of checking that the array has no duplicates, you can use a bit more smartness while generating the numbers, such that uniqueness is enforced at the outset.
Create a boolean[] as long as your range (49 entries);
generate a random number from the full range;
put that number into your output array;
"cross out" the corresponding index in the boolean[];
now generate another random number, but curtail the range by one (now 48);
instead of directly using that number as output, scan your boolean[], counting all the non-crossed entries. Stop when you reach the count equal to the random number generated in step 5. The number corresponding to that entry is your output number;
go to step 4.
in your case n=6
public static int[] chooseAny(int n){
int[] lottery = new int[n];
int[] chooseFrom = new int[49];
for(int i=1 ; i <= 49 ; i++)
chooseFrom[i-1] = i;
Random rand = new Random();
int N = 49;
int index;
for(int i=0 ; i < n ; i++){
//pick random index
index = rand.nextInt(N);
lottery[i] = chooseFrom[index];
chooseFrom[index] = chooseFrom[N-1];
N--;
}
return lottery;
}
Just keep generating numbers and adding them to the array as long as they are unique; psuedocode:
num = genNextRand()
For (array length)
If (num not in array)
addToArray()
Repeat while length not equal 6
Create a variable last; initialize it to 0.
Next, in a loop x from 0 to 5, create a random number between last+1 and 49-6+x. Store this number in a list, and set last to the number generated this way.
You will end up with an ordered list of 6 random numbers in the range of 1..49 with no repeats.
That code generate numbers from 6 to 0 and save in ArrayList.
If generated number was duplicated the program generate numbers again.
If generated number is different that number is added.
Code:
private ArrayList<Integer> arraylist = new ArrayList<Integer>();
private Random rand = new Random();
public void insertNumber() {
while (true) {
int i = generateNumber();
if(!isGenerateNumberExists(i)){
addNumber(i);
break;
}
}
}
//Generate numbers
private int generateNumber() {
return rand.nextInt(6);
}
//Confirm if that number exists
private boolean isGenerateNumberExists(int y) {
for (int num : arraylist) {
if (num == y) {
return true;
}
}
return false;
}
//Add number to arrayList
private void addNumber(int x) {
arraylist.add(x);
}
I need to randomly generate an array with 7 slots in Java. All these slots must have a value of at LEAST 1, but combined, have a total value of another defined number. They also all need to be an int value, no 1.5 or 0.9816465684646 numbers.
Example:
int a=10;
int[] ar = new int[7]
ar[0] = 1
ar[1] = 1
ar[2] = 2
ar[3] = 2
ar[4] = 1
ar[5] = 2
ar[6] = 1
I want it to generate something like that, but if int a=15, all the numbers would total 15 in any order
The standard way to generate N random numbers that add to a given sum is to think of your sum as a number line, generate N-1 random points on the line, sort them, then use the differences between the points as your final values. To get the minimum 1, start by subtracting N from your sum, run the algorithm given, then add 1 back to each segment.
public class Rand {
public static void main(String[] args) {
int count = 8;
int sum = 100;
java.util.Random g = new java.util.Random();
int vals[] = new int[count];
sum -= count;
for (int i = 0; i < count-1; ++i) {
vals[i] = g.nextInt(sum);
}
vals[count-1] = sum;
java.util.Arrays.sort(vals);
for (int i = count-1; i > 0; --i) {
vals[i] -= vals[i-1];
}
for (int i = 0; i < count; ++i) { ++vals[i]; }
for (int i = 0; i < count; ++i) {
System.out.printf("%4d", vals[i]);
}
System.out.printf("\n");
}
}
A good way to achieve uniformity is, for example, to fill up a = 15 units into an 8 element array:
Put 1 in each element in the array as this is your requirement, you have now 7 values left to distribute
Roll a random number between 0 and the max index of the array, and add 1 to that element, and subtract 1 from 7. Do this until 7 goes down to zero.
In this way, you'll meet your minimum conditions by having each element have minimum value 1. Then you distribute the remaining totals in a completely random way.
Adding on to what #Kon said, you could use two random numbers rather than one for more randomness. That is:
Fill every element in the array with the value 1
valuesToDistribute = a - array.length-1
randomIndex = Roll a number between 0 and array.length-1
randomValue = Roll a number between 1 and valuesToDistribute
Add to randomIndex the value randomValue
Subtract randomValue from valuesToDistribute
Repeat until valuesToDistribute = 0
My java is horrible, so I'm not providing the actual code here, as it would probably be wrong. I've done this exact thing in SQL before though, so I know it works...
Let Y be the Total value you want the elements to add up to
Begin a loop with variable Z going from 1 to X where X is the number elements in your array (here called AR)
In the loop, set AR(Z) to a random number between 1 and Y-X+Z
Subtract the new value from Y, so Y = Y - AR(Z)
End loop : back to step 2, advancing Z by 1