Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I need to find the largest sequence of identical digits in a given integer using a recursive function.
For example:
input: "2221", output: 3
input: "2223333", output: 4
input: "222333", output: 3
For some reason the code sometimes works correctly and sometimes it doesn't. when I input "1112" then it gives me the correct output (3), but when I input "1111555", I expected to get the output 4, but instead got 6.
Also, I can't change the parameters that the function receives so if someone knows how can I insert the parameters inside the function instead of outside (if I insert them inside the function then the output I receive is always 0)
I'd really appreciate the help so thank you in advance :)
My code:
int currentLength = 0, maxLength = 0;
int currentDigit = -1;
int maxSequence(int num)
{
if (num <= 0)
return maxLength;
int digit = num % 10;
if (digit == currentDigit) {
maxLength= 1 + maxSequence(num / 10);
}
else {
currentDigit = digit;
if (maxLength > 1)
{
maxLength = 0;
}
else
{
maxLength = 1;
}
return maxSequence(num / 10);
}
}
Recursion and mutable global variables is a nasty combination.
You can add the parameters to a different function and call that instead.
Something like this:
// Since you can't use std::max.
int max(int a, int b) { return a > b ? a : b; }
int maxSequenceHelper(int number, int last, int length, int maximum)
{
int digit = number % 10;
if (digit == last)
{
length += 1;
maximum = max(length, maximum);
}
else
{
length = 1;
}
return number < 10
? maximum
: maxSequenceHelper(number / 10, digit, length, maximum);
}
int maxSequence(int number)
{
return maxSequenceHelper(number / 10, number % 10, 1, 1);
}
And here is a version without any assignments, making it slightly easier to reason about:
int maxSequenceHelper(int number, int last, int length, int maximum)
{
const int digit = number % 10;
const int new_length = digit == last ? length + 1 : 1;
const int new_maximum = max(new_length, maximum);
return number < 10
? new_maximum
: maxSequenceHelper(number / 10, digit, new_length, new_maximum);
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I've written a code to find the largest prime factor that has, so far, worked for every single case that i've tested for, yet it fails when I input 600851475143. It keeps giving me 5102831 which is incorrect. I'm not sure why this happens even though I've checked it, help would be appreciated.
#include <iostream>
long int get_largest_prime_factor(long int);
int main()
{
std::cout << get_largest_prime_factor(600851475143);
return 0;
}
long int get_largest_prime_factor(long int prime_Number)
{
for(long int r = prime_Number - 1; r != 1; r--)
{
if(prime_Number % r == 0)
{
long int a = get_largest_prime_factor(r);
long int b = get_largest_prime_factor(prime_Number / r);
if(a == b)
return a;
return a > b? a : b;
}
}
return prime_Number;
}
Use this easy algorithm to get the right prime factor:
long long int getMaxPrimeFactor(long long int n) {
int i, max = -1;
while (n % 2 == 0) {
max = 2;
n /= 2;
}
for (i = 3; i <= sqrt(n); i = i + 2)
while (n % i == 0) {
max = i;
n /= i;
}
max = (n > 2) ? n : max;
return max;
}
This should output you:
6857
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Prints specific sequence by given n. For example n=1: 1, n=2: 121, n=3,1213121, n=4: 121312141213121 and so on. But for n > 11 the program stops working after 3556 cout. I think the problem is too many cout or too many recursive calls, but im not sure how to fix it or even is that really the problem. Please let me know if u have any solutions. Thank you so much!
#include <iostream>
using namespace std;
int findNumberByIndex(int index, int& number, int n) {
if (index < 0) {
return 0;
}
if (index % 2 == 0) {
return 1;
}
if (index == ((int)pow(2, number - 1) - 1)) {
return number;
}
index -= (int)pow(2, number);
findNumberByIndex(index, number, n);
}
int printSeq(int rowLen, int& index, int& number, int n, int& counter) {
if (index == rowLen) {
return 0;
}
int result = findNumberByIndex(index, number, n);
if (result == 0) {
number++;
}
else {
cout << result;
index++;
number = 2;
}
printSeq(rowLen, index, number, n, ++counter);
}
int main()
{
int n, index = 0, number = 2, seqLen = 1;
cin >> n;
int counter = 0;
if (n < 0 || n >= 20) {
return 0;
}
int rowLen = ((int)pow(2, n - 1) + (int)pow(2, n - 1) - 1);
printSeq(rowLen, index, number, n, counter);
cout << endl;
return 0;
}
In the definition of findNumberByIndex, you forgot to
return findNumberByIndex(index, number, n);
In the definition of printSeq, you forgot to
return printSeq(rowLen, index, number, n, ++counter);
This leads to undefined behaviour.
Regarding your hypothesis
I think the problem is too many cout or too many recursive calls
Unless specific concerns you can revoke the idea of "too many output". You could suffer from a too deep recursive call tree, but in your specific example your functions are tail-recusrive. With optimization correctly turned on, any decent compiler should optimize them.
So, I started learning C++ recently. This code is trying to add the sum of the squares of each numbers digits. For example: 243: 2*2 + 4*4 + 3*3 = 29.
int sumOfSquareDigits(int n) //BUG WITH INPUT OF 10, 100, 1000, etc.
{
int digits = findDigits(n);
int number;
int remainder;
int *allDigits = new int[digits];
for (int i = 0; i < digits; i++) { //assigns digits to array
if (i + 1 == digits){ //sees if there is a ones value left
allDigits[i] = n;
}
else {
remainder = (n % findPower10(digits - (i + 1)));
number = ((n - remainder) / findPower10(digits - (i + 1)));
allDigits[i] = number; //records leftmost digit
n = n - (allDigits[i] * findPower10(digits - (i + 1))); //gets rid of leftmost number and starts over
}
}
int result = 0;
for (int i = 0; i < digits; i++) { //finds sum of squared digits
result = result + (allDigits[i] * allDigits[i]);
}
delete [] allDigits;
return result;
}
int findDigits(int n) //finds out how many digits the number has
{
int digits = 0;
int test;
do {
digits++;
test = findPower10(digits);
} while (n > test);
return digits;
}
int findPower10(int n) { //function for calculating powers of 10
int result = 1;
for (int i = 0; i < n; i++)
result = result * 10;
return result;
}
And after running the code, I've figured out that it (barely) mostly works. I've found that whenever a user inputs a value of 10, 100, 1000, etc. it always returns a value of 100. I'd like to solve this only using the iostream header.
Sorry if my code isn't too readable or organized! It would also be helpful if there are any shortcuts to my super long code, thanks!
The problem is in the findDigits function. For the values 10, 100, 1000 etc, it calculates the number of the digits minus one. This happens because of the comparison in the loop, you are stopping when n is less or equal to test, but in these cases n is equal test and you should run the next iteration.
So, you should change the line 33:
} while (n > test);
to:
} while (n >= test);
Now, it should work just fine. But it will not work for negative numbers (I don't know this is required, but the solution bellow works for that case too).
I came up with a much simpler solution:
int sumOfSquareDigits(int n)
{
// Variable to mantain the total sum of the squares
int sum = 0;
// This loop will change n until it is zero
while (n != 0) {
/// The current digit we will calculate the square is the rightmost digit,
// so we just get its value using the mod operator
int current = n % 10;
// Add its square to the sum
sum += current*current;
// You divide n by 10, this 'removes' one digit of n
n = n / 10;
}
return sum;
}
I found the problem challenging managed to reduce your code to the following lines:
long long sumOfSquareDigits(long long i) {
long long sum(0L);
do {
long long r = i % 10;
sum += (r * r);
} while(i /= 10);
return sum;
}
Haven't test it thoroughly but I think it works OK.
This question already has answers here:
How to get the least number after deleting k digits from the input number
(11 answers)
Closed 6 years ago.
I am trying to code a program that can do something like this:
in:
5 4
1 9 9 9 0
out:
9990
and i have a problem. It doesnt work on any set of numbers. For example it works for the one above, but it doesnt work for this one:
in:
15 9
2 9 3 6 5 8 8 8 8 7 2 2 8 1 4
out: 988887814
2 9 3 6 5 8 8 8 8 7 2 2 8 1 4
I did this with a vector approach and it works for any set of numbers, but i'm trying to do it a stack for a better complexity.
EDIT ---- MODIFIED FOR STD::STACK
Code for method using stack:
#include <iostream>
#include <fstream>
#include <stack>
using namespace std;
ifstream in("trompeta.in");
ofstream out("trompeta.out");
void reverseStack(stack<char> st) {
if(!st.empty())
{
char x = st.top();
st.pop();
reverseStack(st);
out<<x;
}
return;
}
int main()
{
int n,m,count=1;
stack <char> st;
char x;
in>>n>>m;
in>>x;
st.push(x);
for(int i=1; i<n; i++)
{
in>>x;
if(st.top()<x && count+n-i-1>=m)
{
st.pop();
st.push(x);
}
else
{
st.push(x);
count++;
if (count>m-1) break;
}
};
reverseStack(st);
}
Code for method using vectors:
#include <iostream>
#include <fstream>
using namespace std;
ifstream in ( "trompeta.in" );
ofstream out ( "trompeta.out" );
int main ()
{
int i = 0, N, M, max, j, p = 0, var;
in >> N >> M;
char* v = new char[N];
char* a = new char[M];
in >> v;
var = M;
max = v[0];
for ( i = 0; i < M; i++ )
{
for ( j = p ; j < N-var+1; j++ )
{
if ( v[j] > max )
{
max = v[j];
p = j;
}
}
var--;
a[i] = max;
max = v[p+1];
p = p+1;
}
for ( i = 0; i < M; i++ )
out << a[i]-'0';
}
Can any1 help me to get the STACK code working?
Using the fact that the most significant digit completely trumps all other digets except in place of a tie, I would look at the first (N-M+1) digits, find the largest single digit in that range.
If it occurs once, the first digit is locked in. Discard the digits which occur prior to that position, and you repeat for "maximum value of M-1 numbers of out N-position" to find the remaining digits of the answer. (or N-position-1, if position is zero based)
If it occurs multiple times, then recursively find "maximum value of M-1 numbers out of N-position" for each, then select the largest single result from these. There can be at most N such matches.
I forgot to mention, if N==M, you are also done.
proof of recursion:
Computing the value of the sub-match will always select M-1 digits. When M is 1, you only need to select the largest of a few positions, and have no more recursion. This is true for both cases. Also the "select from" steps always contain no more than N choices, because they are always based on selecting one most significant digit.
------------------ how you might do it with a stack ----------------
An actual implementation using a stack would be based on an object which contains the entire state of the problem, at each step, like so:
struct data { // require: n == digits.size()
int n, m;
std::string digits;
bool operator<(const data &rhs){ return digits < rhs.digits; }
};
The point of this is not just to store the original problem, but to have a way to represent any subproblem, which you can push and pop on a stack. The stack itself is not really important, here, because it is used to pick the one best result within a specific layer. Recursion handles most of the work.
Here is the top level function which hides the data struct:
std::string select_ordered_max(int n, int m, std::string digits) {
if (n < m || (int)digits.size() != n)
return "size wrong";
data d{ n, m, digits };
data answer = select_ordered_max(d);
return answer.digits;
}
and a rough pseudocode of the recursive workhorse
data select_ordered_max(data original){
// check trivial return conditions
// determine char most_significant
// push all subproblems that satisfy most_significant
//(special case where m==1)
// pop subproblems, remembering best
return answer {original.m, original.m, std::string(1, most_significant) + best_submatch.digits };
}
String comparison works on numbers when you only compare strings of the exact same length, which is the case here.
Yes, I know having n and m is redundant with digits.size(), but I didn't want to work too hard. Including it twice simplified some recursion checks. The actual implementation only pushed a candidate to the stack if it passed the max digit check for that level of recursion. This allowed me to get the correct 9 digit answer from 15 digits of input with only 28 candidates pushed to the stack (and them popped during max-select).
Now your code has quite a few issues, but rather than focusing on those lets answer the question. Let's say that your code has been corrected to give us:
const size_t M where M is the number of digits expected in our output
const vector<int> v which is the input set of numbers of size N
You just always want to pick the highest value most significant number remaining. So we'll keep an end iterator to prevent us from picking a digit that wouldn't leave us with enough digits to finish the number, and use max_element to select:
const int pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
auto maximum = 0;
auto end = prev(cend(v), M - 1);
auto it = max_element(cbegin(v), end);
for (auto i = M - 1; i > 0; --i) {
maximum += *it * pow10[i];
advance(end, 1);
it = max_element(next(it), end);
}
maximum += *it;
Live Example
This code depends upon M being greater than 0 and less than N and less than log10(numeric_limits<int>::max())
EDIT: Sad to say this solves the consecutive digits problem, after edits the question wants subsequent digits, but not necessarily consecutive
So the little known numeric library provides inner_product which seems like just the tool for this job. Now your code has quite a few issues, but rather than focusing on those lets answer the question. Let's say that your code has been corrected to give us:
vector<int> foo(M) where M is the number of digits expected in our output
const vector<int> v which is the input set of numbers of size N
We'll use foo in the inner_product, initializing it with decreasing powers of 10:
generate(begin(foo), end(foo), [i=int{1}]() mutable {
auto result = i;
i *= 10;
return result; });
We can then use this in a loop:
auto maximum = 0;
for (auto it = prev(rend(v), size(foo) + 1); it != rbegin(v); advance(it, -1)) {
maximum = max<int>(inner_product(cbegin(foo), cend(foo), it, 0), maximum);
}
maximum = max<int>(inner_product(cbegin(foo), cend(foo), rbegin(v), 0), maximum);
Live Example
To use it's initialization requires that your initial M was smaller than N, so you may want to assert that or something.
--EDITED--
here's my suggestion with STACK based on my previous suggestion using vector
findMaxValueOutOfNDigits(stackInput, M, N)
{
// stackInput = [2, 9, 3, 6, 5, 8, 8, 8, 8, 7, 2, 2, 8, 1, 4]
// *where 4 was the first element to be inserted and 2 was the last to be inserted
// if the sequence is inverted, you can quickly fix it by doing a "for x = 0; x < stack.length; x++ { newStack.push(stack.pop()) }"
currentMaxValue = 0
for i = 0; i < (M - N + 1); i++
{
tempValue = process(stackInput, M, N)
stackInput.pop()
if (tempValue > currentMaxValue)
currentMaxValue = tempValue
}
return currentMaxValue
}
process(stackInput, M, N)
{
tempValue = stackInput.pop() * 10^(N - 1)
*howManyItemsCanILook = (M - N + 1)
for y = (N - 2); y == 0; y++
{
currentHowManyItemsCanILook = *howManyItemsCanILook
tempValue = tempValue + getValue(stackInput, *howManyItemsCanILook) * 10^(y)
*howManyItemsCanILook = *howManyItemsCanILook - 1
for x = 0; x < (currentHowManyItemsCanILook - *howManyItemsCanILook); x++
{
stackInput.pop()
}
}
return tempValue
}
getValue(stackInput, *howManyItemsCanILook)
{
currentMaxValue = stackInput.pop()
if (currentMaxValue == 9)
return 9
else
{
goUntil = *howManyItemsCanILook
for i = 0; i < goUntil; i++
{
*howManyItemsCanILook = *howManyItemsCanILook - 1
tempValue = stackInput.pop()
if (currentMaxValue < tempValue)
{
currentMaxValue = tempValue
if (currentMaxValue == 9)
return currentMaxValue
}
}
return currentMaxValue
}
}
note: where *howManyItemsCanILook is passed by reference
I hope this helps
i'm trying to do a subtraction of digits in a recursive way, lets say that I have the number 125 then the subtraction takes place doing it this way
5-2-1 = 2
I've already done the sum with recursion but i'm stuck thinking about it because i'm trying to get each digit and then subtract it within the function itself this way
int RecursiveMath::restaDigitos(int n){
if(n/10 <= 1){
return 0;
}else{
return restaDigitos(n/10) - n%10;
}
}
I do know this function is not working but it's what i've tried along with many combinations, I feel like i'm complicating it too much, any help/advice would be highly appreciated!
You can simplify the task because 5 - 2 - 1 is equal to 5 - (2 + 1), so we can sum up all digits except highest, and subtract this sum from it.
int subtractDigits(const unsigned int n, const bool first = true){
if(n == 0){
return 0;
}
if(first){
return n % 10 - subtractDigits(n / 10, false);
}
else{
return n % 10 + subtractDigits(n / 10, false);
}
}
AHHH This one was tricky
#include <stdio.h>
int restaDigitos(int n){
printf("Processing: %d\n", n);
printf("division: %d\n", n/10);
if(n==0){
return 0;
}else{
return n%10 + restaDigitos(n/10);
}
}
int main() {
int input = 125;
int firstVal = input % 10;
int result = restaDigitos(input / 10);
printf("result: %d\n", firstVal - result);
}
Two major corrections were made:
Your termination condition was neglecting the last case where a single digit remains so it terminated early
The first value cannot be recursive because it is positive. (5-2-1) -> The first number 5 is positive whereas the other values are negative
Hope this helped!
The problem is that you are also subtracting the last number (0 - 1 -2 - 5), but from what I can tell from your question, you want to add it (0 - 1 -2 + 5). My solution is to add another argument specifying the number of digits so that you know when to add instead of subtract
int RecursiveMath::restaDigitos(int n, int numDigits){
if (n == 0) {
return 0;
} else if (n / (pow(10, numDigits - 1)) >= 1){
return restaDigitos(n/10, numDigits) + n % 10;
} else {
return restaDigitos(n / 10, numDigits) - n % 10;
}
}
You are processing the first value differently that the others. Such a use case leads to tricky recursion ways, using default parameters or static values for one shot solutions.
Here you could use:
int restaDigitos(int val, bool first = true, int curr = 0) {
if (val == 0) return curr;
if (first) curr = val%10;
else curr -= val%10;
return restaDigitos(val/10, false, curr);
}
You can control that restaDigitos(125); gives as expected 2.