Multiplying bignums recursively - c

I'm having some trouble figuring out how to multiply bignums recursively. For this problem, I have to input two strings using fgets and if the string consists of entirely digits, then I am to add the two "numbers" together recursively. I was able to do this part.
The next part is to then multiply the first number input from fgets by a character d, which is supposed to represent the numbers 2-9. I had to do this recursively as well. Lastly, the part I am stuck on is figuring out how to multiply these two numbers recursively.
For adding the two bignums together, I wrote a function that essentially traverses the numbers from right to left, adding the numbers as the recursion progresses and storing the result in a character array that grows over the time of the function. So essentially, my resultant array is in reverse order, meaning that the first element of my array is actually not the first number of the sum, but the last. However, I solved this problem by printing the elements in reverse order using a for loop.
For my recursive multiplication with a char d ranging from 2-9, I had a similar algorithm with the result in reverse order of the actual product, but again, I was able to solve this problem. Now I am having some trouble finding out how to multiply these two bignums together.
The idea I had was that I could somehow use the method of long multiplication/grade-school multiplication by calling my single-digit multiplication algorithm on the first string multiplied by the last element and second-to-last element of the second string, then call my sum function to add them together and store the result in a variable called accumulation then repeat this process in a recursion.
However, some problems I am having are that my single-digit multiplication recursive algorithms return the result in reverse order, so I cannot necessary add the two results together. Also, when multiplying the first string by the second-to-last element of the second string, I would have to multiply the result by 10 (since this digit is in the tens place), but I am not so sure how to implement that either.
Do you guys have any ideas on how I could possibly solve this problem using recursion only (no loops)? The result should look something like this:
First number > 57983985376
Second number > 543647645777735
Sum is 543705629763111
57983985376 times 2 is 115967970752
...
57983985376 times 9 is 521855868384
Product is 31522857142473014386403360

Related

Maximum number of primitive operations occurring in a program

I am trying to count the maximum number of operations in a program, given the pseudocode. I am given the pseudocode for finding the maximum number in an array (provided in our class slides by our professor). Now I need to count maximum possible number of primitive operations (I know usually order is the only thing we need to care about, but nonetheless I want to try this out.)
Some examples of primitive operations considered are:
Evaluating an expression
Assigning a value to a variable
Indexing into an array
Calling a method
Returning from a method, etc...
Now I understand why the first line takes 2 operations, we are indexing into the array A and assigning the value to the variable currentMax, thus there are 2 operations in total being carried out in the first line. I understand that the maximum number of primitive operations (that is the worst case) is going to be 2(n-1) for the 3 lines inside the for loop, but I am having trouble with the line that is labelled as having 2n operations.
In my mind, what is happening is the first time, i=1 is getting assigned and checked against n-1, thus 2 operations, and then the only thing occurring is the checking of i each time against n-1. The incrementing is happening in line where it says {increment counter i}. We aren't assigning any value to i in the for loop line. Thus I think the for loop line should have 2 + n operations instead of 2n.
I found another slide on the internet after a bit of searching that has the same structure, but it says 2+n instead of 2n and the total number of operations is then 7n-1 instead of 8n-2. This is shown here:
Which one is the correct one here?

Splitting number into bit halves

I'm implementing karatsuba's method as part of an exercise. Karatsuba's method itself isn't terribly difficult, but one part of it is confusing me. Both numbers being multiplied have to be split into two halves, the high and the low bits. But I can't find much information about how this split is done.
I noticed most Karatsuba implementations use strings to represent huge numbers, but I'm doing something a bit different. I'm representing them as an array of ints, where each element is the next 30 bits of the huge number. Note that this means these arrays may be odd-length. If the huge number's size is not a multiple of 30, it gets leading zeros so it can still be represented as such.
So how can this be split into high and low halves? The main problem I'm running into is that since it can be odd-length, that means I can't just divide the arrays by their elements. Basically, how can I select the first and last bit halves of these int arrays so I can continue recursing in Karatsuba's method?
As long as I can retrieve the bits, I can create two smaller int arrays from them.

Finding the pair of strings with most number of identical letters in an array

Suppose I have an array of strings of different lengths.
It can be assumed that the strings have no repeating characters.
Using a brute-force algorithm, I can find the pair of strings that have the most number of identical letters (order does not matter - for example, "ABCDZFW" and "FBZ" have 3 identical letters) in n-squared time.
Is there a more efficient way to do this?
Attempt: I've tried to think of a solution using the trie data structure, but this won't work since a trie would only group together strings with similar prefixes.
I can find the pair of strings that have the most number of identical
letters (order does not matter - for example, "ABCDZFW" and "FBZ" have
3 identical letters) in n-squared time.
I think you can't as string comparison itself is O(max(length(s1), length(s2))) along with the O(n^2) loop for checking all pairs. However you can optimize the comparison of strings in some extent.
As you mentioned the strings don't have duplicates and I am assuming the strings consist of only uppercase letters according to your input. So, it turns into each string can be only 26 characters long.
For each string, we can use a bitmask. And for each character of a string, we can set the corresponding bit 1. For example:
ABCGH
11000111 (from LSB to MSB)
Thus, we have n bit-masks for n strings.
Way #1
Now you can check all possible pairs of strings using O(n^2) loop and compare the string by ANDing two corresponding mask and check the number of set bits (hamming weight). Obviously this is an improvement of your version because the string comparison is optimized now - Only an AND operation between two 32 bit integer which is a O(1) operation.
For example for any two strings comparison will be:
ABCDG
ABCEF
X1 = mask(ABCDG) => 1001111
X2 = mask(ABCEF) => 0110111
X1 AND X2 => 0000111
hamming weight(0000111) => 3 // number of set bits
Way #2
Now, one observation is the AND of same type bit is 1. So for every masks, we will try to maximize the Hamming weight (total number of set bits) of AND value of two string's masks as the string with most matched characters have same bit 1 and ANDing these two masks will make those bits 1.
Now build a Trie with all masks - every node of the trie will hold 0 or 1 based on the corresponding bit is set or not. Insert each mask from MSB ot LSB. Before inserting ith mask into Trie(already holding i - 1 masks), we will query to try maximizing the Hamming weight of AND recusively by going to same bit's branch (to make the bit 1 in final AND variable) and also to opposite bit's branch because in later levels you might get more set bits in this branch.
Regarding this Trie part, for nice pictorial explanation, you can find a similar thread here (this works with XOR).
Here in worst case, we will need to traverse many branches of trie for maximizing the hamming weight. And in worst case it will take around 6 * 10^6 operations (which will take ~1 sec in typical machine) and also we need additional space for building trie. But say the total number of strings is 10^5, then for O(n^2) algorithms, it will take 10^10 operations which is too much - so the trie approach is still far better.
Let me know if you're having problem with implementation. Unfortunately I can able to help you with code only if you're a C/C++ or Java guy.
Thanks #JimMischel for pointing out a major flaw. I slightly misunderstood the statement first.

Assembly language program (sum the differences of a number in an array)

I have been tasked, with a homework assignment (I'm not going to sugar-coat it), writing a 32-bit assembly program that uses a loop and indexed addressing to calculate the sum of the gaps between successive array elements, which are in non-decreasing order. (Ex: dwarray dword 0,2,5,9,10)
What I don't know how to do is subtract the nth element of an array from the nth-1 element in the array using a loop. If I did, then I would store the result in a different register and keep adding the results into that register until the last element has been reached. I'm only looking to be pointed in the right direction (I'm not looking for the answer). Does anyone have any suggestions?
Since you will be using a loop you'll need a loop counter equal to the number of elements in the array minus 1.
Convenient instructions would be add eax,[ebx+ecx*4] and sub eax,[ebx+ecx*4-4]

What's the efficient algorithm to find the Integer square root of a very large number, digit by digit?

I need to write program to find the integer square root of a number which is thousands of digits long. I can't use Newton Raphson as I don't have data types to store and divide such large numbers. I am using a long array in C to store the number. Is there any algorithm to find the square root by maybe iterating over the digits?
Edit:
I can't use external library like GMP.
If you can input the target number, then you must have a way to store at least one such large number. For Newton-Raphson you only need to be able to halve and add numbers. Think of a way to halve a number without using division.
ETA: Correction: division can be avoided by doubling and subtraction.
You seem to have a lot of very unrealistic constraints on your 'bignum' implementation. I might suggest a binary search? At each iteration, find the 'half-way' value mid = (hi + lo) / 2, and prune the search space as [hi, mid], or [mid, lo] depending on the square of those values.
Not as fast as NR, etc. But should converge with careful treatment of squaring range values...
You can implement long division method to compute square root which is being taught at school. You can implement this method for base 10 and the result is computed digit by digit from left to right. You can stop once integer part is calculated.

Resources