C++ Karatsuba long integer algorithm error - c++

i got this error = Unhandled exception at 0x7A5B1088 (ucrtbased.dll) in algorthmprokect1.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x006B2FF4). occurred
i don't know where i have a mistake i am using strings because i need to get integers from file and they has 1000 digits
Update:After Debugging i realized that else statement runs infinite number of times but i still didn't found the solution.
string karatsuba(string X,string Y) {
if (X.length()==1 || (X.length()==2 && ((X.substr(0, 1).compare("-") == 0))))
{
int buf = stoi(X) * stoi(Y); //multiply if int has single digit
return to_string (buf);
}
else
{
string X1 = X.substr(0, (X.length()/2)); //divide half to X
string X2 = X.substr((X.length() / 2), X.length());
string Y1 = Y.substr(0, (Y.length() / 2)); // divide half to Y
string Y2 = Y.substr((Y.length() / 2) , Y.length() );
string U= karatsuba(X1, X2);
string V = karatsuba(Y1, Y2);
string W = karatsuba(to_string(stoi(X1) - stoi(X2)), to_string(stoi(Y1) - stoi(Y2)));
string Z = to_string(stoi(U) + stoi(V) - stoi(W));
string P = to_string(pow(10, X.length()) * stoi(U) + pow(10, X.length() / 2) * stoi(Z) + stoi(V));
return P;
}
}

This code is not working properly because of the infinite recursion.
But this is not the main problem of it.
The main problem is: it's a brilliant example of how not to do. You are severe underqualified to do such tasks. There is no point in attempts to fix this code, you must simply put it into trash. I would recommend to start with the GNU MP library. You can learn much from the source code and documentation there how to work with big integers and implement big integer algorithms. You may also try to read this source.

Related

use of 'n' before deduction of 'auto' C++

I'm trying to have my function return 3 values (n, down and across) I've read online how 'auto' can be used but must be doing something wrong.
The function takes in a 2D vector of integers (as well as other variables) and checks for how many numbers are connected to board[0][0] such that they are the same number.
I've tried putting auto in front of the function inside the function itself, tried leaving it blank, tried just having chain = chainNodes(...) but I always seem to get an error. Here's the code:
tuple<int, int, int> chainNodes(vector<vector<int>> board, int originalNum,
unsigned int across, unsigned int down, int ijSum,
int n)
{
struct chain {
int n, down, across;
};
if(down + across > ijSum) {
ijSum = down + across;
} else if((down + across == ijSum) &&
((down - across) * (down - across) < (ijSum) * (ijSum))) {
ijSum = down + across;
}
board[down][across] = 0;
n += 1;
// Check below
if((down != (board.size() - 1)) && (board[down + 1][across]) == originalNum) {
down += 1;
auto [n, iPoint, jPoint] = chainNodes(board, originalNum, across, down, ijSum, n);
down -= 1;
}
// Check right, up and left (I've removed so its not too messy here)
return chain{n, down, across};
}
Sorry, I forgot to include the error message.
error: use of 'n' before deduction of 'auto'
It occurs on the line that uses auto.
Issue with
auto [n, iPoint, jPoint] = chainNodes(board, originalNum, across, down, ijSum, n);
is similar to
auto n = foo(n); // `foo(n)` uses `n` from `auto n`,
// not the one from outer scope as function parameter
The construct int a = a + 1; is legal but lead to UB as reading uninitialized variable.
That kind of construct allows legal and valid behavior void* p = &p;.
Your code has other errors and it is not clear for me expected behavior of the function.
So not sure if following is the correct fix, but you might want:
n = std::get<0>(chainNodes(board, originalNum, across, down, ijSum, n));

Recursion Stack Overflow C++

I am new to C++ but thought that working on some project Euler problems would familiarize me with the language.
When attempting
Project Euler Problem 14: Longest Collatz sequence
I could not manage to get my C++ solution to work, but had no problem with my python solution...
import time
start = time.time()
memo = {1:1,2:2}
longest_chain, longest_starting_key = 2, 2
def rec(a):
global longest_chain, longest_starting_key
if a in memo.keys():
return memo[a]
if a % 2 == 0:
memo[a] = rec(a // 2) + 1
else:
memo[a] = rec(3 * a + 1) + 1
if memo[a] > longest_chain:
longest_chain = memo[a]
longest_starting_key = a
return memo[a]
for i in range(1000000,3,-1): rec(i)
print("starting key", longest_starting_key , ": has length", longest_chain)
print((time.time() - start), "seconds")
and got
starting key 837799 has length 525
1.399820327758789 seconds
My C++ attempt... (that I thought was equivalent...)
#include <iostream>
#include <unordered_map>
std::unordered_map<int, int> mem = { {1,1},{2,2} };
int longest_chain{ 2 }, best_starting_num{ 2 };
bool is_in(const int& i){
auto search = mem.find(i);
if(search == mem.end())
return false;
else
return true;
}
int f(int n){
if(is_in(n))
return mem[n];
if(n % 2)
mem[n] = f(3 * n + 1) + 1;
else
mem[n] = f(n / 2) + 1;
if(mem[n] > longest_chain)
longest_chain = mem[n];
return mem[n];
}
int main(){
for(int i = 3; i < 1000000; i++){
f(i);
}
std::cout << longest_chain << std::endl;
}
When running this in Visual Studio in debug mode I get the following error
Unhandled exception at 0x00007FF75A64EB70 in
0014_longest)collatz_sequence_cpp.exe: 0xC00000FD: Stack overflow
(parameters: 0x0000000000000001, 0x000000DC81493FE0).
Someone told me that I should allocate on the heap using pointers, but have very limited experience with working with pointers...
The other thing I don't understand is... when I run it with 100'000 instead of 1'000'000 in the main body loop, it works but is very slow.
Hint: What is the invariant on the range of n that the Collatz sequence provides (mathematically), which your Python code satisfies but your C++ code doesn't? Hint to the hint: what are the last few values of n before your stack overflow actually occurs?

Recursive Anagram Calculator C++

I am trying to make a program that, with a given word, can calculate and print every letter combination.
To be more specific, I am asked to use a recursive function and what I should get is something like this:
Given word: HOME
EHOM
EMOH
MEHO
The approach I am taking in to swap the content #x with #x+1 like this
string[0]->string[1]
string[0]->string[2]
This is what I came up with
void anagram(char * s, int len, int y)
{
char temp; //used to store the content to swap betwen the two
if (len < 0) //when the total lenght of the array gets to 0 it means that every single swap has been made
return;
temp = s[len]; //swapping
s[len] = s[y];
s[y] = temp;
puts(s); //prints the string
if (y == 0)
return anagram(s, len-1, y - 1);
return anagram(s, len, y - 1);
}
What I get is just a huge mess and a Break Point from VS (if not a crash).
Can somebody help me please?

Computing median of std::vector<double> causing segfault

The following function is supposed to compute the median of a std::vector<double>.
double vecMed(vector<double>& vec) {
vector<double> copyVec = vec;
sort(copyVec.begin(), copyVec.end());
if( copyVec.size()%2 == 0)
return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
else
return copyVec[copyVec.size()/2];
}
I'm getting a segfault on this line, sometimes:
return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
Can anyone see a problem with this function?
The segfault might be due to memory corruption elsewhere that I'm unaware of, but I want to make sure I'm not making a subtle or careless mistake in the above code before I explore that possibility.
GDB says:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000428ab6 in vecMed (this=0x7fffffffd1b0, vec=...) at ../globals.cpp:834
834 return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
(gdb) bt
#0 0x0000000000428ab6 in vecMed (this=0x7fffffffd1b0, vec=...) at ../globals.cpp:834
So much errors in the code!
I guess you want:
#include <algorithm>
#include <vector>
double vecMed(std::vector<double> vec) {
if(vec.empty()) return 0;
else {
std::sort(vec.begin(), vec.end());
if(vec.size() % 2 == 0)
return (vec[vec.size()/2 - 1] + vec[vec.size()/2]) / 2;
else
return vec[vec.size()/2];
}
}
First off, if the initial vector is empty, what you're doing is not safe.
Secondly, your logic isn't right in the even case. If copyVec.size() % 2 == 0, it's even, so static_cast<double>(copyVec.size())/2.0 is an integer. So both the floor and ceil are the same thing, so that's probably not what you want to do. Prefer something like:
const int mid = copyVec.size() / 2;
if (copyVec.size() % 2 == 0) {
return 0.5 * (copyVec[mid] + copyVec[mid+1]); // safe unless size == 0
}
else {
return copyVec[mid]; // e.g. if size == 3, return copyVec[1]
}
You don't need floor of ceil, you can do this far more efficiently using integer arithmetic:
return (copyVec[copyVec.size()/2] + copyVec[(copyVec.size() + 1)/2]) / 2.0;
Now this code will do the same as yours but it is easier to read and understand.
Start by trying out some simple cases and some edge cases. In this case you may note that your code does not run correctly for an empty array.
Lets assume you don't see anything suspicious in the code you investigate your best option is to use a debugger. Sometimes using valgrind would also help if you have a stack corruption.
Also you may want to consider using std::nth_element for finding the median of a vector.

C++ code crashes with "free(): invalid next size"

I have written a small program which uses function pointers to do some numerical calculations.
double polynom(const int j, const double xi) {
return pow(xi, j);
}
/**
* Calculate the legendre_polynom l_end on a certain position xi.
*/
double legendre_polynom(const int l_end, const double xi) {
vector <double> p_l(l_end+1);
p_l[0] = 1.0;
p_l[1] = xi;
for (int x = 2; x <= l_end; x++) {
// p_l = ((2x-1) * p_{x-1} - (x-1) * p_{x-2}) / l
p_l[x] = ((2 * x - 1) * p_l[x - 1] - (x - 1) * p_l[x - 2]) / x;
}
double result = p_l[l_end];
return result;
}
The program crashes with an unusual free() error. If I change the function pointer to the first function (polynom) it works fine, but it fails with legendre_polynom.
I already debugged that far that it breaks right after exiting that function and before the other code continues.
*** glibc detected *** blub: free(): invalid next size (fast): 0x0804f248 ***
======= Backtrace: ========= /lib/i386-linux-gnu/libc.so.6(+0x6ebc2)[0xb7d70bc2]
/lib/i386-linux-gnu/libc.so.6(+0x6f862)[0xb7d71862]
/lib/i386-linux-gnu/libc.so.6(cfree+0x6d)[0xb7d7494d]
...
number2(_ZN9__gnu_cxx13new_allocatorIdE10deallocateEPdj+0x11)[0x804bc8b]
number2(_ZNSt12_Vector_baseIdSaIdEE13_M_deallocateEPdj+0x25)[0x804bbc3]
number2(_ZNSt12_Vector_baseIdSaIdEED1Ev+0x37)[0x804ba33]
number2(_ZNSt6vectorIdSaIdEED1Ev+0x38)[0x804b8a0]
number2(_Z16legendre_polynomid+0x13f)[0x804af9b]
So my question is what is wrong here?
There is no error in that code, provided that you always call that function with l_end >= 1.
When l_end == 0 instead there is an out of boundary write operation in p_l[1] = xi;.
Note however that you cannot infer that this is the function having the problem just because this is where you get a crash or just because not calling this function you have no crash.
An error is an error and a crash is a crash. They are completely distinct in C++; the sooner you realize this important fact the better. There may be an error somewhere else and this function may be just the victim.
If you see a crash then there is an error. If you see no crash you know nothing (the error may be still present).