This is for my "Intro to C++" course. I need to
Write a program that uses a recursive function double_all_digit that doubles all digit from an integer. For example, double_all_digits(101) will return 110011
My code below works for only one digit; I have no idea how to proceed:
int double_all_digit(int x)
{
if(x < 10)
return (x*10) + x;
}
You have the base case; now for the recursion.
split the number into the 1's digit (use modulus) and the rest.
recur on the rest; your result is that number with all the digits doubled.
multiply that result by 100; add 11 times the 1's digit.
return this value up one level.
Here's a strategy:
convert a digit to a string. (use std::to_string)
iterate over characters in the string and append 2 characters in a new string for each character in the original. (See std::string::append)
convert the resulting string to an integer.
Since it's homework, you'll have to do the coding bit. :)
Related
I'm new to competitive programming and I've seen people not using conventional I/O stream such cin or scanf() rather they define their own function to take inputs. There is one such function that I've come across many times and I do not get the code. Here it is
int get(){
char ch;
while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
if (ch=='-'){
int s=0;
while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
return -s;
}
int s=ch-'0';
while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
return s;
}
what does this getchar() function really does and what is the whole point of this entire function. I guess this must be to optimize the code for taking large inputs but how is it done.
this must be a silly question for the experienced people but since I'm a newbie any help would be appreciated.
while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
skips all input until 0,1,2,3,4,5,6,7,8,9 or - is read
if (ch=='-'){
If a negative sign is read, continue reading digits:
int s=0;
Start with a sum of zero
while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
While reading digits, keep accumulating the sum by moving the previous 1 decimal to the left (multiply by 10) and adding the next digit (subtracting ascii value of 0 leaves '0' -> 0, '1' -> 1 etc).
return -s;
Returns the sum, but negative.
If the negation sign wasn't there, we do EXACTLY the same, but return positive.
NOTES
There is no parsing delimiters, embedded space, positive signs (+123), neither is there any range/overflow checking. Notable quirk: "aaaaa -" will be parsed as 0
Conclusion:
Do not do this. Use scanf or int i; if (std::cin >> i) { /*something*/ }
So I'm making a binary->decimal program where i need to target a specific digit in the number which is inputed, so for instance if the input is 100110110, how do i target the fourth digit, in this case obviously being 1, and the fifth, sixth, ... how many ever digits there are?
If the input is a binary string, store the input in a string and process it using a loop
string num = "1001010";
int l = num.length();
for(int i=0; i<l; i++) {
// num[i] is the (i+1)th bit from left;
}
how many ever digits there are?
these are called bits. To find number of bits in a variable use sizeof operator that returns number of bytes.
sizeof(variable) * 8
how do i target the fourth digit
you can test a bit with operator&:
if (8 == (variable & 8))
...
There are already detailed answers on how to do that: How do you set, clear, and toggle a single bit in C/C++?
I think the question is simple enough to understand.For more clarity I'm giving example :
In the list of 2 digit palindromes, the 7th palindrome is 77 (1st being 11, 2nd being 22 and so on).
Obviously a brute force solution exists but it's not efficient.
Can anyone suggest me some better solution to solve the problem ?
First, we can simplify the problem because we only need to look at the first half of the digits (rounding up if there are an odd number of digits). I will call the first set of digits significant digits and the rest non-significant digits.
This is because the non-significant digits must match the significant digits (in reverse). It is not possible to have another palindrome number with the same leading significant digits and different non-significant digits. The significant digits determine the entire palindrome number.
Now, we just need to come up with an algorithm to generate the nth valid significant digits. This would be easier if we allowed for leading zeros, so we'll come up with the algorithm that allows for leading zeros, then tweak the algorithm.
The first few palindromes (significant digits) would be:
1: 0000
2: 0001
3: 0002
...
100: 0099
So we can find the significant digits of the nth number by finding the decimal representation of (n-1).
To tweak the algorithm to work when not allowing leading zeros, we would start with a one as the leading digit:
1: 1000
2: 1001
3: 1002
...
100: 1099
This boils down to finding the decimal representation of (n-1) + 1000 = n + 999 and expanding into a full palindrome:
Example: Find the 113th palindrome of length 9.
Determine number of digits to look at: Round up(9 / 2) = 5 --> only look at first 5 digits.
Find number to add to get rid of leading zeros: 10^(5-1) = 10000
Use formula: (113 - 1) + 10000 = 10112
Expanded into palindrome: 101121101
On a side note, this algorithm could also be generalized to finding the nth palindrome of any ordered set of symbols (or alphabet).
Generalized algorithm:
Given: finding palindrome number n , palindrome has m symbols as digits , there are p symbols (10 symbols in decimal)
Let q = ceiling(m / 2)
Let offset = p ^ (q - 1)
Let number = (n - 1) + offset
Let answer be number expanded as a palindrome
The first few 7-digit palindrome are:
1000001
1001001
1002001
1003001
...
1009001
1010101
1011101
...
I think it's very easy to see from the pattern of what is the nth m-digit palindrome...
When the number of digits is even, just take the nth number with half as many digits starting from 100..0, where the length is half the number of digits. The palindrome is just this number followed by its mirror.
For an odd number of digits, just take the ceiling of half that number, and count from 100...0 the same way. Then the palindrome is this number followed by its mirror with the first digit removed.
The 65th 10 digit number:
65 + 9999 = 10064
1006446001
The 10298th 13 digit number:
10298 + 999999 = 1010297
1010297920101
For two digit palindromes the difference between two consecutive palindromes is 11.
something like:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
void reverseString(char *dest,char *src){
char *iter=src;
while (*iter) iter++;
while (iter!=src){
iter--;
*dest=*iter;
dest++;
}
*dest=0;
}
char *pal(int n,int len){
char *tmp=new char[len/2+2];
char *out=new char[len+1];
sprintf(out,"%i",n+int(pow(10.0,(len+1)/2-1))-1);
reverseString(tmp,out); //copy reversed out into tmp
strcat(out,tmp+len%2);
delete []tmp;
return out;
}
int main(){
cout<<pal(4,7)<<endl;
}
Trying to understand radix sort for my data structures class. My teacher showed us a sample of radix sort in C++. I don't understand what the for loop for the digits does, she said something about maximum digits. Also when I try this in VS it says log10 is an ambiguous call to an overloaded function.
void RadixSort(int A[], int size)
{
int d = 1;
for(int i = 0; i < size; ++i)
{
int digits_temp;
digits_temp=(int)log10(abs(A[i]!=0 ? abs(A[i]) : 1)) +1;
if(digits_temp > d)
d = digits_temp;
}
d += 1;
*rest of the implementation*
}
Can anyone explain what this for loop does and why i get that ambiguous call error? Thanks
That piece of code is just a search for the number of digits needed for the "longest" integer; that's probably needed to allocate some buffer later.
log10 gives you the power of ten that corresponds to its argument, which, rounded to the next integer (hence the +1 followed by the (int) cast, which results in truncation), gives you the number of digits required for the number.
The argument of log10 is a bit of a mess, since abs is called twice when just once would suffice. Still, the idea is to pass to log10 the absolute value of the number being examined if it's not zero, or 1 if it is zero - this because, if the argument were zero, the logarithm would diverge to minus infinity (which is not desirable in this case, I think that the conversion to int would lead to strange results).
The rest of the loop is just the search for the maximum: at each iteration it calculates the digits needed for the current int being examined, checks if it's bigger than the "current maximum" (d) and, if it is, it replaces the "current maximum".
The d+=1 may be for cautionary purposes (?) or for the null-terminator of the string being allocated, it depends on how d is used afterward.
As for the "ambiguous call" error: you get it because you are calling log10 with an int argument, which can be converted equally to float, double and long double (all types for which log10 is overloaded), so the overload to choose is not clear to the compiler. Just stick a (double) cast before the whole log10 argument.
By the way, that code could have been simplified/optimized by just looking for the maximum int (in absolute value) and then taking the base-10 logarithm to discover the number of digits needed.
Log base 10 + 1 gives you the total number of digits present in a number.
Essentially here, you are checking every element in the array A[] and if the element is == 0 you store 1 in the digits_temp variable.
You initialize d = 1 as a number should have atleast 1 digit, and if it has more than 1 you replace it with the number of digits calculated.
Hope that helps.
There are 3 types of definition for log10 function which are float,double,long double input.
log10( static_cast<double> (abs(A[i]!=0 ? abs(A[i]) : 1)) );
So you need to static cast it as double to avoid the error.
(int)log10(x)+1 gives the number of digit present in that number.
Rest is simple implementation of Radix Sort
You see the warning because log10 is defined for float, double and long double but not integer and it's being called with a integer. The compiler can convert the int into any of those types so the call is ambiguous.
The for loop is doing a linear search for the maximum of digits in any of the numbers in the array. It is unnecessarily complicated and slow because you can simply searched for the largest absolute value in A then taken the log10 of that.
void RadixSort(int A[], int size)
{
int max_abs = 1;
for(int i = 0; i < size; ++i)
{
if(abs(A[i] > max_abs)
max_abs = abs(A[i]);
}
int d += log10(float(max_abs));
/* rest of the implementation */
}
Rest of code is missing so cant exactly determined usage.
But basically Radix sort goes over all INTEGERS and sort them comparing Digit Digit starting from least significant upwards.
the first part of code only determines the max digit count+1 from integers in array, this could be used to normalize all numbers to same length for easy handling.
i.e (1,239,2134) to (0001,0239,2134)
I was studying hash-based sort and I found that using prime numbers in a hash function is considered a good idea, because multiplying each character of the key by a prime number and adding the results up would produce a unique value (because primes are unique) and a prime number like 31 would produce better distribution of keys.
key(s)=s[0]*31(len–1)+s[1]*31(len–2)+ ... +s[len–1]
Sample code:
public int hashCode( )
{
int h = hash;
if (h == 0)
{
for (int i = 0; i < chars.length; i++)
{
h = MULT*h + chars[i];
}
hash = h;
}
return h;
}
I would like to understand why the use of even numbers for multiplying each character is a bad idea in the context of this explanation below (found on another forum; it sounds like a good explanation, but I'm failing to grasp it). If the reasoning below is not valid, I would appreciate a simpler explanation.
Suppose MULT were 26, and consider
hashing a hundred-character string.
How much influence does the string's
first character have on the final
value of 'h'? The first character's value
will have been multiplied by MULT 99
times, so if the arithmetic were done
in infinite precision the value would
consist of some jumble of bits
followed by 99 low-order zero bits --
each time you multiply by MULT you
introduce another low-order zero,
right? The computer's finite
arithmetic just chops away all the
excess high-order bits, so the first
character's actual contribution to 'h'
is ... precisely zero! The 'h' value
depends only on the rightmost 32
string characters (assuming a 32-bit
int), and even then things are not
wonderful: the first of those final 32
bytes influences only the leftmost bit
of `h' and has no effect on the
remaining 31. Clearly, an even-valued
MULT is a poor idea.
I think it's easier to see if you use 2 instead of 26. They both have the same effect on the lowest-order bit of h. Consider a 33 character string of some character c followed by 32 zero bytes (for illustrative purposes). Since the string isn't wholly null you'd hope the hash would be nonzero.
For the first character, your computed hash h is equal to c[0]. For the second character, you take h * 2 + c[1]. So now h is 2*c[0]. For the third character h is now h*2 + c[2] which works out to 4*c[0]. Repeat this 30 more times, and you can see that the multiplier uses more bits than are available in your destination, meaning effectively c[0] had no impact on the final hash at all.
The end math works out exactly the same with a different multiplier like 26, except that the intermediate hashes will modulo 2^32 every so often during the process. Since 26 is even it still adds one 0 bit to the low end each iteration.
This hash can be described like this (here ^ is exponentiation, not xor).
hash(string) = sum_over_i(s[i] * MULT^(strlen(s) - i - 1)) % (2^32).
Look at the contribution of the first character. It's
(s[0] * MULT^(strlen(s) - 1)) % (2^32).
If the string is long enough (strlen(s) > 32) then this is zero.
Other people have posted the answer -- if you use an even multiple, then only the last characters in the string matter for computing the hash, as the early character's influence will have shifted out of the register.
Now lets consider what happens when you use a multiplier like 31. Well, 31 is 32-1 or 2^5 - 1. So when you use that, your final hash value will be:
\sum{c_i 2^{5(len-i)} - \sum{c_i}
unfortunately stackoverflow doesn't understad TeX math notation, so the above is hard to understand, but its two summations over the characters in the string, where the first one shifts each character by 5 bits for each subsequent character in the string. So using a 32-bit machine, that will shift off the top for all except the last seven characters of the string.
The upshot of this is that using a multiplier of 31 means that while characters other than the last seven have an effect on the string, its completely independent of their order. If you take two strings that have the same last 7 characters, for which the other characters also the same but in a different order, you'll get the same hash for both. You'll also get the same hash for things like "az" and "by" other than in the last 7 chars.
So using a prime multiplier, while much better than an even multiplier, is still not very good. Better is to use a rotate instruction, which shifts the bits back into the bottom when they shift out the top. Something like:
public unisgned hashCode(string chars)
{
unsigned h = 0;
for (int i = 0; i < chars.length; i++) {
h = (h<<5) + (h>>27); // ROL by 5, assuming 32 bits here
h += chars[i];
}
return h;
}
Of course, this depends on your compiler being smart enough to recognize the idiom for a rotate instruction and turn it into a single instruction for maximum efficiency.
This also still has the problem that swapping 32-character blocks in the string will give the same hash value, so its far from strong, but probably adequate for most non-cryptographic purposes
would produce a unique value
Stop right there. Hashes are not unique. A good hash algorithm will minimize collisions, but the pigeonhole principle assures us that perfectly avoiding collisions is not possible (for any datatype with non-trivial information content).