Multiplying, dividing numbers with a specific format - java

Today, I have a question about multiplying, dividing numbers with a specific format. The format is like this: I will make the number into a linked list, and do the operation with this linked list. For example, if I want to multiply 1234567 and 7890123, I will make these two numbers into linked list by cutting the numbers into 3 digits at one time, like 1,234,567 and 7,890,123. Then, I will put one chunk at one node(1, 234, 567 are three chunks, and they all go into different nodes) for every numbers. Now, the problem is, I have to multiply, divide, and get the quotient and remnant of the operation between the two numbers without changing them back to the real 'numbers'. The operation must be done with the form of linked list. So, for the multiplying, I've thought 'let's multiply the numbers in each node first, and put the zeros in the back to adjust the cipher, then add them all to finish the operation. for example, if I want to multiply 1,234 and 5,678, I will do (234*678 + (1*678)000 + (5*234)000 + (1*5)000,000). But, I can't be certain this method is right, And I can't imagine about the dividing and getting the quotient and remnant part. So, please help..!

Related

Generating random integers uniformly in log space

I want to generate random integers which are uniformly distributed in log space. That is, the log of the values of will be uniformly distributed.
A normal uniformly distributed unsigned int will have 75% of its magnitudes above 1 billion, and something like 99.98% above 1 million, so small values are underrepresented. A uniform value from log space would have the same number of values in the range 4-8, as 256-512, for example.
Ignoring negative values for now, one way I can think of is something like:
Random r = new Random();
return (int)Math.pow(2, r.nextDouble() * 31);
That should generate a 31-bit log-uniformly distributed. It's not going to be fast though, with an pow() operation in there and to introduce floating point values to generate integers is a bit of a smell. Furthermore, a lot of the range of double is lost by Random.nextDouble() and it is not clear to me if this code can even generate all 2^31-1 positive integer values.
Better solutions welcome.
There are two similar solutions below which both involve filling the integer with random bits, then shifting a random number of bits to the right. Something like:
int number = rand.nextInt(Integer.MAX_VALUE) >> rand.nextInt(Integer.SIZE);
This has two types of bias:
Step-wise bias
This produces sort of a stepwise log distributed value, not a smooth one. In particular, the right shift by a random value in [0,31], means there are 31 equally probable "sizes" of integers, and every value in that range is equally probable. Since there are 2^N values in range N, the values in one range are twice as probable as the ones in the next - so you get log behavior between the ranges, but the ranges themselves are flat.
I don't know of an easy way to get rid of this bias.
Top bit bias
A second form of bias occurs because the MSB is not always 1 (e.g., even a shift amount of 10, doesn't necessary produce a 31-10=21 bit value, there is an additional distortion. In effect, the ranges overlap. The value 1 is not just present (with p(1)=.5) for a shift amount of 30, but also for shifts of 29 (p(1)=0.25), 28 (p(1)=.125), and so on. That effect cancels out for smaller values (i.e., if you look at shift amounts of 30 and 29 only, 1 seems like it is 3x more likely than 2, rather than the predicted value of 2x, but once you look at more values it converges. It doesn't cancel out for large values, however, which is why you see the 20:32207 bucket be smaller than the others in #sprinter's answer.
I think this form of bias can pretty easily be removed simply by forcing the top bit to zero, so something like:
(r.nextInt(0x40000000) | 0x40000000) >> r.nextInt(31)
This has a couple of other tweaks - it a max of 2^30 for the rand, which is faster (special case for powers of 2 in nextInt(int) code), since we never want the second-from-MSB bit set anyway (we force it to 1). This also eliminates a microscopic additional source of bias which is that Integer.MAX_VALUE could never be generated, so one value is missing from full representation.
It shifts by [0,31) bits so you never get zero, if you want zeros too, change that to shift by [0,32) bits and you'll get zeros equal in frequency to ones (technically not log-distributed anymore, but useful in many cases). Another approach is to subtract one from the final value to get zeros (at the cost of never getting Integer.MAX_VALUE).
Incorrect answer provided for information only. This does not satisfy OP's requirements for the reasons given in the question.
int number = rand.nextInt(Integer.MAX_VALUE) >> rand.nextInt(Integer.SIZE);
My informal test of that seems to indicate there is the expected skew. I generated 1M numbers this way and had the following distribution of the log (ignoring zeros)
0:46819
1:47045
2:40663
3:44001
4:45306
5:43802
6:46447
7:43355
8:47366
9:42747
10:46387
11:43899
12:45179
13:45496
14:44431
15:46751
16:43055
17:47127
18:41243
19:41837
20:32207
21:11965

Representing large numbers using linked lists and performing operations

I need to store two extremely large numbers (Strings, since they won't fit in int) in two linked lists, add them and then display the result (again, a String).
I can store the numbers directly into the list.
312312 can be stored as 2->1->3->2->1->3 (actual number will be extremely long)
111119 can be stored as 9->1->1->1->1->1
Then I can add them
11->2->4->3->2->4
Normally I could do 11*10^0 + 2*10^1 +...+ 4*10^5 and get 423431 but all those operations (multiplication, addition and exponentiation) would again be integer operations and since the actual numbers are going to be extremely big, int or long won't support the operations. The final result has to be a string.
So I need a way to convert 11->2->4->3->2->4 into 423431 without using int. Also, I cannot use BigInteger. Can anyone help me?
Well, first thing you need to do is implement carry.
For each digit (that is >= 10), you need to increase the next digit by that digit /10 and set that digit to that digit %10.
So 11->2->... becomes 1->3->....
Then to actually produce the string.
For the most performant option, I suggest StringBuilder.
Just append each digit in the linked-list, then just reverse().toString() (since you started with the smallest number).
Think about how you would do it by hand on paper. If the sum of a pair digits is greater than 9 you write down a carry digit of 1, which you add into the sum of the next pair of digits.
In a computer program you can use a local variable for that: add digits from first and last numbers and the carry from earlier, if sum is greater than.. set carry to 1, else set carry to 0, move on to the next pair...

Finding and storing combinations

I have a n-digit number composed of 1's only. I want to replace 1's with 0's in all possible combinations and store the combinations in an array.
How do I find all combinations?
I was thinking of starting with one zero and then increasing the number if zeroes that will replace 1's.
If there are 2 zeroes, for example, then i will keep the position of one zero fixed and move the other, till it reaches the end then i'd do the same for the other zero. But then i'll have to root out the repeated combinations.
Basically, this is getting complicated. I want to know a better way to find combinations!
You are simply trying to generate n-digit binary numbers. It means that you can generate 2^n different numbers. So here you go:
Firstly, calculate 2^n.
Implement a loop, starting from 0 and ending at 2^n.
For every loop variable, take the variable as a decimal and convert
it to binary and append some leading zeros (if necessary) to make it
length of n.
Add the binary to your permutations array.

multiply 2 arraysLists together in java

So I have an two arrayLists that represent two numbers. This is so I don't have to use BigInt. so for example
ArrayList<Integer> LargeInt = [2,3,6,4] would really equal 2,364
ArrayList<Integer> LargeInt2 = [8,7,9,4,6] would be 87,946
my goal is to figure out a way to multiply the two numbers and make the answer to a string. I know that multiplying two numbers would need to be put into another array before put into a string so it won't crash with larger numbers. I also know it will be one for loop put into another. But i am finding it difficult to make a code that multiplies the two numbers. the two arrays being multiplied can be any number.
Assuming that this is homework, here is a no-code explanation of what you need to do:
Define a class that wraps ArrayList<Integer>; let's say you call it ArrayInt
Define an operation that adds two ArrayInts together, and returns a third ArrayInt that equals their sum. You can do it digit by digit, taking care of a possible carry into an extra digit, so you need to size your result accordingly.
Define an operation that multiplies your number by a power of ten by adding zeros to the array list. Again, the operation should return a new ArrayInt, rather than modifying the current one
Define an operation that multiplies a number by a single digit. You can use multiplication, or a simple loop that uses addition. The loop would not run more than nine times, so it shouldn't be too bad.
Combine the three operations that you have (addition, multiplication by a digit, and multiplication by a power of ten) into a simple multiplication algorithm that you learned in the elementary school.

Performing arithmetic operations on isolated arraylist elements

I am looking for a clear explanation to my question (NOT looking for code), but if a bit of code helps to explain yourself, then please do.. thank you :)
Question:
-using Java
-Main class asks user for 2 integer inputs, then places them into 2 arraylists, of type integer. Each digit is broken up and stored in its own index, so it is its own "element", so to speak.
For example, with my code right now, it goes something like this:
"Please enter an integer:"
688
"Please enter another integer:"
349
At this point now, internally, I have stored the input as 2 arraylists, that look like this:
ArrayList1: [6, 8, 8]
ArrayList2: [3, 4, 9]
Now, lets say I want to perform some addition, such as ArrayList1 + ArrayList2.
I'll probably go ahead and create a temporary 'result' arraylist, then move that answer over to arraylist1 when my calculation is complete.
But the part I am having trouble with, is coming up with a systematic clear way to add the arraylists together. Keep in mind that this example uses an arraylist which represents an integer of length 3, but this could be anything. I could, for example, have an arraylist with 50 elements, such as [2, 4, 4, 3, 7, 3, 6, 3,.............] which could represent a huge number in the trillions, etc.
Think about how you would do grade-school addition. You'd start up by lining up the numbers like this:
1 3 7
+ 4 5
-----------
Then, you'd add the last two digits to get
1 3 7
+ 4 5
-----------
2
And you'd have a carry of 1. You then add the next two digits, plus the carry:
1 3 7
+ 4 5
-----------
8 2
Now you have carry 0, so you can add the last digit and the missing digit to get
1 3 7
+ 4 5
-----------
1 8 2
The general pattern looks like this: starting from the last digit of each array, add the last two numbers together to get a sum and a carry. Write the units digit of the sum into the resulting array, then propagate the carry to the next column. Then add the values in that column (plus the carry) together, and repeat this process across the digits. Once you have exhausted all of the digits in one of the numbers, continue doing the sum, but pretend that there's a 0 as the missing digit. Once you have processed all the digits, you will have the answer you're looking for.
Hope this helps!
If you store digits backwards, your arrays will be much easier to manipulate, because their ones, tens, hundreds, etc. will be aligned with each other (i.e. they will be sitting at the same index).
You could then implement the addition the same way they teach in the elementary school: go through arrays of digits one by one, add them, check for digit overflow (>=10), and pay attention to the carry flag (result digit is (a+b) % 10, carry flag is (a+b)/10). If the carry flag is not zero when you are done with the addition, and there are no additional digits remaining on either side, add the carry flag to the end of the result array.
The only remaining issue is displaying the lists. You can do it with a simple backward loop.
P.S. If you would like to double-check your mulch-trilion calculation against something that is known to work, use BigInteger to compute the expected results, and check your results against theirs.
Think of an arraylist as a storage container. It can hold items in it that are of type "integer", but it's type is still "storage container". You can't perform math on these type of objects--only their contents.
you have
list1
list2
and need an extra variable
int carry
then
1 do add(0,0) on short list, so that at the end two lists have same length.
2 reversely loop the two list.
sum=(carry+(e1+e2))
set e1 (list1 element) = sum%10,
carry = sum/10,
till the first element.
3 if carry==1, list1.add(0,1)
now list1 stores the result.
Note, step1 is not a must. it could be done in loop by checking the short list's length.

Categories