I have this program which is supposed to find the Longest Common Substring of a number of strings. Which it does, but if the strings are very long (i.e. >8000 characters long), it works slowly (1.5 seconds).
Is there any way to optimise that?
The program is this:
//#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
using namespace std;
const unsigned short MAX_STRINGS = 10;
const unsigned int MAX_SIZE=10000;
vector<string> strings;
unsigned int len;
string GetLongestCommonSubstring( string string1, string string2 );
inline void readNumberSubstrings();
inline const string getMaxSubstring();
void readNumberSubstrings()
{
cin >> len;
assert(len > 1 && len <=MAX_STRINGS);
strings.resize(len);
for(register unsigned int i=0; i<len;i++)
strings[i]=string(MAX_SIZE,0);
for(register unsigned int i=0; i<len; i++)
cin>>strings[i];
}
const string getMaxSubstring()
{
string maxSubstring=strings[0];
for(register unsigned int i=1; i < len; i++)
maxSubstring=GetLongestCommonSubstring(maxSubstring, strings[i]);
return maxSubstring;
}
string GetLongestCommonSubstring( string string1, string string2 )
{
const int solution_size = string2.length()+ 1;
int *x=new int[solution_size]();
int *y= new int[solution_size]();
int **previous = &x;
int **current = &y;
int max_length = 0;
int result_index = 0;
int j;
int length;
int M=string2.length() - 1;
for(register int i = string1.length() - 1; i >= 0; i--)
{
for(register int j = M; j >= 0; j--)
{
if(string1[i] != string2[j])
(*current)[j] = 0;
else
{
length = 1 + (*previous)[j + 1];
if (length > max_length)
{
max_length = length;
result_index = i;
}
(*current)[j] = length;
}
}
swap(previous, current);
}
string1[max_length+result_index]='\0';
return &(string1[result_index]);
}
int main()
{
readNumberSubstrings();
cout << getMaxSubstring() << endl;
return 0;
}
Note: there is a reason why I didn't write code that would solve this problem with suffix trees (they're large).
Often when it comes to optimization, a different approach might be your only true option rather than trying to incrementally improve the current implementation. Here's my idea:
create a list of valid characters that might appear in the longest common substring. I.e., if a character doesn't appear in all strings, it can't be part of the longest common substring.
separate each string into multiple strings containing only valid characters
for every such string, create every possible substring and add it to the list as well
filter (as with the characters) all strings, that don't show up in all lists.
The complexity of this obviously depends largely on the number of invalid characters. if it's zero, this approach doesn't help at all.
Some remarks on your code: Don't try to be overly clever. The compiler will optimize so much, there's really no need for you to put register in your code. Second, your allocating strings and then overwrite them (in readNumberSubstrings), that's totally unnecessary. Third, pass by const reference if you can. Fourth, don't use raw pointers, especially if you never delete [] your new []d objects. Use std::vectors instead, it behaves well with exceptions (which you might encounter, you're using strings a lot!).
You have to use suffix tree. This struct will make algorithm, which work about 1 second for 10 string with 10000 symbols.
Give a Suffix Arraya try, they take as much memory as your input strings (depending on your text encoding though) and a built quickly in linear time.
http://en.wikipedia.org/wiki/Suffix_array
Here is my JavaScript code for this
function LCS(as, bs, A, B) {
var a = 0, b = 0, R = [], max = 1
while (a < A.length && b < B.length) {
var M = cmpAt(as, bs, A[a], B[b])
if (M.size > 0) {
if (M.ab < 0) {
var x = b; while (x < B.length) {
var C = cmpAt(as, bs, A[a], B[x])
if (C.size >= M.size) { if (C.size >= max) max = C.size, R.push([a, x, C.size]) } else break
x++
}
} else {
var x = a; while (x < A.length) {
var C = cmpAt(as, bs, A[x], B[b])
if (C.size >= M.size) { if (C.size >= max) max = C.size, R.push([x, b, C.size]) } else break
x++
}
}
}
if (M.ab < 0) a++; else b++
}
R = R.filter(function(a){ if (a[2] == max) return true })
return R
}
function cmpAt(a, b, x, y) {
var c = 0
while (true) {
if (x == a.length) {
if (y == b.length) return { size: c, ab: 0 }
return { size: c, ab: -1 }
}
if (y == b.length) return { size: c, ab: 1 }
if (a.charCodeAt(x) != b.charCodeAt(y)) {
var ab = 1;
if (a.charCodeAt(x) < b.charCodeAt(y)) ab = -1
return { size: c, ab: ab }
}
c++, x++, y++
}
}
Related
Basically i want to write a function that takes values from 0 to 6 and gives back a random assortment such as 2,3,4,5,0,1,6. Here is the code that i came up with. However the problem is that the integer prev (meaning previous) does not store all the old values of r (random number) and thus some values end up being repeated. How might i fix this?
int s(int b)
{
// b is 7
int h = b-1;
int prev = -1;// to store the previous r value
srand(time(0));
for (int i = 0; i < b; i++)
{
int r = rand()%(h - 0 + 1) + 0;
if (r != prev)
{
cout << r << endl;
prev = r;
}
else if (r == prev)
{
s(b);
}
}
return 0;
}
From the comments, this sounds more like a homework problem than a practical problem because you said "No arrays allowed". But I suppose it is an interesting problem.
Here's some code, in Java with only loops, if statements, and with no arrays, as required.
It outputs a random permutation of the set 0, 1, ..., N, shuffled with the Fisher-Yates algorithm.
void printRandom(int N) {
long used = 0;
for (int i = 0; i < N; i++) {
int randomIndex = ThreadLocalRandom.current().nextInt(N - Long.bitCount(used));
for (int j = 0; j < N; j++) {
if ((used & (1L << j)) == 0) {
if (randomIndex-- == 0) {
System.out.print(j + " ");
used = used | (1L << j);
break;
}
}
}
}
}
It is unfortunately limited to the size of a long on your system :)
I think the best way to solve this problem is by using an aux funtion that stores in a variable all the numbers printed until the moment, check if the new number is in the used numbers variable, if not add it to the variable (you can use strings? I know that they are arrays of char's but maybe you can)
Something like this:
function aux(int b, char *variables_printed, int iterations_left)
if (b = 0) then print variables_printed
else
int n = generate_random_number() %b
while (n in variables_printed)
n= (n+random_number) % b
variables_printed += n
aux(b, variables_printed, iterations_left-1)
And your other function:
function s(b)
if b < 0 return 0
else
char *variables_to_print
aux(b, variables_to_print, b)
If you can not use strings, you can do it with long as konsolas said.
I'm practicing in programming and I generating all combinations in c++. I know how to generate all combination in
certain length
My result is something like that
A A A
A A B
A A C
A B A
A B B
A B C
A C A
A C B
A C C
B A A
.....
and my problem is, I don't know, how to generate all combinations with unknown length. For example I want word length = 5 and program will generate all combination in exactly length 5. How to do it?
A A A A A
A A A A B
A A A A C
A A A B A
.........
(Sorry for my english)
See the link Print all permutations with repetition of characters
The below recursive function in the page, can create last+1 length permutations.
/* The main function that recursively prints all repeated
permutations of the given string. It uses data[] to store all
permutations one by one */
void allLexicographicRecur (char *str, char* data, int last, int index)
{
int i, len = strlen(str);
// One by one fix all characters at the given index and recur for
// the/ subsequent indexes
for ( i=0; i<len; i++ )
{
// Fix the ith character at index and if this is not the last
// index then recursively call for higher indexes
data[index] = str[i] ;
// If this is the last index then print the string stored in
// data[]
if (index == last)
printf("%s\n", data);
else // Recur for higher indexes
allLexicographicRecur (str, data, last, index+1);
}
}
I think this can serve your purpose.
Call allLexicographicRecur with the required (length-1) value for the 'last' parameter.
This is actually nothing more than counting.
If you have the letters A, B, and C, you are counting in base 3.
A is 0, B is 1 and C is 2.
Quick and dirty:
#include <string>
#include <iostream>
int main()
{
for(int i = 0; i < 100; i++) {
const int base = 3;
const char zero_char = 'A';
const size_t length = 5;
std::string out;
for(int n = i; n > 0; ) {
int d = n%base;
out = static_cast<char>(zero_char + d) + out;
n /= base;
}
while(out.length() < length) out = zero_char + out;
std::cout << out << '\n';
}
}
see it live
The possible combinations are baselength, so if you want all combinations for A, B, C with 5 digits, change the limit of the first for loop to 35 ( = 243):
for(int i = 0; i < 243; i++)
You may use something like:
bool increase(const std::string& s, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= s.size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::string& s,
const std::vector<std::size_t>& it)
{
for (std::size_t i = 0; i != it.size(); ++i) {
std::cout << s[it[i]] << " ";
}
std::cout << std::endl;
}
void cartesian_product(const std::string& s, std::size_t n)
{
std::vector<std::size_t> it(n, 0u);
do {
do_job(s, it);
} while (increase(s, it));
}
Demo
I am coding for the problem in which we got to count the number of common characters in two strings. Main part of the count goes like this
for(i=0; i < strlen(s1); i++) {
for(j = 0; j < strlen(s2); j++) {
if(s1[i] == s2[j]) {
count++;
s2[j] = '*';
break;
}
}
}
This goes with an O(n^2) logic. However I could not think of a better solution than this. Can anyone help me in coding with an O(n) logic.
This is very simple. Take two int arrays freq1 and freq2. Initialize all its elements to 0. Then read your strings and store the frequencies of the characters to these arrays. After that compare the arrays freq1 and freq2 to find the common characters.
It can be done in O(n) time with constant space.
The pseudo code goes like this :
int map1[26], map2[26];
int common_chars = 0;
for c1 in string1:
map1[c1]++;
for c2 in string2:
map2[c2]++;
for i in 1 to 26:
common_chars += min(map1[i], map2[i]);
Your current code is O(n^3) because of the O(n) strlens and produces incorrect results, for example on "aa", "aa" (which your code will return 4).
This code counts letters in common (each letter being counted at most once) in O(n).
int common(const char *a, const char *b) {
int table[256] = {0};
int result = 0;
for (; *a; a++)table[*a]++;
for (; *b; b++)result += (table[*b]-- > 0);
return result;
}
Depending on how you define "letters in common", you may have different logic. Here's some testcases for the definition I'm using (which is size of the multiset intersection).
int main(int argc, char *argv[]) {
struct { const char *a, *b; int want; } cases[] = {
{"a", "a", 1},
{"a", "b", 0},
{"a", "aa", 1},
{"aa", "a", 1},
{"ccc", "cccc", 3},
{"aaa", "aaa", 3},
{"abc", "cba", 3},
{"aasa", "asad", 3},
};
int fail = 0;
for (int i = 0; i < sizeof(cases) / sizeof(*cases); i++) {
int got = common(cases[i].a, cases[i].b);
if (got != cases[i].want) {
fail = 1;
printf("common(%s, %s) = %d, want %d\n",
cases[i].a, cases[i].b, got, cases[i].want);
}
}
return fail;
}
You can do it with 2n:
int i,j, len1 = strlen(s1), len2 = strlen(s2);
unsigned char allChars[256] = { 0 };
int count = 0;
for( i=0; i<len1; i++ )
{
allChars[ (unsigned char) s1[i] ] = 1;
}
for( i=0; i<len2; i++ )
{
if( allChars[ (unsigned char) s1[i] ] == 1 )
{
allChars[ (unsigned char) s2[i] ] = 2;
}
}
for( i=0; i<256; i++ )
{
if( allChars[i] == 2 )
{
cout << allChars[i] << endl;
count++;
}
}
Following code traverses each sting only once. So the complexity is O(n). One of the assumptions is that the upper and lower cases are considered same.
#include<stdio.h>
int main() {
char a[] = "Hello world";
char b[] = "woowrd";
int x[26] = {0};
int i;
int index;
for (i = 0; a[i] != '\0'; i++) {
index = a[i] - 'a';
if (index > 26) {
//capital char
index = a[i] - 'A';
}
x[index]++;
}
for (i = 0; b[i] != '\0'; i++) {
index = b[i] - 'a';
if (index > 26) {
//capital char
index = b[i] - 'A';
}
if (x[index] > 0)
x[index] = -1;
}
printf("Common characters in '%s' and '%s' are ", a, b);
for (i = 0; i < 26; i++) {
if (x[i] < 0)
printf("%c", 'a'+i);
}
printf("\n");
}
int count(string a, string b)
{
int i,c[26]={0},c1[26]={};
for(i=0;i<a.length();i++)
{
if(97<=a[i]&&a[i]<=123)
c[a[i]-97]++;
}
for(i=0;i<b.length();i++)
{
if(97<=b[i]&&b[i]<=123)
c1[b[i]-97]++;
}
int s=0;
for(i=0;i<26;i++)
{
s=s+abs(c[i]+c1[i]-(c[i]-c1[i]));
}
return (s);
}
This is much easier and better solution
for (std::vector<char>::iterator i = s1.begin(); i != s1.end(); ++i)
{
if (std::find(s2.begin(), s2.end(), *i) != s2.end())
{
dest.push_back(*i);
}
}
taken from here
C implementation to run in O(n) time and constant space.
#define ALPHABETS_COUNT 26
int commonChars(char *s1, char *s2)
{
int c_count = 0, i;
int arr1[ALPHABETS_COUNT] = {0}, arr2[ALPHABETS_COUNT] = {0};
/* Compute the number of occurances of each character */
while (*s1) arr1[*s1++-'a'] += 1;
while (*s2) arr2[*s2++-'a'] += 1;
/* Increment count based on match found */
for(i=0; i<ALPHABETS_COUNT; i++) {
if(arr1[i] == arr2[i]) c_count += arr1[i];
else if(arr1[i]>arr2[i] && arr2[i] != 0) c_count += arr2[i];
else if(arr2[i]>arr1[i] && arr1[i] != 0) c_count += arr1[i];
}
return c_count;
}
First, your code does not run in O(n^2), it runs in O(nm), where n and m are the length of each string.
You can do it in O(n+m), but not better, since you have to go through each string, at least once, to see if a character is in both.
An example in C++, assuming:
ASCII characters
All characters included (letters, numbers, special, spaces, etc...)
Case sensitive
std::vector<char> strIntersect(std::string const&s1, std::string const&s2){
std::vector<bool> presents(256, false); //Assuming ASCII
std::vector<char> intersection;
for (auto c : s1) {
presents[c] = true;
}
for (auto c : s2) {
if (presents[c]){
intersection.push_back(c);
presents[c] = false;
}
}
return intersection;
}
int main() {
std::vector<char> result;
std::string s1 = "El perro de San Roque no tiene rabo, porque Ramon Rodriguez se lo ha cortado";
std::string s2 = "Saint Roque's dog has no tail, because Ramon Rodriguez chopped it off";
//Expected: "S a i n t R o q u e s d g h l , b c m r z p"
result = strIntersect(s1, s2);
for (auto c : result) {
std::cout << c << " ";
}
std::cout << std::endl;
return 0;
}
Their is a more better version in c++ :
C++ bitset and its application
A bitset is an array of bool but each Boolean value is not stored separately instead bitset optimizes the space such that each bool takes 1 bit space only, so space taken by bitset bs is less than that of bool bs[N] and vector bs(N). However, a limitation of bitset is, N must be known at compile time, i.e., a constant (this limitation is not there with vector and dynamic array)
As bitset stores the same information in compressed manner the operation on bitset are faster than that of array and vector. We can access each bit of bitset individually with help of array indexing operator [] that is bs[3] shows bit at index 3 of bitset bs just like a simple array. Remember bitset starts its indexing backward that is for 10110, 0 are at 0th and 3rd indices whereas 1 are at 1st 2nd and 4th indices.
We can construct a bitset using integer number as well as binary string via constructors which is shown in below code. The size of bitset is fixed at compile time that is, it can’t be changed at runtime.
For more information about bitset visit the site : https://www.geeksforgeeks.org/c-bitset-and-its-application
The code is as follows :
// considering the strings to be of lower case.
int main()
{
string s1,s2;
cin>>s1>>s2;
//Declaration for bitset type variables
bitset<26> b_s1,b_s2;
// setting the bits in b_s1 for the encountered characters of string s1
for(auto& i : s1)
{
if(!b_s1[i-'a'])
b_s1[i-'a'] = 1;
}
// setting the bits in b_s2 for the encountered characters of string s2
for(auto& i : s2)
{
if(!b_s2[i-'a'])
b_s2[i-'a'] = 1;
}
// counting the number of set bits by the "Logical AND" operation
// between b_s1 and b_s2
cout<<(b_s1&b_s2).count();
}
No need to initialize and keep an array of 26 elements (numbers for each letter in alphabet). Just fo the following:
Using HashMap store letter as a key and integer got the count as a value.
Create a Set of characters.
Iterate through each string characters, add to the Set from step 2. If add() method returned false, (means that same character already exists in the Set), then add the character to the map and increment the value.
These steps are written considering Java programming language.
Python Code:
>>>s1='abbc'
>>>s2='abde'
>>>p=list(set(s1).intersection(set(s2)))
>>print(p)
['a','b']
Hope this helps you, Happy Coding!
can be easily done using the concept of "catching" which is a sub-algorithm of hashing.
i'm working on a code right now in C++, in which i'm supposed to make a function which receives a string of numbers and converts it into an integer then returns that value. for example if i pass "4569" as string, it will return 4569 integer value.
can anyone help me point out where i'm wrong ??? thanks in advance :)
#include<iostream>
#include<cstdlib>
using namespace std;
void getInput(char arr[] , int size )
{
cout<<"ENTER THE ARRAY"<<endl;
cin.getline(arr,size);
}
int stringToInteger(char source[])
{
int sum = 0;
int y=strlen(source);
int multiply = 1;
for( int i=y ; i>=0 ; i--)
{
int n= source[i];
sum = (sum + (n * multiply));
multiply = (multiply *10);
}
return sum;
}
int main()
{
const int size =100;
char inputArr [size];
getInput (inputArr, size );
int x = stringToInteger (inputArr );
cout<<"THE RETURNED INTEGER VALUE IS"<<endl;
cout<<x<<endl;
return 0;
}
First, you're starting at the character after the end of the string. If the length (returned by strlen) is y, then valid indexes are 0 <= i < y. So your loop wants to start from y-1.
for( int i=y-1 ; i>=0 ; i--)
^^
Then, you need to convert each ASCII digit into a value from 0 to 9, by subtracting the ASCII value for '0':
int n= source[i] - '0';
^^^^^
Then you should probably detect and handle erroneous input, including values that are too large to be represented by int.
Then, once you've learnt how to implement this in C, throw it away and use the C++ library:
std::string input;
std::getline(std::cin, input);
int x = std::stoi(input);
Try,
#include <stdlib.h>
and in your main():
int x = atoi(inputArr);
I'm not sure why you aren't using atoi or std::stoi, but your algorithm has a logical flaw:
int stringToInteger(char source[])
{
int sum = 0;
int y=strlen(source);
int multiply = 1;
for(int i=y - 1; i >= 0; i--) // you were starting at y, which is 1 passed the end of the array
{
int n = (int)(source[i] - '0');
sum += (n * multiply); // += makes this more readable
multiply *= 10; // same with *=
}
return sum;
}
That said, if this was something other than a homework assignment, you should be using the solutions posted https://stackoverflow.com/a/18238566/529761 or https://stackoverflow.com/a/18238682/529761 (depending on your language requirements).
Also, even this change has 1 potential problem: If the source contains non-numeric characters, it will not work properly. A simple way to approach it is to break out if you encounter a character that shouldn't be there:
int stringToInteger(char source[])
{
int sum = 0;
int y=strlen(source);
int multiply = 1;
for(int i=y - 1; i >= 0; i--) // you were starting at y, which is 1 passed the end of the array
{
int n = (int)(source[i] - '0');
if (n < 0 || n > 9)
break;
sum += (n * multiply); // += makes this more readable
multiply *= 10; // same with *=
}
return sum;
}
No need to call a strlen -- until you are allowed to use library functions (the above-mentioned atoi and strtol), you can use this:
int stringToInteger(char *source)
{
int sum = 0;
if (source)
while (*source >= '0' && *source <= '9')
{
sum = 10*sum + *source - '0';
source++;
}
return sum;
}
As implied in about every other answer, you forgot there is a difference between the ASCII character '0' and the binary value 0.
Here is my implementation of Problem 25 - Project Euler (see comments in code for explanation of how it works):
#include <iostream> //Declare headers and use correct namespace
#include <math.h>
using namespace std;
//Variables for the equation F_n(newTerm) = F_n-1(prevTerm) + Fn_2(currentTerm)
unsigned long long newTerm = 0;
unsigned long long prevTerm = 1; //F_1 initially = 1
unsigned long long currentTerm = 1; //F_2 initially = 2
unsigned long long termNo = 2; //Current number for the term
void getNextTerms() { //Iterates through the Fib sequence, by changing the global variables.
newTerm = prevTerm + currentTerm; //First run: newTerm = 2
unsigned long long temp = currentTerm; //temp = 1
currentTerm = newTerm; //currentTerm = 2
prevTerm = temp; //prevTerm = 1
termNo++; //termNo = 3
}
unsigned long long getLength(unsigned long long number) //Returns the length of the number
{
unsigned long long length = 0;
while (number >= 1) {
number = number / 10;
length++;
}
return length;
}
int main (int argc, const char * argv[])
{
while (true) {
getNextTerms(); //Gets next term in the Fib sequence
if (getLength(currentTerm) < 1000) { //Checks if the next terms size is less than the desired length
}
else { //Otherwise if it is perfect print out the term.
cout << termNo;
break;
}
}
}
This works for the example, and will run quickly as long as this line:
if (getLength(currentTerm) < 1000) { //Checks if the next term's size is less than the desired length
says 20 or lower instead of 1000. But if that number is greater than 20 it takes a forever, my patience gets the better of me and I stop the program, how can I make this algorithm more efficient?
If you have any questions just ask in the comments.
There is a closed formula for the Fibonachi numbers (as well as for any linear recurrent sequence).
So F_n = C1 * a^n + C2 * b^n, where C1, C2, a and b are numbers that can be found from the initial conditions, i.e. for the Fib case from
F_n+2 = F_n+1 + F_n
F_1 = 1
F_2 = 1
I don't give their values on purpose here. It's just a hint.
nth fibonacci number is =
(g1^n-g2^n)/sqrt(5).
where g1 = (1+sqrt(5))/2 = 1.61803399
g2 = (1-sqrt(5))/2 = -0.61803399
For finding the length of nth fibonacci number, we can just calculate the log(nth fibonacci number).So, length of nth fibonacci number is,
log((g1^n-g2^n)/sqrt(5)) = log(g1^n-g2^n)-0.5*log(5).
you can just ignore g2^n, since it is very small negative number.
Hence, length of nth fibonacci is
n*log(g1)-0.5*log(5)
and we need to find the smallest value of 'n' such that this length = 1000, so we can find the value of n for which the length is just greater than 999.
So,
n*log(g1)-0.5*log(5) > 999
n*log(g1) > 999+0.5*log(5)
n > (999+0.5*log(5))/log(g1)
n > (999.3494850021680094)/(0.20898764058551)
n > 4781.859263075
Hence, the smallest required n is 4782. No use of any coding, easiest way.
Note: everywhere log is used in base 10.
This will probably speed it up a fair bit:
int getLength(unsigned long long number) //Returns the length of the number when expressed in base-10
{
return (int)log10(number) + 1;
}
...but, you can't reach 1000 digits using an unsigned long long. I suggest looking into arbitrary-precision arithmetic libraries, or languages which have arbitrary-precision arithmetic built in.
You could try computing a Fibonacci number using matrix exponentiation. Then repeated doubling to get to a number that has more than 1000 digits and use binary search in that range to find the first one.
using doubles, you can come to a solution knowing the highest exponential is 308:
get the sequence to the exp of 250, then divide your two numbers by 1e250. Restart the algorithm with those two numbers
if you do this 4 times, you'll get the right answer
C++ code maybe as follows:
#include "iostream"
#include "string.h"
#include "algorithm"
using namespace std;
string addTwoString(string a, string b)
{
if (a.length() == 0)
{
return b;
}
if (b.length() == 0)
{
return a;
}
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
string result = "";
string str_1, str_2;
if (a.length() > b.length())
{
str_1 = b;
str_2 = a;
}
else
{
str_1 = a;
str_2 = b;
}
int index = 0;
int value = 0, over_value = 0;
for (; index < str_1.length(); ++index)
{
int temp_1 = (int)(str_1[index] - '0');
int temp_2 = (int)(str_2[index] - '0');
int temp = temp_1 + temp_2 + over_value;
value = temp % 10;
over_value = temp / 10;
char c = (char)(value + '0');
result += c;
}
for (; index < str_2.length(); ++index)
{
int temp_2 = (int)(str_2[index] - '0');
int temp = temp_2 + over_value;
value = temp % 10;
over_value = temp / 10;
char c = (char)(value + '0');
result += c;
}
if (over_value > 0)
{
char c = (char)(over_value + '0');
result += c;
}
reverse(result.begin(), result.end());
return result;
}
int main()
{
string a = "1";
string b = "1";
string c = addTwoString(a, b);
int index = 3;
while (c.length() < 1000)
{
a = b;
b = c;
c = addTwoString(a, b);
++ index;
}
cout << index << endl;
}
I just used a recursive function that adds arrays vertically to complete the problem. Basically zero run time, less than 50 lines of code. Enjoy:
#include <stdio.h>
int Calc_Fib (int numA[], int numB[], int temp[], int index) {
int i = 0;
//Check 1000th digit for non-zero value.
if (numB[999] != 0) return index;
//Add arrays A and B vertically.
for (i = 0; i < 1000; ++i) {
temp[i] += (numA[i] + numB[i]);
if (temp[i] > 9) {
temp[i + 1] = temp[i] / 10;
temp[i] %= 10;
}
numA[i] = numB[i];
numB[i] = temp[i];
temp[i] = 0;
}
Calc_Fib(numA, numB, temp, ++index);
}
int main() {
int numA[1000]; //Holds previous term.
int numB[1000]; //Holds current term.
int temp[1000]; //Holds temporary number for vertical addition.
int i = 0;
int indexVal = 2;
for (i = 0; i < 1000; ++i) {
numA[i] = 0;
numB[i] = 0;
temp[i] = 0;
}
//Initialize first two terms.
numA[0] = (numB[0] = 1);
indexVal = Calc_Fib(numA, numB, temp, indexVal);
printf("Tada: %d\n", indexVal);
return 0;
}