Interview: Adding two binary numbers given as strings [closed] - c++

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
While looking through some interview questions at http://www.glassdoor.com/Interview/Facebook-Interview-Questions-E40772.htm I came across the following question:
Given two string representations of binary numbers (e.g. "1001", "10") write a function that adds them and returns the result as a string as well (e.g. "1011").
Here's some Python code that I started to write for the problem (it is incomplete right now), but I am not very sure if this is the best (or even correct) approach. I also thought about implementing the same in C++ first, but gave up considering the added complexities in string manipulations.
def add_binary(a,b):
temp = ""
carry = false
//i from len(a) to 1 and j from len(b) to 1
bit_sum = add_bit ((a[i],b[j])
if (bit_sum == "10"):
temp.append("0")
carry = true
elif carry:
temp.append(add_bit("1",bit_sum))
else:
temp.append(bit_sum)
return temp.reverse()
def add_bit(b1, b2):
if b1 == '0':
return b2
elif b2 == '0':
return b1
elif (b1 = '1' and b2 =='1'):
return "10"
else return None
a = "1001"
b = "10"
add_binary(a,b)

First, if the strings are short enough (less than 64 bits), I'd
probably just convert them to an internal integral type
(unsigned long long), do the addition there, and then
reconvert the results. Converting between binary strings and
internal format is really, really trivial.
Otherwise, I'd probably first normallize them so that they have
the maximum length of the results. Something like:
size_t size = std::max( lhs.size(), rhs.size() ) + 1;
lhs.insert( lhs.begin(), size - lhs.size(), '0' );
rhs.insert( rhs.begin(), size - rhs.size(), '0' );
I'd also create a results string of this size:
std::string results( size, '0' );
And a carry variable, initialized to '0':
char carry = '0';
I'd then loop over the three strings, using reverse iterators,
or more likely, just an index (which will ensure accessing the
same element of each string):
size_t current = size;
while ( current != 0 ) {
-- current;
// ...
}
With in the loop, you really only have four possibilities: I'd
just count the '1's (in lhs[current], rhs[current] and
carry), and do a switch on the results, setting
results[current] and carry appropriately:
int onesCount = 0;
if ( carry == '1' ) {
++ onesCount;
}
if ( lhs[current] == '1' ) {
++ onesCount;
}
if ( rhs[current] == '1' ) {
++ onesCount;
}
swith ( onesCount ) {
case 0:
carry = '0';
results[current] = '0';
break;
case 1:
carry = '0';
results[current] = '1';
break;
case 2:
carry = '1';
results[current] = '0';
break;
case 3:
carry = '1';
results[current] = '1';
break;
}
Personally, I think this is the simplest and the cleanest
solution, albeit a bit verbose. Alternatively, you can replace
the switch with something like:
results[current] = onesCount % 2 == 0 ? '0' : '1';
carry = onesCount < 2 ? '0' : '1';
Finally, if desired, you can suppress any leading zeros in the
results (there will be at most one), and maybe assert that
carry == '0' (because if it isn't, we've screwed up our
calculation of the size).

The most difficult part here is the fact that we need to process the strings from right to left. We can do this by either:
Reversing the strings (input and output).
In a recursive call, process the bits when "going back", i.e. first call a recursive add on the "next bits", then add the "current bit".
Use reverse iterators and construct the result from right to left. A problem will still be how to know the resulting length in advance (so you know where to start).
The recursive solution has problems when the numbers are large, i.e. the stack might overflow.
Reversing the strings is the easiest solution, yet not the most efficient one.
A combination of the first and third option would be to process the input strings in reverse using reverse iterators, but construct the result in reverse order (so you can simply append bits), then reverse the result.
This is more or less also your approach. Implement the loop counting i and j from the string length minus 1 (!) until 0, so this will walk through the input strings in reverse order. If carry was set to true, add one to the bit sum in the next iteration. Represent the bit sum of add_bit as an integer, not as a string again, so you can add the carry.
In C++, you have the possibility to iterate through any sequence in reverse order using rbegin() and rend().

in Python you can convert strings to integers with int, which also allows a base for conversion:
num = '111'
print int(num, 2)
prints 7.
For converting the result back to binary:
print "{:b}".format(4)
prints 100

Related

How to sort non-numeric strings by converting them to integers? Is there a way to convert strings to unique integers while being ordered?

I am trying to convert strings to integers and sort them based on the integer value. These values should be unique to the string, no other string should be able to produce the same value. And if a string1 is bigger than string2, its integer value should be greater. Ex: since "orange" > "apple", "orange" should have a greater integer value. How can I do this?
I know there are an infinite number of possibilities between just 'a' and 'b' but I am not trying to fit every single possibility into a number. I am just trying to possibly sort, let say 1 million values, not an infinite amount.
I was able to get the values to be unique using the following:
long int order = 0;
for (auto letter : word)
order = order * 26 + letter - 'a' + 1;
return order;
but this obviously does not work since the value for "apple" will be greater than the value for "z".
This is not a homework assignment or a puzzle, this is something I thought of myself. Your help is appreciated, thank you!
You are almost there ... just a minor tweaks are needed:
you are multiplying by 26
however you have letters (a..z) and empty space so you should multiply by 27 instead !!!
Add zeropading
in order to make starting letter the most significant digit you should zeropad/align the strings to common length... if you are using 32bit integers then max size of string is:
floor(log27(2^32)) = 6
floor(32/log2(27)) = 6
Here small example:
int lexhash(char *s)
{
int i,h;
for (h=0,i=0;i<6;i++) // process string
{
if (s[i]==0) break;
h*=27;
h+=s[i]-'a'+1;
}
for (;i<6;i++) h*=27; // zeropad missing letters
return h;
}
returning these:
14348907 a
28697814 b
43046721 c
373071582 z
15470838 abc
358171551 xyz
23175774 apple
224829626 orange
ordered by hash:
14348907 a
15470838 abc
23175774 apple
28697814 b
43046721 c
224829626 orange
358171551 xyz
373071582 z
This will handle all lowercase a..z strings up to 6 characters length which is:
26^6 + 26^5 +26^4 + 26^3 + 26^2 + 26^1 = 321272406 possibilities
For more just use bigger bitwidth for the hash. Do not forget to use unsigned type if you use the highest bit of it too (not the case for 32bit)
You can use position of char:
std::string s("apple");
int result = 0;
for (size_t i = 0; i < s.size(); ++i)
result += (s[i] - 'a') * static_cast<int>(i + 1);
return result;
By the way, you are trying to get something very similar to hash function.

I just created an extremely fast way to sort primes. How do I improve it?

Basically, how it works is it converts a number into a string, and if it finds any even in the string then it gives foundEven variable a positive value. The same goes for odd numbers.
(One thing I don't get is why if I switch the '>' sign with an '<' in if (FoundEvenSignedInt < FoundOddSignedInt) it gives you the correct result of an odd number.)
Are there any ways I could improve the code? Are there any bugs in it? I'm fairly new at C++ programing.
#include <string>
#include <cstddef>
int IsPrime(long double a)
{
int var;
long double AVar = a;
signed int FoundEvenSignedInt, FoundOddSignedInt;
std::string str = std::to_string(a);
std::size_t foundEven = str.find_last_of("2468");
std::size_t foundOdd = str.find_last_of("3579");
FoundEvenSignedInt = foundEven;
FoundOddSignedInt = foundOdd;
if (FoundEvenSignedInt < FoundOddSignedInt)
{
var = 1;
goto EndOfIsPrimeFunction;
}
if (FoundEvenSignedInt > FoundOddSignedInt)
{
var = 2;
goto EndOfIsPrimeFunction;
}
// This if statement kept giving me this weird warning so I made it like this
if (FoundEvenSignedInt == -1)
{
if (FoundOddSignedInt == -1)
{
if (AVar == 10 || 100 || 1000 || 10000 || 100000 || 1000000)
{
var = 2;
goto EndOfIsPrimeFunction;
}
}
}
EndOfIsPrimeFunction:
return var;
}
Here are some ways to improve the code.
The Collatz conjecture is about integers. long double is a data type of floating point numbers. It is unsuitable for checking the conjecture. You need to work with an integral data type such as unsigned long long. If this doesn't have enough range for you, you need to work with some kind of Bignum dat atype. There isn't any in the standard C library, you need to find a third party one.
The Collatz conjecture has nothing to do with being prime. It is about even and odd integers. It is true that all prime numbers except 2 are odd, but this fact doesn't help you.
The data type to answer yes/no questions in C++ is bool. By convention. for any other numeric data type zero means "no" and all other values mean "yes" (technically, when converted to bool, zero is converted to false and other values to true, so you can do things like if (a % 2). A function that returns 1 and 2 for yes and no is highly unconventional.
A natural method of checking whether a number is odd is this:
bool isOdd (unsigned long long a)
{
return a % 2;
}
It is somewhat faster than your code (by a factor of about 400 on my computer), gives correct results every time, is readable, and has zero goto statements.
Instead of the if(AVar == 10 || 100 || ..., you can say if(!(AVar % 10)).

Separating every second digit in an integer C++

I am currently finishing up an assignment I have to complete for my OOP class and I am struggling with 1 part in particular. Keep in mind I am still a beginner. The question is as followed:
If the string contains 13 characters, all of characters are digits and the check digit is modulo 10, this function returns true; false otherwise.
This is in regards to a EAN. I basically have to separate every second digit from the rest digits. for example 9780003194876 I need to do calculations with 7,0,0,1,4,7. I have no clue about doing this.
Any help would be greatly appreciated!
bool isValid(const char* str){
if (atoi(str) == 13){
}
return false;
}
You can start with a for loop which increments itself by 2 for each execution:
for (int i = 1, len = strlen(str); i < len; i += 2)
{
int digit = str[i] - '0';
// do something with digit
}
The above is just an example though...
Since the question was tagged as C++ (Not C, so I suggest other answerers to not solve this using C libraries, please. Let us getting OP's C++ knoweledge in the right way since the beggining), and is an OOP class I'm going to solve this with the C++ way: Use the std::string class:
bool is_valid( const std::string& str )
{
if( str.size() == 13 )
{
for( std::size_t i = 0 ; i < 13 ; i += 2 )
{
int digit = str[i] - '0';
//Do what you wan't with the digit
}
}
else
return false;
}
First, if it's EAN, you have to process every digit, not just
every other one. In fact, all you need to do is a weighted sum
of the digits; for EAN-13, the weigths alternate between 1 and
3, starting with three. The simplest solution is probably to
put them in a table (i.e. int weigt[] = { 1, 3, 1, 3... };,
and iterate over the string (in this case, using an index rather
than iterators, since you want to be able to index into
weight as well), converting each digit into a numerical value
(str[i] - '0', if isdigit(static_cast<unsigned char>(str[i])
is true; if it's false, you haven't got a digi.), then
multiplying it by the running total. When you're finished, if
the total, modulo 10, is 0, it's correct. Otherwise, it isn't.
You certainly don't want to use atoi, since you don't want the
numerical value of the string; you want to treat each digit
separately.
Just for the record, professionally, I'd write something like:
bool
isValidEAN13( std::string const& value )
{
return value.size() == 13
&& std::find_if(
value.begin(),
value.end(),
[]( unsigned char ch ){ return !isdigit( ch ); } )
== value.end()
&& calculateEAN13( value ) == value.back() - '0';
}
where calculateEAN13 does the actual calculations (and can be
used for both generation and checking). I suspect that this
goes beyond the goal of the assignment, however, and that all
your teacher is looking for is the calculateEAN13 function,
with the last check (which is why I'm not giving it in full).

c++ string compare algorithm [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
what is your best string comparison algorithm?
i find O(n)
#include <string>
bool str_cpmr(char* str1, char* str2)
{
int l1 = strlen(str1), l2 = strlen(str2) ;
if(l1 != l2)
return false;
for(int i = 0 ; i < l1 ; i++)
if(str1[i] != str2[i])
return false ;
return true ;
}
and i wonder if there is any other / better solution.
also, how to test that accurately?
i propose to compare
100 matches
100 strings differing by one char swap
is there more to test string compare ?
how is it in stl c++ (slt string::compare) ?
thanks!!!!!
You function is O(n), but still takes roughly double the time necessary -- strlen walks through the string to find the length, then (assuming they're the same length) you walk through the strings again comparing the characters.
Instead of that, I'd walk through the strings until you reach a mismatch or the end of both strings. If you reach a mismatch, you return false. You return true if and only if you reach the end of both strings (simultaneously) without any mismatches first.
Logically it's hard to see how you can check all the values in a string for a single char mismatch in less than O(n) time - assuming you have no other info about the string.
If this is a real application and you have some knowledge of the strngs and the type of differences you could do better on average by checking every Nth char first if you know that it contains sequences of length 'N' eg part or phone numbers.
edit: Note this is still O(n), O() only describes the power of the scaling, it would just be O(n/N) which is still O(n). If you make the string 10x longer checking every Nth entry still takes 10x as long.
what is your best string comparison algorithm?
template< class T, class Alloc >
bool operator==( basic_string<T,Alloc>& lhs, basic_string<T,Alloc>& rhs );.
It compares two strings using only two characters of source code:
a==b;
Here's a non-smartalec answer, written in C:
bool str_cpmr(char* str1, char* str2)
{
while( *str1 && *str2 && *str1++ == *str2++ )
;
return *str1 == *str2;
}
It is exactly one loop, so it is obviously O(n), where n goes as length of the shorter string. Also, it is likely to compile to exactly 2n memory fetches. You can go faster with specialized string instructions (so calling strcmp() will probably go faster than this), but you probably won't go faster in straight C.
Your improved function might look like this:
bool str_cpmr(char* str1, char* str2)
{
if (NULL == str1 || NULL == str2) return false;
while (*str1 && *str2) {
if (*str1++ != *str2++) {
return false;
}
}
return *str1 || *str2 ? false : true;
}
If there is no additional information on the nature of the strings, there is nothing that can be better than O(n), where n is the length of the (shorter) string.
You cannot do with less than n comparisons! Give me an algorithm that can do it with n-1 comparisons. Then there must be a position in the string where the algorithm cannot tell if the characters are different or not. That way I can give you an example where you algorithm with n-1 comparisons fails.
You can only improve this by a constant factor. This will also take into account additional information, e.g. if you know that the underlying hardware compares 32-bit values faster than 8-bit values, then it will better to compare chunks of four characters instead of comparing character by character. You will not do much better.

Reading variable length user input in C++

How do I read in a variable number of characters? The user can input a positive or negative number that is too big to be stored in an integer. I am then checking to make sure the char is a number and storing it in an array of ints (although that will probably be changed to a short since I only need to be able to store 0-9).
istream& operator>>(istream &in, LargeInt &l)
{
char x;
do
{
cin >> x;
int v = (int)x;
switch( v )
{
case 48: v = 0;
case 49: v = 1;
case 50: v = 2;
case 51: v = 3;
case 52: v = 4;
case 53: v = 5;
case 54: v = 6;
case 55: v = 7;
case 56: v = 8;
case 57: v = 9;
default: v=10 /* END INPUT */;
}
l.largeInt[ l.usedLength ] = v;
l.usedLength++;
//need to check array length and make bigger if needed
}
while( (x == 45) || ((x > 47) && (x < 57)) );
}
If you wish to read digits, you need to do it a character at a time. E.g.
char ch;
while (std::cin.get(ch) && ch >= '0' && ch <= '9') {
// You have a digit to process (maybe you want to push_back it into a vector)
}
Notice that you need to use ch - '0' to get the value of the digit because ch contains the character code rather than the value. In ASCII this means that '0' is in fact 48, '1' is 49 and so on (and 'A' is 65). The values may be different for different character encodings but the digits are guaranteed by the standard to be sequential, so that subtracting zero works.
Why not input a string, and then convert it to a number?
A few points. First of all, if you only need to store values from 0 to 9, you might as well store them in a char (which is just a small integer type in C++).
Second, you probably need to add a break; to the end of all the cases in your switch statement -- in C++, execution falls through from one case to the next without a break to stop it. Then again, you should probably just get rid of the switch statement entirely. You'd probably be better off using isdigit from <ctype.h>. Since char is a small integer type in C++, you can also do math on it, so you could just subtract '0' from each digit after verifying that it is a digit. Edit: contrary to the later edit, I would strongly advise against subtracting 48 from each digit. First of all, it's not guaranteed to work (and won't with some character sets -- even if you don't think your code will ever be used on an IBM mainframe, it's a poor habit). Second, it makes the intent much more apparent. I don't think there's a good reason to expect the reader to have memorized the ASCII table so they'll know that 48 is equivalent to '0'.
Finally, to deal with the problem you knew you had, you'll probably want to look up std::vector.