Converting base 10 to 12, having trouble adding alphabet characters recursivly - c++

I'm having trouble using recursion to add letters to a base 10 - base 12 conversion. How would I go about adding letters into my function? I was thinking about adding an if statement in, but i have no idea where and how to go about this. pointers are appreciated Thanks!
Given a count from 1 to 12:
Dec 1 2 3 4 5 6 7 8 9 10 11 12
Duo 1 2 3 4 5 6 7 8 9 X E 10
my function:
template<class myType>
myType convertDec(myType number){
if(number == 0)
return number;
//if statement somewhere in here? not sure considering i can't touch the return statement
return (number % 12) + 10*convertDec(number / 12);
}
example ideal output:
65280 = 31940 (works fine)
2147483626 = 4EE23088X (doesnt work!)

#include <iostream>
#include <string>
using namespace std;
string ConvertToDuodecimal(unsigned long long n)
{
if (n < 12)
return string() + "0123456789XE"[n];
return ConvertToDuodecimal(n / 12) + ConvertToDuodecimal(n % 12);
}
int main()
{
cout << ConvertToDuodecimal(0) << endl;
cout << ConvertToDuodecimal(1) << endl;
cout << ConvertToDuodecimal(10) << endl;
cout << ConvertToDuodecimal(11) << endl;
cout << ConvertToDuodecimal(12) << endl;
cout << ConvertToDuodecimal(13) << endl;
cout << ConvertToDuodecimal(65280) << endl;
cout << ConvertToDuodecimal(2147483626) << endl;
return 0;
}
Output (ideone):
0
1
X
E
10
11
31940
4EE23088X

The base is a property of the way a number is displayed and nothing to do with it's internal representation. You need to write a function that prints a normal int using base 12.
a = 12; // A = 12 (in base 10)
printf("%d",a); // Prints a in base 10 (still 12)
printf("%x",a); // Prints a in base 16 (now C)
You code is changing the actual value, which isn't the right thing to do.
(and yes, before the pedants strike, printf isn't good C++...)

Related

C++ pushing back a string by value in a vector

I'm doing some algorithmics problem and I'm having trouble with managing functions, vectors and strings in C++.
I have to find a concrete path in a matrix and for that, I need to have all the different paths, so I decided to use a function. This function will check where to continue to search. Here is the code of the function:
vector<string> get_all_paths(string actual, int rows, int columns, int col_actual, int row_prev) {
vector<string> solutions;
int row_actual = (rows+row_prev-1)%rows;
for (int i = 0; i < 3; i++) {
cout << col_actual << " " << row_actual << "\n";
//cout << (dp[row_prev][col_actual+1] - matrix[row_prev][col_actual+1]) << " " << dp[row_actual][col_actual] << "\n";
if( (dp[row_prev][col_actual+1] - matrix[row_prev][col_actual+1]) == dp[row_actual][col_actual] ) {
if (col_actual > 0) {
//cout << "--" << actual << " " << row_actual << "\n";
string branch = actual + to_string(row_actual+1) + " ";
solutions = get_best_path(branch, rows, columns, col_actual-1, row_actual);
//cout << ".." << actual << "\n";
} else {
//cout << actual << " " << row_actual << "\n";
cout << actual << "\n";
string branch = actual.c_str();
branch += to_string(row_actual+1);
cout << branch << "\n";
solutions.push_back( branch );
break;
}
}
row_actual = (row_actual+1)%rows;
}
for(auto i : solutions) cout << "--" << i << "\n";
return solutions;
}
And here is the call to the method:
vector<string> solutions;
for (int i = 0; i < rows; i++) {
if (dp[i][cols-1] == min_path) {
cout << "................\n";
solutions = get_best_path( (to_string(i+1)+" "), rows, cols, cols-2, i);
for(auto i : solutions) {
reverse(i.begin(), i.end());
cout << i << "\n";
}
cout << "xxxxxxxxxxxxxxx\n";
}
}
The thing is that I'm getting three paths for a given example, which is correct, but they are all the same string, which is the last path or the last change done in variable branch.
Maybe I'm mixing a lot of concepts and maybe this has been answered a lot of times, but I've searched this and got nothing.
EDIT: I'm not getting three paths from the function, just the last one, but when printing inside the function the paths i do have three inside that function all with the same value, sorry about that.
EDIT2: The idea of the problem is to find the minimum cost path in a given matrix and, if there are more than 1, the one that is the smallest lexicographically. So given a matrix:
5 4
9 1 9 9
1 9 9 9
9 9 9 9
1 1 1 1
9 9 1 9
My approach is to use dp as a matrix with the dynamic programming results and then i try to recreate all the paths in the function above.
In this case, the dp matrix is:
9 2 11 12
1 10 11 20
9 10 11 12
1 2 3 4
9 10 3 12
And so, the best paths are:
4 4 4 4
4 5 4 4
2 1 5 4
And the one correct is the last one.
Inside my function i do get the different paths and i add them to the vector of results, but then i lose them when searching for more.
Thanks for the time if you have read this :D!
Well I think the problem is here
solutions = get_best_path(branch, rows, columns, col_actual-1, row_actual);
because that assignment replaces any solutions you might have found so far. Instead you should append any solutions returned to any that you've found so far. In other words something like this
vector<string> tmp = get_best_path(branch, rows, columns, col_actual-1, row_actual);
solutions.insert(solutions.end(), tmp.begin(), tmp.end());
But this is just intuition, I haven't tested anything.

Using CheckSum with C++ for 13 Digit ISBN

I am trying to calculate the final digit of a 13 digit ISBN using the first 12 digits using C++. I feel like my code should be correct but I have a feeling the formula I'm using may be wrong.
The formula is:
10 - (d0 + d1 * 3 + d2 + d3 * 3 + d4 + d5 * 3 + d6 + d7 * 3 + d8 + d9 * 3 + d10 + d11 * 3) % 10
Here's what I have:
#include <cstring>
#include <iostream>
int main() {
int weightedSum = 0;
int checksum = 0;
int i; //for loop decrement
int mul = 3;
const int LENGTH = 12;
char ISBNinput[LENGTH];
std::cout << "Enter first 12 digits of ISBN: "; //ask user for input
std::cin >> ISBNinput; //stores input into ISBNinput
std::cout << std::endl;
for (i = 0; i < strlen(ISBNinput); i++) {
weightedSum += (ISBNinput[i] % 12) * mul;
if (mul == 3) {
mul = 1;
} else {
mul = 3;
}
}//close for loop
checksum = weightedSum % 10; //calculates checksum from weightedSum
std::cout << checksum << std::endl; //prints checksum with new line for format
return 0;
}
For example:
978007063546 should return 3
and
978032133487 should return 9
Thank you for any help.
Here's how I go about this.
First, let's decide how we're going to test this. I'll assume that we've written the function, and that it gives the correct output. So I pick up a couple of books off my desk, and test that it works for them:
#include <iostream>
int main()
{
std::cout << "Book 1 - expect 3, got " << checksum("978032114653") << std::endl;
std::cout << "Book 2 - expect 0, got " << checksum("978020163361") << std::endl;
}
Of course, when we try to compile that, we get an error. So create the function, before main():
char checksum(const char *s)
{
return '1';
}
Now it compiles, but the result is always 1, but now we can start to fill in the body. Let's start with some smaller examples, that we can calculate by hand; add these at the beginning of main():
std::cout << "1 digit - expect 4, got " << checksum("6") << std::endl;
Now let's get this one working - this gives us conversion from character to digit and back, at least:
char checksum(const char *s)
{
int digit = *s - '0';
return '0' + 10 - digit;
}
Let's try 2 digits:
std::cout << "1 digit - expect 6, got " << checksum("11") << std::endl;
And now our test fails again. So add some more processing, to make this pass (and not break the single-digit test):
char checksum(const char *s)
{
int sum = 0;
int digit = *s - '0';
sum += digit;
++s;
if (*s) {
digit = *s - '0';
sum += 3 * digit;
}
return '0' + (10 - sum)%10;
}
We're probably ready to make this into a loop now. Once that's passed, we no longer need the short tests, and I have:
#include <iostream>
char checksum(const char *s)
{
int sum = 0;
for (int mul = 1; *s; ++s) {
int digit = *s - '0';
sum += mul * digit;
mul = 4 - mul;
}
return '0' + (1000 - sum)%10;
}
int test(const char *name, char expected, const char *input)
{
char actual = checksum(input);
if (actual == expected) {
std::cout << "PASS: " << name << ": "
<< input << " => " << actual
<< std::endl;
return 0;
} else {
std::cout << "FAIL: " << name << ": "
<< input << " => " << actual
<< " - expected " << expected
<< std::endl;
return 1;
}
}
int main()
{
int failures = 0;
failures += test("Book 1", '3', "978032114653");
failures += test("Book 2", '0', "978020163361");
return failures > 0;
}
I factored out the actual checking into a function here, so we can keep count of failures, and exit with the appropriate status, but everything else is as I described above.
You'll want to add a few more test cases - in particular, make sure the function correctly returns the extreme values 0 and 9 when it should.
There is one clear bug in your code: you are not allocating enough space in for ISBNinput. You should make it one character longer:
const int LENGTH = 13;
The reason for this is that that character-array strings are terminated with an extra null character. You might be lucky and the next byte in memory could sometimes happen to be a null byte, in which case the program would still work sometimes.
If you run the program with valgrind or a similar memory checker you are likely to see an error as the program access memory beyond what was allocated on the stack.
Also I think there is another bug. I think that mul should be initialized to 1.
By the way, this code is very fragile, depending on you entering no more than 12 characters, all of which are assumed to be digits. It might be OK as a quick hack for a proof-of-concept, but should not be used in any real program.

C++ rand() why give me the same number How can i have different [duplicate]

This question already has answers here:
Why do I always get the same sequence of random numbers with rand()?
(12 answers)
Closed 7 years ago.
if (ii == 3){//车辆只停了一个小时,有3/4的概率离场
srand((unsigned)time(NULL)*100);
int a = 1+rand() % 4;
int b = 1+rand() % 4;
int c = 1+rand() % 4;
cout << "++++3 " << a << "++++" << endl;//用作测试判断是否离场函数
cout << "++++3 " << b << "++++" << endl;
cout << "++++3 " << c << "++++" << endl;
cout << "*************" << endl;
if ((a == 1 && b == 2 && c == 3)||(a==2&&b==1&&c==3)||(a==3&&b==2&&c==1)||(a==3&&b==2&&c==1))
return true;
else
return false;
}
Just like this picture, the program gives me the same number ,but I need different numbers , how can I do it.
#ifndef Head_H
#define Head_H
#include<stdlib.h>
#include<iostream>
#include<time.h>
#define PathSize 5
#define ParkSize 10
#define Price 5
using namespace std;
srand((unsigned)time(NULL));
Use srand once, at the start of your program.
If you repeatedly re-seed the generator then you ruin its statistical properties.
Moving on:
Avoid using % to rescale the generator. This will introduce statistical bias (unless by pure luck the modulo is a multiple of RAND_MAX).
Look at the C++11 random number library. This contains better-specified generators than plain old rand, which is awful on some platforms.

Calculating modulus in a function gives different answer from using % operator directly [duplicate]

This question already has answers here:
Modulo operator with negative values [duplicate]
(3 answers)
Closed 9 years ago.
my_mod.cpp:
#include <iostream>
using namespace std;
unsigned int my_mod(int a, unsigned int b)
{
int result;
cout << "\ta\t=\t" << a << endl;
cout << "\tb\t=\t" << b << endl;
cout << "\ta%b\t=\t" << a%b << endl;
result = a%b;
if (result < 0) {result += b;}
return result;
}
int main()
{
cout << "-1%5 = " << -1%5 << endl;
cout << "my_mod(-1,5) = " << my_mod(-1,5) << endl;
return 0;
}
compiled via:
g++ ./my_mod.cpp
results in:
-1%5 = -1
a = -1
b = 5
a%b = 0
my_mod(-1,5) = 0
What the actual hell is happening here I just can't understand what possibly could go on?! This can't be due to the global scope, right?!
I mean it is exactly the same %-expression ... how can they yield 0 and -1?! (Instead of the desired 4, by the way.)
Please, if anybody can, explain this to me ... it just took me days to narrow down an error in a wider context to this. Seriously, I'm about to cry.
How can I have my (global) own modulus returning 4 in the example above??
It's because you're using an unsigned int, the signed int (-1) gets promoted to -1 % UINT_MAX so your operation becomes (-1 % UINT_MAX) % 5 = 0 (thanks to jrok for this more detailed reason)
try
cout << "\ta%b\t=\t" << a%(int)b << endl;
result = a%(int)b;
with function signature of: int my_mod(int a, unsigned int b)
Or just use a function signature of: int my_mod(int a, int b)

pointer c++ explanation

I am confused with this block of code:
ipPtr = ipPtr + 3; // 5
cout << *ipPtr << endl;
Why the cout is not 5 but some random large number? can anyone explain to me please. As my understanding I thought the cout << *ipPtr << endl; is pointed to the *ipPtr above it. Am I right ?
#include <iostream>
void main(){
using namespace std;
int iaArray[] = {1,2,3,4,5};
int* ipPtr = 0;
ipPtr = &(iaArray[1]);
cout << *ipPtr << endl;//2
++ipPtr;
cout << *ipPtr << endl;//3
ipPtr = ipPtr + 3; //not 5 but random number.
cout << *ipPtr << endl;
}
Because you have incremented the pointer past the end of the array. You seem to have forgotten that you wrote ++ipPtr before adding 3 to it.
&(iaArray[1])
|
iaArray = { 1, 2, 3, 4, 5 } ?
| |
++ipPtr ipPtr + 3
Because when you add 3 to the pointer it's already on the third position of the array, so it ends up after the last element.
ipPtr = &(iaArray[1]);
//Pointing to the second position (first one is 0)
++ipPtr;
//Pointing to the third position
//3 + 3 = 6
ipPtr = ipPtr + 3;
The array only has 5 positions so it prints whatever is in that memory location not 5 which is in the fifth position.