So I got this introduction to Programming assignment, I have to write a program that find the nth member of the following sequence 1, 121, 1213121, 121312141213121.. and so on. Basically, the first member is 1, and every next one is made of [the previous member] [n] [the previous member]. N < 10. So I got this problem that I do not understand, tried searching for it in the internet but didn't get anything that can help me.
#include "stdafx.h"
#include <iostream>
using namespace std;
int size(int n, int realsize);
int main()
{
int n;
cin >> n;
if (n == 1) {
cout << "1";
return 0;
}
int helper = 0;
char c = '2';
char* look;
char* say;
say = new char[size(n, 1) + 1]();
look = new char[size(n - 1, 1) + 1]();
look[0] = '1';
while (helper < n) {
for (int i = 0; i < size(helper + 1, 1); i++) {
say[i] = look[i];
}
say[size(helper + 1, 1)] = c;
for (int i = size(helper + 1, 1) + 1; i < size(helper + 1, 1) * 2 + 1; i++) {
say[i] = look[i - (size(helper + 1, 1) + 1)];
}
for (int i = 0; i < size(helper + 1, 1) * 2 + 1; i++) {
look[i] = say[i];
}
helper += 1;
}
cout << say;
delete[] say;
delete[] look;
return 0;
}
int size(int n, int realsize)
{
if (n == 1)
return realsize;
else
return size(n - 1, realsize * 2 + 1);
}
You are overwriting the capacity of your look variable. It ends out being written with the entire contents of say, so it needs to have that same size as well.
While I don't condone the below code as good code, it has minimal adjustments from your own implementation and should give a more solid base to continue towards a working outcome. I tested it with the first couple of numbers, but that's no guarantee it is perfect.
#include <iostream>
using namespace std;
int size(int n, int realsize);
int main()
{
int n;
cin >> n;
if (n == 1)
{
cout << "1";
return 0;
}
int helper = 0;
char c = '2';
char * look;
char * say;
say = new char[size(n, 1) + 1]; // Ditch the () call, which is confusing.
look = new char[size(n, 1) + 1]; // Make the same size as "say"
look[0] = '1';
while (helper < n - 1) // You're overrunning this loop I think, so I did it to n - 1.
{
for (int i = 0; i < size(helper + 1, 1); i++)
{
say[i] = look[i];
}
say[size(helper + 1, 1)] = c + helper; // You were adding '2' every time, so this will add 2, 3, 4, etc incrementally.
for (int i = size(helper + 1, 1) + 1; i < size(helper + 1, 1) * 2 + 1; i++)
{
say[i] = look[i - (size(helper + 1, 1) + 1)];
}
for (int i = 0; i < size(helper + 1, 1) * 2 + 1; i++)
{
look[i] = say[i];
}
helper += 1;
}
say[size(n, 1)] = '\0'; // Null-terminate "say" before printing it out.
cout << say;
delete[] say;
delete[] look;
return 0;
}
int size(int n, int realsize)
{
if (n == 1)
return realsize;
else
return size(n - 1, realsize * 2 + 1);
}
Related
I need to find a maximum size subset from a set of numbers which will have a given sum X.
I've found a solution which solves this:
// A Dynamic Programming solution for the
// subset sum problem+ maximal subset size.
#include <bits/stdc++.h>
using namespace std;
// Returns size of maximum sized subset
// if there is a subset of set[] with sum
// equal to given sum. It returns -1 if there
// is no subset with given sum.
int isSubsetSum(int set[], int n, int sum)
{
// The value of subset[i][j] will be true if there
// is a subset of set[0..j-1] with sum equal to i
bool subset[sum + 1][n + 1];
int count[sum + 1][n + 1];
// If sum is 0, then answer is true
for (int i = 0; i <= n; i++)
{
subset[0][i] = true;
count[0][i] = 0;
}
// If sum is not 0 and set is empty,
// then answer is false
for (int i = 1; i <= sum; i++)
{
subset[i][0] = false;
count[i][0] = -1;
}
// Fill the subset table in bottom up manner
for (int i = 1; i <= sum; i++)
{
for (int j = 1; j <= n; j++)
{
subset[i][j] = subset[i][j - 1];
count[i][j] = count[i][j - 1];
if (i >= set[j - 1])
{
subset[i][j] = subset[i][j] ||
subset[i - set[j - 1]][j - 1];
if (subset[i][j])
count[i][j] = max(count[i][j - 1],
count[i - set[j - 1]][j - 1] + 1);
}
}
}
return count[sum][n];
}
// Driver code
int main()
{
int set[] = { 2, 3, 5, 10 };
int sum = 20;
int n = 4;
cout << isSubsetSum(set, n, sum);
}
However that solutions provided output is maximum number of elements from the set that sum up to given sum X. I would also need to have the subset as well.
For example:
set[] = { 2, 3, 5, 7, 10, 15 }
sum = 10
The output will be 3 which is correct, but I would also know the subset which in this case would be {2, 3, 5}.
It is not obvious for me how to extract this as I don't fully understand the algorithm. I am working on C implementation, but if anyone can explain the algorithm then that would also help.
EDIT:
I've worked up some solution in standard C which works, but seems to have some problem.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct s_set {
int indx;
int arr[15];
};
int main(int argc, char *argv[]) {
int set[] = {2, 3, 5, 10, 7, 6, 1, 1};
int sum= 10;
int n=8;
int i, j, index;
bool subset[sum + 1][n + 1]; // [subset_sum][subset_size]
int count[sum + 1][n + 1];
s_set lset[sum + 1][n + 1];
s_set element;
// if sum is 0, then answer is true - edge case when user provides sum vaue of 0 so no subset can exists
i = 0;
for (i; i <= n; i++)
{
subset[0][i] = true;
count[0][i] = 0;
}
// if sum is not 0 and set is empty, then answer is false - edge case when user provides empty set so no subset to be found
i = 1;
for (i; i <= sum; i++)
{
subset[i][0] = false;
count[i][0] = -1;
}
// set indexes to 0
i=0;
for (i; i <= sum; i++)
{
lset[i][0].indx=0;
}
// fill the subset table in bottom up manner
i = 1;
for (i; i <= sum; i++) { // column index
j=1;
for (j; j <= n; j++) {
subset[i][j] = subset[i][j - 1];
count[i][j] = count[i][j - 1];
lset[i][j]=lset[i][j - 1];
if (i >= set[j - 1]) {
subset[i][j] = subset[i][j] || subset[i - set[j - 1]][j - 1];
if (subset[i][j])
if ((count[i - set[j - 1]][j - 1] + 1) > count[i][j - 1]) {
count[i][j]=count[i - set[j - 1]][j - 1] + 1;
element=lset[i - set[j - 1]][j - 1];
index=element.indx;
element.arr[index]=set[j - 1];
element.indx=index+1;
lset[i][j]=element;
}
else
{
count[i][j]=count[i][j - 1];
}
}
}
}
printf("Maximum number of elements from set: %d \n", count[sum][n]);
//printf("Maximum number of elements from set: %d \n", lset[sum][n].indx);
i=0;
printf("SET{");
for (i;i<=count[sum][n]-1;i++) {
printf(" %d ", lset[sum][n].arr[i]);
}
printf("}");
return 0;
}
The problem is that if arr size in the struct s_set is too low then it will not work and will give return code 3221225477. I've gotten it to work by randomly increasing the number (40 seems to work fine), but I don't understand why does this have any effect. The index number which is used to write into arr variable should not go so high.
Working (arr size 40):
Not working (arr size 10):
I'm solving a algorithm problem https://codeforces.com/contest/1671/problem/E. Although my submit can pass the tests provided by the contest, I find it fails on specific test(Hack). When I'm trying to find where's the error, I find that if I choose start debugging, the program would run perfectly. However, when I click "run", it would give a wrong answer. So, I'm curious about what happens.
#include<iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int const NN = 1e6;
int const MOD = 998244353;
char str[NN];
long long dfs_data[NN];
int powans[20];
string myhash[NN];
int n;
long long dfs(int num) {
if (dfs_data[num] != 0) return dfs_data[num];
if (num >= powans[n - 1] - 1) {
dfs_data[num] = 1;
return 1;
}
if (myhash[num * 2 + 1] == myhash[num * 2 + 2]) {
dfs_data[num] = (dfs(num * 2 + 1) % MOD) * (dfs(num * 2 + 2) % MOD) % MOD;
} else dfs_data[num] = 2 * (dfs(num * 2 + 1) % MOD) * (dfs(num * 2 + 2) % MOD) % MOD;
return dfs_data[num];
}
void gethashcode(int t) {
if (t >= powans[n - 1] - 1) {
myhash[t] += str[t];
return;
}
if (myhash[2 * t + 1] == "") gethashcode(2 * t + 1);
if (myhash[2 * t + 2] == "") gethashcode(2 * t + 2);
if (myhash[2 * t + 1] < myhash[2 * t + 2]) myhash[t] = str[t] + myhash[2 * t + 1] + myhash[2 * t + 2];
else myhash[t] = str[t] + myhash[2 * t + 2] + myhash[2 * t + 1];
}
void solve() {
memset(dfs_data, 0, sizeof dfs_data);
cin >> n;
cin >> str;
powans[0] = 1;
for (int i = 1; i < 19; i++) {
powans[i] = 2 * powans[i - 1];
}
for (int i = 0; i < NN; i++) {
myhash[i] = "";
}
gethashcode(0);
cout << dfs(0);
}
int main() {
solve();
}
I'm made a memorization version of the Fibonacci function (code commented out). Now I want to make a bottom-up and memorization version of the same function. However, my solution seem to be out of the range for really large numbers.
class Solution
{
public:
//Function to count number of ways to reach the nth stair.
int fib(int n)
{
// int memo[n + 1];
// for(int i = 0; i < n + 1; i++) {
// memo[i] = -1;
// }
// if(memo[n] == -1) {
// if(n <= 2) {
// memo[n] = 1;
// } else {
// memo[n] = fib(n - 1) + fib(n - 2);
// }
// }
// return memo[n];
int memo[n + 1];
memo[0] = 1;
memo[1] = 1;
memo[2] = 1;
for(int i = 3; i < n + 1; i++) {
memo[i] = memo[i - 1] + memo[i - 2];
}
return memo[n];
}
// Returns number of ways to
// reach s'th stair
int countWays(int s)
{
int memo[s + 1];
return fib(s + 1);
}
};
example input:
Input:
84
Its Correct output is:
93254120
And Your Code's output is:
-1289228135
You should use uint64_t instead of int to cover wider range of numbers (up to term number 93 which is 12200160415121876738) and avoid this overflow problem, also correct that memo[0] = 0; not 1. Finally, the term number 84 is 160500643816367088 not 93254120.
The prober code for the first method should be like this:
uint64_t fib(int n)
{
if (n < 2)
return n;
else
return fib(n - 1) + fib(n - 2);
}
This code will take long time for later terms.
For the second method:
uint64_t fib(int n)
{
uint64_t *memo = new uint64_t[n + 1];
memo[0] = 0;
memo[1] = 1;
for (int i = 2; i <= n; i++)
memo[i] = memo[i - 1] + memo[i - 2];
return memo[n];
}
This one is much more efficient and faster.
I have to optimitze a code with a triply-recursive function. I know that these kind of functions might be really slow, specially when dealing with large numbers. I have tried to improve the following code by comparing it with an efficient code of Fibonacci, but I'm still stucked.
Could you give me some hints? How can I use a loop instead? Thanks in advance!
int f(int i) {
if (i == 0) return -3;
if (i == 1) return -1;
if (i == 2) return 4;
if (i == 3) return 8;
if (i == 4) return 15;
return f(i-5) + f(i-3) + f(i-1);
}
int main() {
int n;
while (cin >> n) {
for (int i = 0; i < n; ++i) cout << f(i) << " ";
cout << "..." << endl;
}
}
First you might store result in std::vector:
int f(int n) {
std::vector<int> res{-3, -1, 4, 8, 15};
if (n < 5) return res[n];
for (int i = 5; i != n + 1; ++i) {
res.push_back(res[i - 5] + res[i - 3] + res[i - 1]);
}
return res[n];
}
Then to reduce memory foot print, you might use only last values of the array:
int f(int n) {
int res[5] = {-3, -1, 4, 8, 15};
if (n < 5) return res[n];
for (int i = 5; i != n + 1; ++i) {
const int fi = res[0] + res[2] + res[4];
std::copy(res + 1, res + 5, res);
res[4] = fi;
}
return res[4];
}
You might even avoid the copy with circular buffer and use of modulo.
int f(int n) {
int res[5] = {-3, -1, 4, 8, 15};
if (n < 5) return res[n];
for (int i = 5; i != n + 1; ++i) {
const int fi = res[(i - 5) % 5] + res[(i - 3) % 5] + res[(i - 1) % 5];
res[i % 5] = fi;
}
return res[n % 5];
}
You might notice that ((i - 5) % 5) == (i % 5)
and replace the computation by
res[i % 5] += res[(i - 3) % 5] + res[(i - 1) % 5];
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 years ago.
Consider the following code:
int* solve(int input[], int len) {
//Processing and building the calc array. Can be ignored.
int calc[3*(len-1)];
calc[0] = input[0];
calc[1] = 1;
calc[2] = 1;
for (int b = 1; b < len - 1; b++) {
calc[3*b] = 0;
calc[3*b + 1] = 0;
calc[3*b + 2] = 0;
}
if (input[0] < input[1]) {
calc[3] = input[1];
calc[4] = 0;
calc[5] = 1;
} else {
calc[3] = input[0];
calc[4] = 1;
calc[5] = 0;
}
for (int i = 2; i < len - 1; i++) {
for (int j = 0; j < i; j++) {
if ((i - j > 1 || calc[3*j + 2] == 0) && calc[3*j] + input[i] > calc[3*i]) {
calc[3*i] = calc[3*j] + input[i];
calc[3*i + 1] = calc[3*j + 1];
calc[3*i + 2] = 1;
} else if (input[i] > input[j] && calc[3*i] < calc[3*j] - input[j] + input[i]) {
calc[3*i] = calc[3*j] - input[j] + input[i];
calc[3*i + 1] = calc[3*j + 1];
calc[3*i + 2] = 1;
} else if (calc[3*i] < calc[3*j]) {
calc[3*i] = calc[3*j];
calc[3*i + 1] = calc[3*j + 1];
calc[3*i + 2] = 0;
}
}
}
//Printing the array
cout<<"Calc array: ";
for (int a = 0; a < len - 1; a++) {
cout<<"("<<calc[3*a]<<" "<<calc[3*a + 1]<<" "<<calc[3*a+2]<<") ";
}
cout<<endl;
//Returning a pointer to the array
int *pointer = calc;
return pointer;
}
int main() {
//Taking input. Can be ignored.
int len;
cin>>len;
int input[len];
for (int i = 0; i < len; i++) {
cin>>input[i];
}
//Assigning another pointer to the array that the solve() function returns.
int *a = solve(input, len);
int *b;
//Printing the array that the pointer points to.
cout<<"A Array: ";
for (int x = 0; x < len - 1; x++) {
cout<<"("<<a[3*x]<<" "<<a[3*x + 1]<<" "<<a[3*x+2]<<") ";
}
cout<<endl;
//Ignore code from here.
int c;
if (a[3*(len - 2) + 1] == 1) {
input[0] = -10*10*10*10;
b = solve(input, len);
if (b[3*(len - 2) + 2] == 1) {
if (input[len-1] > input[len-2]) {
c = b[3*(len - 2)] - input[len-2] + input[len - 1];
cout<<c<<endl;
} else {
c = b[3*(len - 2)];
}
} else {
c = b[3*(len - 2)] + input[len-1];
}
if (c < a[3*(len - 2)]) {
cout<<a[3*(len - 2)];
} else {
cout<<c<<endl;
cout<<a[3*(len - 2)]<<" "<<a[3*(len - 2) + 1]<<" "<<a[3*(len - 2) + 2];
cout<<"This route"<<endl;
}
} else {
input[1] = -10*10*10*10;
b = solve(input, len);
if (a[3*(len - 2) + 2] == 1) {
if (input[len-1] > input[len-2]) {
c = a[3*(len - 2)] - input[len-2] + input[len - 1];
} else {
c = a[3*(len - 2)];
}
} else {
c = a[3*(len - 2)] + input[len-1];
}
if (c > b[3*(len - 2)]) {
cout<<b[3*(len - 2)];
} else {
cout<<c;
}
}
}
Now the problem here is, that when I print the calc array inside the solve() function the first time it prints perfectly and gives the following desired output:
Calc array: (10 1 1) (10 1 0) (12 1 1) (15 1 1) (19 1 1)
But when I print it again inside the main() function, I get the following output:
A Array: (135712 0 1259266624) (2045 1 0) (4792936 0 32) (15 4792936 0) (2357952 0 4792936)
I have just migrated from Python to C++, and I find it extremely cumbersome, at times such as these. I have tried all sorts of modifications to the code but I still can't figure out the problem. Any help would be appreciated.
calc is a local variable whose lifetime starts at it's definition and ends when the function exits.
Since you're returning a pointer to it when exiting the function, the dereferencing of said pointer will be undefined behaviour (since the "object" behind it no longer exists).
If you want a variable to survive function return, you'll need to do something like allocating it dynamically, changing:
int calc[3*(len-1)];
to:
int *calc = new int [(3 * (len - 1)];
and then ensuring you delete[] it in the caller when you're done with it.