I'm writing my own custom BigInteger class in Java, and want to parse Integers in the constructor of my class. So question is, how can I add each digit of my number n to my vector properly, keeping the correct sequence? In other words, how can I add each digit to it like if I were adding them into the stack?
E.g. for n = 1234 i need to add this like 1 2 3 4 to my vector.
That's what I already have:
class VeryLong {
Vector<Integer> A = new Vector<Integer>();
VeryLong(int n) {
while (n > 0) {
// A.push(n % 10)
n /= 10;
}
}
There goes another problem, I need to overload constructor of the class to create an instance of VeryLong from int and long. Here is my code:
private ArrayList<Long> A = new ArrayList<>();
private VeryLong(int n) {
while (n > 0) {
A.add(long()(n % 10));
n /= 10;
}
while (!A.isEmpty()) {
System.out.println(A.get(0));
A.remove(0);
}
}
private VeryLong(long n) {
while (n > 0) {
A.add(n % 10);
n /= 10;
}
while (!A.isEmpty()) {
System.out.println(A.get(0));
A.remove(0);
}
}
If I define ArrayList of Long there goes error in constructor first constuctor. Similarly, it's error in add() method in second, if i defina A as Vector<Integer> A = new Vector<Integer>();. How can I fix it?
By taking a quick look at the Javadoc, there is no push method. However, what I think you are looking for is the add method, which adds the given item to the end of the Vector (or if an additional integer is provided, at that index of the Vector). In your example, this would look like
class VeryLong {
Vector<Integer> A = new Vector<Integer>();
VeryLong(int n) {
while (n > 0) {
A.add(0, n % 10);
n /= 10;
}
}
In this case, I wrote A.add(0, n % 10); since you want the "less significant" digits towards the end. Each successive digit added will push the existing elements to the "right" or end of the list in this case. This should solve your problem. :)
As acarlstein pointed out, using a Vector in this case is not necessarily recommended. Quoting from the Vector Javadoc,
As of the Java 2 platform v1.2, this class was retrofitted to implement the List interface, making it a member of the Java Collections Framework. Unlike the new collection implementations, Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.
Related
I'm trying to implement a recursive shuffle method that will take nlog(n) time but am having major difficulty, given I am restricted to a single parameter and can't include the size of n in my params when calling the recursive method. I looked at the structure of a similar shuffling problem with different parameters and got the idea for how to structure the shuffling using Random, but I've spent way too much time trying to figure out how to implement this.
If I could implement the method taking two parameters, a and n, I don't feel like I would be having so much trouble. My question is, should I have n be a global variable for the purpose of decrementing it? How would I go about either decrementing n for the purpose of managing the recursion, or modify a somehow to eventually end the recursion?
*Also, would declaring the objects in the indices like this cause a referential issue? If so, how would I fix this? I tried clone and couldn't get it to function within the requirements of the problem.
public static void shuffle(Object[] a) {
int n = a.length;
if (n == 0) {
return;
}
int d = (int) (Math.random() * (n-1)); //random index
Object c = a[n - 1]; //value at n-1
a[n-1]= a[d]; //a[n-1] index = val at rand index
a[d] = c; //val at rand index set to val at n-1
shuffle(a);
shuffle(a);
}
***What I've started to implement which looks a lot more like it would work in nlogn time complexity, but not sure if it's right or how it would need to be finished...
public static void shuffle(Object[] a){
if(a.length == 1) return; //return if length = 1: base case
Object[] b = new Object[a.length/2]();
Random rand = new Random(0,a.length); //random index to swap
for(int i = 0; i < b.length; i++){
b[i] = a[rand]; //how do I make sure no index of a is
//repeated?
}
shuffle(b); //recursively call shuffle on b, dividing size by 2
for(int i = 0; i < a.length; i++){
a[i] = b[i]; //copy values from b to a (I guess you could use arraycopy)
}
}
If I could implement the method taking two parameters, a and n, I don't feel like I would be having so much trouble. My question is, should I have n be a global variable for the purpose of decrementing it?
It does not have to be a global variable. You can create a class inside your method as follows. This should support any requirement that the implementation must be kept inside the publicly available method. Of course, you'll need to decide if this is in accordance with any other restrictions not mentioned in your question. I leave the actual algorithm up to you. But the array can be shuffled in-place in O(n).
public static void shuffle(Object[] a) {
class Shuffle {
private void recShuffle(Object[] ob, int n) {
// your shuffle algorithm here
}
}
Shuffle s = new Shuffle();
int n = ... // up to you
s.recShuffle(a, n);
}
So I was able to figure out a way to solve it this morning by implementing a helper method and moving most of my code there in case anyone ever comes across a problem like this:
//calls helper shuffle method
public static void shuffle(Object[] a) {
int n = a.length;
helperShuffle(a, n);
}
public static Object[] helperShuffle(Object[] a, int n) {
if (n <= 1)
return a; //base case: size of array is 1
Random rand = new Random(); //declare new random
int d = (rand.nextInt(n)); //random index < n
Object c = a[n - 1]; //value at n-1
a[n-1]= a[d]; //a[n-1] index = val at rand index
a[d] = c; //val at rand index set to val at n-1
return helperShuffle(a,n-1);
}
So I have some code which returns the min and max of an array in an object called min max. My question is inside the for loop do we need to create a new MinMax object at each iteration. Or could we just update MinMax's member variables like so:
globalMinMax.largest = Math.min(globalMinMax.smallest, localMinMax.smallest);
globalMinMax.smallest = Math.max(globalMinMax.largest, localMinMax.largest));
Instead of creating a new MinMax each time like we do on the starred line in the code below
private static class MinMax {
public Integer smallest;
public Integer largest;
public MinMax(Integer smallest, Integer largest) {
this.smallest = smallest;
this.largest = largest;
}
private static MinMax minMax(Integer a, Integer b) {
return Integer.compare(b, a) < 0 ? new MinMax(b, a) : new MinMax(a, b);
}
}
public static MinMax findMinMax(List<Integer> A) {
if (A.size() <= 1) {
return new MinMax(A.get(0), A.get(0));
}
MinMax globalMinMax = MinMax.minMax(A.get(0), A.get(1));
// Process two elements at a time.
for (int i = 2; i + 1 < A.size(); i += 2) {
MinMax localMinMax = MinMax.minMax(A.get(i), A.get(i + 1));
**********Do we need to create a new object here?*****
globalMinMax
= new MinMax(Math.min(globalMinMax.smallest, localMinMax.smallest),
Math.max(globalMinMax.largest, localMinMax.largest));
}
// If there is odd number of elements in the array, we still
// need to compare the last element with the existing answer.
if ((A.size() % 2) != 0) {
globalMinMax
= new MinMax(Math.min(globalMinMax.smallest, A.get(A.size() - 1)),
Math.max(globalMinMax.largest, A.get(A.size() - 1)));
}
return globalMinMax;
}
This code is too complex for what its doing. You should use the MinMax class you've generated to act as a store of the min/max of a list but should not use it during computation.
Finding the minimum/maximum of a list is as simple as:
int minimum = A.get(0);
int maximum = A.get(0);
for(int i=1; i < A.size(); i++){
if(A.get(i) < minimum) minimum = A.get(i);
if(A.get(i) > maximum) maximum = A.get(i);
}
return new MinMax(minimum, maximum);
If you want to incorporate the MinMax class more into the your overall program you can add a static method to the class called something like generateMinMaxFromList that will statically generate minMax objects from supplied Integer lists.
Updating globalMinMax would be the better solution of the two provided if the data is not accessed in a multithreaded environment. You also need not spin up a lot of objects (especially inside a loop) just to find the minimum and maximum value. this can cause overhead when the source collection you're iterating over has a lot of elements.
However, there is one situation in which you'll want to create a new instance of MinMax objects within each iteration. This would be when you spin up multiple threads to act on the data.
Note - the first check within the MinMax method would throw an exception if the list passed in is empty. thus make a check for A.size() == 0 as the first statement within the method and perform the appropriate action.
I have a program that sums the common elements of two arrays. For that I used two for loops and if I have three then I could use three for loops. But how to sum the common elements of n number of arrays where n is coming during run time.
I don't know how to change the number of loops during run time or is there any other relevant concept for this ?
Here is the code I've tried for summing twoarrays:
import java.util.Scanner;
public class Sample {
public static void main(String... args)
{
Scanner sc=new Scanner(System.in);
int arr1[]={1,2,3,4,5},arr2[]={4,5,6,7,8},sum=0;
for (int i=0;i<arr1.length;i++)
{
for (int j=0;j<arr2.length;j++)
{
if (arr1[i]==arr2[j])
{
sum+=(arr1[i]);
}
}
}
}
}
There can be different implementation for that. You can use the following approach. Here is the pseudo code
use a 2D array to store the array. if the number of array is n and size is m then the array will be input[n][m]
Use a ArrayList commonItems to store the common items of. Initiate it with the elements of input[0]
Now iterate through the array for i = 1 to n-1. compare with every input[i], store only the common items of commonItems and input[i] at each step. You can do it by converting the input[i] into a list and by using retainAll method.
At the end of the iteration the commonItem list will contains the common numbers only. Now sum the value of this list.
There is actually a more general method, that also answers the question "how to change the number of loops during run time?".
The general question
We are looking for a way to implement something equivalent to this:
for (i1 = 0; i1 < k1; i1++) {
for (i2 = 0; i2 < k2; i2++) {
for (i3 = 0; i3 < k3; i3++) {
...
for (in = 0; in < kn; in++) {
f(x1[i1], x2[i2], ... xn[in]);
}
...
}
}
}
where, n is given at runtime and f is a function taking a list of n parameters, processing the current n-tuple.
A general solution
There is a general solution, based on the concept of recursion.
This is one implementation that produces the desired behavior:
void process(int idx, int n, int[][] x, int[] k, Object[] ntuple) {
if (idx == n) {
// we have a complete n-tuple,
// with an element from each of the n arrays
f(ntuple);
return;
}
// this is the idx'th "for" statement
for (int i = 0; i < k[idx]; i++) {
ntuple[idx] = x[idx][i];
// with this recursive call we make sure that
// we also generate the rest of the for's
process(idx + 1, n, x, k, ntuple);
}
}
The function assumes that the n arrays are stored in a matrix x, and the first call should look like this:
process(0, n, x, k, new Object[n]);
Practical considerations
The solution above has a high complexity (it is O(k1⋅k2⋅..⋅kn)), but sometimes it is possible to avoid going until the deepest loop.
Indeed, in the specific problem mentioned in this post (which requires summing common elements across all arrays), we can skip generating some tuples e.g. if already x2[i2] ≠ x1[i1].
In the recursive solution, those situations can easily be pruned. The specific code for this problem would probably look like this:
void process(int idx, int n, int[][] x, int[] k, int value) {
if (idx == n) {
// all elements from the current tuple are equal to "value".
// add this to the global "sum" variable
sum += value;
return;
}
for (int i = 0; i < k[idx]; i++) {
if (idx == 0) {
// this is the outer "for", set the new value
value = x[0][i];
} else {
// check if the current element from the idx'th for
// has the same value as all previous elements
if (x[idx][i] == value) {
process(idx + 1, n, x, k, value);
}
}
}
}
Assuming that the index of the element is not important: a[1] = 2 and a[5] = 2, you only need two nested loops.
First you need to put n-1 arrays in a list of sets. Then loop over nth array and check if each element exists in all of the sets in the list. If it does exist then add to total.
I have developed a code for expressing the number in terms of the power of the 2 and I am attaching the same code below.
But the problem is that the expressed output should of minimum length.
I am getting output as 3^2+1^2+1^2+1^2 which is not minimum length.
I need to output in this format:
package com.algo;
import java.util.Scanner;
public class GetInputFromUser {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n;
Scanner in = new Scanner(System.in);
System.out.println("Enter an integer");
n = in.nextInt();
System.out.println("The result is:");
algofunction(n);
}
public static int algofunction(int n1)
{
int r1 = 0;
int r2 = 0;
int r3 = 0;
//System.out.println("n1: "+n1);
r1 = (int) Math.sqrt(n1);
r2 = (int) Math.pow(r1, 2);
// System.out.println("r1: "+r1);
//System.out.println("r2: "+r2);
System.out.print(r1+"^2");
r3 = n1-r2;
//System.out.println("r3: "+r3);
if (r3 == 0)
return 1;
if(r3 == 1)
{
System.out.print("+1^2");
return 1;
}
else {
System.out.print("+");
algofunction(r3);
return 1;
}
}
}
Dynamic programming is all about defining the problem in such a way that if you knew the answer to a smaller version of the original, you could use that to answer the main problem more quickly/directly. It's like applied mathematical induction.
In your particular problem, we can define MinLen(n) as the minimum length representation of n. Next, say, since we want to solve MinLen(12), suppose we already knew the answer to MinLen(1), MinLen(2), MinLen(3), ..., MinLen(11). How could we use the answer to those smaller problems to figure out MinLen(12)? This is the other half of dynamic programming - figuring out how to use the smaller problems to solve the bigger one. It doesn't help you if you come up with some smaller problem, but have no way of combining them back together.
For this problem, we can make the simple statement, "For 12, it's minimum length representation DEFINITELY has either 1^2, 2^2, or 3^2 in it." And in general, the minimum length representation of n will have some square less than or equal to n as a part of it. There is probably a better statement you can make, which would improve the runtime, but I'll say that it is good enough for now.
This statement means that MinLen(12) = 1^2 + MinLen(11), OR 2^2 + MinLen(8), OR 3^2 + MinLen(3). You check all of them and select the best one, and now you save that as MinLen(12). Now, if you want to solve MinLen(13), you can do that too.
Advice when solo:
The way I would test this kind of program myself is to plug in 1, 2, 3, 4, 5, etc, and see the first time it goes wrong. Additionally, any assumptions I happen to have thought were a good idea, I question: "Is it really true that the largest square number less than n will be in the representation of MinLen(n)?"
Your code:
r1 = (int) Math.sqrt(n1);
r2 = (int) Math.pow(r1, 2);
embodies that assumption (a greedy assumption), but it is wrong, as you've clearly seen with the answer for MinLen(12).
Instead you want something more like this:
public ArrayList<Integer> minLen(int n)
{
// base case of recursion
if (n == 0)
return new ArrayList<Integer>();
ArrayList<Integer> best = null;
int bestInt = -1;
for (int i = 1; i*i <= n; ++i)
{
// Check what happens if we use i^2 as part of our representation
ArrayList<Integer> guess = minLen(n - i*i);
// If we haven't selected a 'best' yet (best == null)
// or if our new guess is better than the current choice (guess.size() < best.size())
// update our choice of best
if (best == null || guess.size() < best.size())
{
best = guess;
bestInt = i;
}
}
best.add(bestInt);
return best;
}
Then, once you have your list, you can sort it (no guarantees that it came in sorted order), and print it out the way you want.
Lastly, you may notice that for larger values of n (1000 may be too large) that you plug in to the above recursion, it will start going very slow. This is because we are constantly recalculating all the small subproblems - for example, we figure out MinLen(3) when we call MinLen(4), because 4 - 1^2 = 3. But we figure it out twice for MinLen(7) -> 3 = 7 - 2^2, but 3 also is 7 - 1^2 - 1^2 - 1^2 - 1^2. And it gets much worse the larger you go.
The solution to this, which lets you solve up to n = 1,000,000 or more, very quickly, is to use a technique called Memoization. This means that once we figure out MinLen(3), we save it somewhere, let's say a global location to make it easy. Then, whenever we would try to recalculate it, we check the global cache first to see if we already did it. If so, then we just use that, instead of redoing all the work.
import java.util.*;
class SquareRepresentation
{
private static HashMap<Integer, ArrayList<Integer>> cachedSolutions;
public static void main(String[] args)
{
cachedSolutions = new HashMap<Integer, ArrayList<Integer>>();
for (int j = 100000; j < 100001; ++j)
{
ArrayList<Integer> answer = minLen(j);
Collections.sort(answer);
Collections.reverse(answer);
for (int i = 0; i < answer.size(); ++i)
{
if (i != 0)
System.out.printf("+");
System.out.printf("%d^2", answer.get(i));
}
System.out.println();
}
}
public static ArrayList<Integer> minLen(int n)
{
// base case of recursion
if (n == 0)
return new ArrayList<Integer>();
// new base case: problem already solved once before
if (cachedSolutions.containsKey(n))
{
// It is a bit tricky though, because we need to be careful!
// See how below that we are modifying the 'guess' array we get in?
// That means we would modify our previous solutions! No good!
// So here we need to return a copy
ArrayList<Integer> ans = cachedSolutions.get(n);
ArrayList<Integer> copy = new ArrayList<Integer>();
for (int i: ans) copy.add(i);
return copy;
}
ArrayList<Integer> best = null;
int bestInt = -1;
// THIS IS WRONG, can you figure out why it doesn't work?:
// for (int i = 1; i*i <= n; ++i)
for (int i = (int)Math.sqrt(n); i >= 1; --i)
{
// Check what happens if we use i^2 as part of our representation
ArrayList<Integer> guess = minLen(n - i*i);
// If we haven't selected a 'best' yet (best == null)
// or if our new guess is better than the current choice (guess.size() < best.size())
// update our choice of best
if (best == null || guess.size() < best.size())
{
best = guess;
bestInt = i;
}
}
best.add(bestInt);
// check... not needed unless you coded wrong
int sum = 0;
for (int i = 0; i < best.size(); ++i)
{
sum += best.get(i) * best.get(i);
}
if (sum != n)
{
throw new RuntimeException(String.format("n = %d, sum=%d, arr=%s\n", n, sum, best));
}
// New step: Save the solution to the global cache
cachedSolutions.put(n, best);
// Same deal as before... if you don't return a copy, you end up modifying your previous solutions
//
ArrayList<Integer> copy = new ArrayList<Integer>();
for (int i: best) copy.add(i);
return copy;
}
}
It took my program around ~5s to run for n = 100,000. Clearly there is more to be done if we want it to be faster, and to solve for larger n. The main issue now is that in storing the entire list of results of previous answers, we use up a lot of memory. And all of that copying! There is more you can do, like storing only an integer and a pointer to the subproblem, but I'll let you do that.
And by the by, 1000 = 30^2 + 10^2.
In an array first we have to find whether a desired number exists in that or not?
If not then how will I find nearer number to the given desired number in Java?
An idea:
int nearest = -1;
int bestDistanceFoundYet = Integer.MAX_INTEGER;
// We iterate on the array...
for (int i = 0; i < array.length; i++) {
// if we found the desired number, we return it.
if (array[i] == desiredNumber) {
return array[i];
} else {
// else, we consider the difference between the desired number and the current number in the array.
int d = Math.abs(desiredNumber - array[i]);
if (d < bestDistanceFoundYet) {
// For the moment, this value is the nearest to the desired number...
bestDistanceFoundYet = d; // Assign new best distance...
nearest = array[i];
}
}
}
return nearest;
Another common definition of "closer" is based on the square of the difference. The outline is similar to that provided by romaintaz, except that you'd compute
long d = ((long)desiredNumber - array[i]);
and then compare (d * d) to the nearest distance.
Note that I've typed d as long rather than int to avoid overflow, which can happen even with the absolute-value-based calculation. (For example, think about what happens when desiredValue is at least half of the maximum 32-bit signed value, and the array contains a value with corresponding magnitude but negative sign.)
Finally, I'd write the method to return the index of the value located, rather than the value itself. In either of these two cases:
when the array has a length of zero, and
if you add a "tolerance" parameter that bounds the maximum difference you will consider as a match,
you can use -1 as an out-of-band value similar to the spec on indexOf.
//This will work
public int nearest(int of, List<Integer> in)
{
int min = Integer.MAX_VALUE;
int closest = of;
for (int v : in)
{
final int diff = Math.abs(v - of);
if (diff < min)
{
min = diff;
closest = v;
}
}
return closest;
}
If the array is sorted, then do a modified binary search. Basically if you do not find the number, then at the end of search return the lower bound.
Pseudocode to return list of closest integers.
myList = new ArrayList();
if(array.length==0) return myList;
myList.add(array[0]);
int closestDifference = abs(array[0]-numberToFind);
for (int i = 1; i < array.length; i++) {
int currentDifference= abs(array[i]-numberToFind);
if (currentDifference < closestDifference) {
myList.clear();
myList.add(array[i]);
closestDifference = currentDifference;
} else {
if(currentDifference==closestDifference) {
if( myList.get(0) !=array[i]) && (myList.size() < 2) {
myList.add(array[i]);
}
}
}
}
return myList;
Array.indexOf() to find out wheter element exists or not. If it does not, iterate over an array and maintain a variable which holds absolute value of difference between the desired and i-th element. Return element with least absolute difference.
Overall complexity is O(2n), which can be further reduced to a single iteration over an array (that'd be O(n)). Won't make much difference though.
Only thing missing is the semantics of closer.
What do you do if you're looking for six and your array has both four and eight?
Which one is closest?
int d = Math.abs(desiredNumber - array[i]);
if (d < bestDistanceFoundYet) {
// For the moment, this value is the nearest to the desired number...
nearest = array[i];
}
In this way you find the last number closer to desired number because bestDistanceFoundYet is constant and d memorize the last value passign the if (d<...).
If you want found the closer number WITH ANY DISTANCE by the desired number (d is'nt matter), you can memorize the last possibile value.
At the if you can test
if(d<last_d_memorized){ //the actual distance is shorter than the previous
// For the moment, this value is the nearest to the desired number...
nearest = array[i];
d_last_memorized=d;//is the actual shortest found delta
}
A few things to point out:
1 - You can convert the array to a list using
Arrays.asList(yourIntegerArray);
2 - Using a list, you can just use indexOf().
3 - Consider a scenario where you have a list of some length, you want the number closest to 3, you've already found that 2 is in the array, and you know that 3 is not. Without checking the other numbers, you can safely conclude that 2 is the best, because it's impossible to be closer. I'm not sure how indexOf() works, however, so this may not actually speed you up.
4 - Expanding on 3, let's say that indexOf() takes no more time than getting the value at an index. Then if you want the number closest to 3 in an array and you already have found 1, and have many more numbers to check, then it'll be faster to just check whether 2 or 4 is in the array.
5 - Expanding on 3 and 4, I think it might be possible to apply this to floats and doubles, although it would require that you use a step size smaller than 1... calculating how small seems beyond the scope of the question, though.
// paulmurray's answer to your question is really the best :
// The least square solution is way more elegant,
// here is a test code where numbertoLookFor
// is zero, if you want to try ...
import java.util.* ;
public class main {
public static void main(String[] args)
{
int[] somenumbers = {-2,3,6,1,5,5,-1} ;
ArrayList<Integer> l = new ArrayList<Integer>(10) ;
for(int i=0 ; i<somenumbers.length ; i++)
{
l.add(somenumbers[i]) ;
}
Collections.sort(l,
new java.util.Comparator<Integer>()
{
public int compare(Integer n1, Integer n2)
{
return n1*n1 - n2*n2 ;
}
}
) ;
Integer first = l.get(0) ;
System.out.println("nearest number is " + first) ;
}
}
int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();
boolean arrayContainsNumber =
new HashSet(Arrays.asList(somenumbers))
.contains(numbertoLookfor);
It's fast, too.
Oh - you wanted to find the nearest number? In that case:
int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();
ArrayList<Integer> l = new ArrayList<Integer>(
Arrays.asList(somenumbers)
);
Collections.sort(l);
while(l.size()>1) {
if(numbertoolookfor <= l.get((l.size()/2)-1)) {
l = l.subList(0, l.size()/2);
}
else {
l = l.subList(l.size()/2, l.size);
}
}
System.out.println("nearest number is" + l.get(0));
Oh - hang on: you were after a least squares solution?
Collections.sort(l, new Comparator<Integer>(){
public int compare(Integer o1, Integer o2) {
return (o1-numbertoLookFor)*(o1-numbertoLookFor) -
(o2-numbertoLookFor)*(o2-numbertoLookFor);
}});
System.out.println("nearest number is" + l.get(0));