Related
I'm trying to print the numbers from 1 to N in lexicographic order, but I get a failed output. for the following input 100, I get the 100, but its shifted and it doesn't match with the expected output, there is a bug in my code but I can not retrace it.
class Solution {
public:
vector<int> lexicalOrder(int n) {
vector<int> result;
for(int i = 1; i <= 9; i ++){
int j = 1;
while( j <= n){
for(int m = 0; m < j ; ++ m){
if(m + j * i <= n){
result.push_back(m+j*i);
}
}
j *= 10;
}
}
return result;
}
};
Input:
100
Output:
[1,10,11,12,13,14,15,16,17,18,19,100,2,20,21,22,23,24,25,26,27,28,29,3,30,31,32,33,34,35,36,37,38,39,4,40,41,42,43,44,45,46,47,48,49,5,50,51,52,53,54,55,56,57,58,59,6,60,61,62,63,64,65,66,67,68,69,7,70,71,72,73,74,75,76,77,78,79,8,80,81,82,83,84,85,86,87,88,89,9,90,91,92,93,94,95,96,97,98,99]
Expected:
[1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,22,23,24,25,26,27,28,29,3,30,31,32,33,34,35,36,37,38,39,4,40,41,42,43,44,45,46,47
Think about when i=1,j=10 what will happen in
for(int m = 0; m < j ; ++ m){
if(m + j * i <= n){
result.push_back(m+j*i);
}
}
Yes,result will push_back 10(0+10*1),11(1+10*1),12(2+10*1)..
Here is a solution:
#include <iostream>
#include <vector>
#include <string>
std::vector<int> fun(int n)
{
std::vector<std::string> result;
for (int i = 1; i <= n; ++i) {
result.push_back(std::to_string(i));
}
std::sort(result.begin(),result.end());
std::vector<int> ret;
for (auto i : result) {
ret.push_back(std::stoi(i));
}
return ret;
}
int main(int argc, char *argv[])
{
std::vector<int> result = fun(100);
for (auto i : result) {
std::cout << i << ",";
}
std::cout << std::endl;
return 0;
}
You are looping through all 2 digit numbers starting with 1 before outputting the first 3 digit number, so your approach won't work.
One way to do this is to output the digits in base 11, padded out with leading spaces to the maximum number of digits, in this case 3. Output 0 as a space, 1 as 0, 2 as 1 etc. Reject any numbers that have any non-trailing spaces in this representation, or are greater than n when interpreted as a base 10 number. It should be possible to jump past multiple rejects at once, but that's an unnecessary optimization. Keep a count of the numbers you have output and stop when it reaches n. This will give you a lexicographical ordering in base 10.
Example implementation that uses O(1) space, where you don't have to generate and sort all the numbers up front before you can output the first one:
void oneToNLexicographical(int n)
{
if(n < 1) return;
// count max digits
int digits = 1, m = n, max_digit11 = 1, max_digit10 = 1;
while(m >= 10)
{
m /= 10; digits++; max_digit11 *= 11; max_digit10 *= 10;
}
int count = 0;
bool found_n = false;
// count up starting from max_digit * 2 (first valid value with no leading spaces)
for(int i = max_digit11 * 2; ; i++)
{
int val = 0, trailing_spaces = 0;
int place_val11 = max_digit11, place_val10 = max_digit10;
// bool valid_spaces = true;
for(int d = 0; d < digits; d++)
{
int base11digit = (i / place_val11) % 11;
if(base11digit == 0)
{
trailing_spaces++;
val /= 10;
}
else
{
// if we got a non-space after a space, it's invalid
// if(trailing_spaces > 0)
// {
// valid_spaces = false;
// break; // trailing spaces only
// }
val += (base11digit - 1) * place_val10;
}
place_val11 /= 11;
place_val10 /= 10;
}
// if(valid_spaces && (val <= n))
{
cout << val << ", ";
count++;
}
if(val == n)
{
found_n = true;
i += 10 - (i % 11); // skip to next number with one trailing space
}
// skip past invalid numbers:
// if there are multiple trailing spaces then the next run of numbers will have spaces in the middle - invalid
if(trailing_spaces > 1)
i += (int)pow(11, trailing_spaces - 1) - 1;
// if we have already output the max number, then all remaining numbers
// with the max number of digits will be greater than n
else if(found_n && (trailing_spaces == 1))
i += 10;
if(count == n)
break;
}
}
This skips past all invalid numbers, so it's not necessary to test valid_spaces before outputting each.
The inner loop can be removed by doing the base11 -> base 10 conversion using differences, making the algorithm O(N) - the inner while loop tends towards a constant:
int val = max_digit10;
for(int i = max_digit11 * 2; ; i++)
{
int trailing_spaces = 0, pow11 = 1, pow10 = 1;
int j = i;
while((j % 11) == 0)
{
trailing_spaces++;
pow11 *= 11;
pow10 *= 10;
j /= 11;
}
int output_val = val / pow10;
if(output_val <= n)
{
cout << output_val << ", ";
count++;
}
if(output_val == n)
found_n = true;
if(trailing_spaces > 1)
{
i += (pow11 / 11) - 1;
}
else if(found_n && (trailing_spaces == 1))
{
i += 10;
val += 10;
}
else if(trailing_spaces == 0)
val++;
if(count == n)
break;
}
Demonstration
The alternative, simpler approach is just to generate N strings from the numbers and sort them.
Maybe more general solution?
#include <vector>
#include <algorithm>
using namespace std;
// returns true is i1 < i2 according to lexical order
bool lexicalLess(int i1, int i2)
{
int base1 = 1;
int base2 = 1;
for (int c = i1/10; c > 0; c/=10) base1 *= 10;
for (int c = i2/10; c > 0; c/=10) base2 *= 10;
while (base1 > 0 && base2 > 0) {
int d1 = i1 / base1;
int d2 = i2 / base2;
if (d1 != d2) return (d1 < d2);
i1 %= base1;
i2 %= base2;
base1 /= 10;
base2 /= 10;
}
return (base1 < base2);
}
vector<int> lexicalOrder(int n) {
vector<int> result;
for (int i = 1; i <= n; ++i) result.push_back(i);
sort(result.begin(), result.end(), lexicalLess);
return result;
}
The other idea for lexicalLess(...) is to convert integers to string before comparision:
#include <vector>
#include <algorithm>
#include <string>
#include <boost/lexical_cast.hpp>
using namespace std;
// returns true is i1 < i2 according to lexical order
bool lexicalLess(int i1, int i2)
{
string s1 = boost::lexical_cast<string>(i1);
string s2 = boost::lexical_cast<string>(i2);
return (s1 , s2);
}
You need Boost to run the second version.
An easy one to implement is to convert numbers to string, them sort the array of strings with std::sort in algorithm header, that sorts strings in lexicographical order, then again turn numbers to integer
Make a vector of integers you want to sort lexicographically, name it numbers.
Make an other vector and populate it strings of numbers in the first vector. name it strs.
Sort strs array.4. Convert strings of strs vector to integers and put it in vectors
List item
#include <cstdlib>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
string int_to_string(int x){
string ret;
while(x > 0){
ret.push_back('0' + x % 10);
x /= 10;
}
reverse(ret.begin(), ret.end());
return ret;
}
int main(){
vector<int> ints;
ints.push_back(1);
ints.push_back(2);
ints.push_back(100);
vector<string> strs;
for(int i = 0; i < ints.size(); i++){
strs.push_back(int_to_string((ints[i])));
}
sort(strs.begin(), strs.end());
vector<int> sorted_ints;
for(int i = 0; i < strs.size(); i++){
sorted_ints.push_back(atoi(strs[i].c_str()));
}
for(int i = 0; i < sorted_ints.size(); i++){
cout<<sorted_ints[i]<<endl;
}
}
As the numbers are unique from 1 to n, you can use a set of size n and insert all of them into it and then print them out.
set will automatically keep them sorted in lexicographical order if you store the numbers as a string.
Here is the code, short and simple:
void lexicographicalOrder(int n){
set<string> ans;
for(int i = 1; i <= n; i++)
ans.insert(to_string(i));
for(auto ele : ans)
cout <<ele <<"\n";
}
I am programming a solution to the problem http://acmph.blogspot.com/2010/12/usaco-prime-cryptarithm.html
and when I run it on my computer, given the input data
7
4 1 2 5 6 7 3
My computer gives me an answer of 384 which is the right answer. But when I upload it to USACO site, it says that my program outputs 1. Why does this happen?
Here is my code:
/*
ID: harry47341
PROG: crypt1
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> digits;
int a, b, c, d, e, abc, de;
bool oneof1(int n) {
int count1 = 1;
while (true) {
if (count1 > n)break;
else {
count1 = count1 * 10;
int digit = n%count1 / (count1 / 10);
if (!count(digits.begin(), digits.end(), digit) ){
return false;
}
n = n - n%count1;
}
}
}
bool check() {
int n = abc*e;
int n1 = abc*d;
if (n > 999 || n < 100)return false;
if (n1 > 999 || n1 < 100)return false;
if ((n1 * 10 + n) > 9999 || (n1 * 10 + n) < 1000)return false;
if (oneof1(n) && oneof1(n1) && oneof1(n1 * 10 + n)) {
return true;
}
}
int main() {
ofstream fout("crypt1.out");
ifstream fin("crypt1.in");
int count = 0;
int n;
fin >> n;
for (int i = 0; i < n; i++) {
int f;
fin >> f;
digits.push_back(f);
}
for (int i = 0; i < n; i++) {
a = digits[i];
for (int i1 = 0; i1 < n; i1++) {
b = digits[i1];
for (int i2 = 0; i2 < n; i2++) {
c = digits[i2];
for (int i3 = 0; i3 < n; i3++) {
d = digits[i3];
for (int i4 = 0; i4 < n; i4++) {
e = digits[i4];
abc = a * 100 + b * 10 + c;
de = d * 10 + e;
if (check()) {
count++;
}
}
}
}
}
}
fout << count << endl;
return 0;
}
In your oneof1 and check functions, you do not return a value for all the return paths in the function. Thus your program exhibits undefined behavior, since returning nothing from a function that returns a value is UB. That's why you were getting different answers when run on a different computer / system.
To fix the issue, return true in the oneof1 function, and return false for the check function:
bool oneof1(int n) {
int count1 = 1;
while (true) {
if (count1 > n)break;
else {
count1 = count1 * 10;
int digit = n%count1 / (count1 / 10);
if (!count(digits.begin(), digits.end(), digit) ){
return false;
}
n = n - n%count1;
}
}
return true; // this was missing
}
bool check() {
int n = abc*e;
int n1 = abc*d;
if (n > 999 || n < 100)return false;
if (n1 > 999 || n1 < 100)return false;
if ((n1 * 10 + n) > 9999 || (n1 * 10 + n) < 1000)return false;
if (oneof1(n) && oneof1(n1) && oneof1(n1 * 10 + n)) {
return true;
}
return false; // this was missing
}
Most compilers have a warning when you write a function that doesn't return a value for all return paths. Please set your warnings to at least to the level that gives this information (or if you did, read the warnings that your compiler is giving you).
I have a function counter(string s1, string s2) which takes two strings (both size 4) of numbers as its parameters. s1 is randomly generated while s2 is user-input.
int counter(string s1, string s2){
int count = 0;
int i, j;
if(i != j){
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(s2[i] != s2[j] && s2[j] == s1[i]){
count += 1;
}
}
}
}
return count;
}
What this function does is compare each element of s2 to s1's. If an element of s2 is equal to an element of s1, provided that they do not have the same index or position, count increments by 1. The function, however, encounters problems when s2 contains duplicates. For example, if s1 = 1234 and s2 = 4445, the output should be 1, but my program outputs 3. How should I be able to detect the duplicates in the string?
Forgot to mention this, but s1 (the randomly generated string) has distinct characters.
This would solve the problem you have when the same letter is present in S2 several times.
int counter(string s1, string s2){
int count = 0;
int i, j;
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(i != j){
if(s2[j] == s1[i]){
count += 1;
break; // Break out of inner for-loop
// to avoid counting letters twice
}
}
}
}
return count;
}
However, I'm not sure what you want the program to do in case the same letter is present in S1 several times.
EDIT:
After reading some of the clarifications in the comments, the if-statement should be
if(s2[i] != s2[j] && s2[j] == s1[i]){
like in the original post.
I dare suggest. But I broke my brain your question =)
int counter(string s1, string s2){
int count = 0;
for(int i = 0; i < s1.length(); ++i)
{
string::size_type loc = s2.find(s1[i], 0);
while (loc != string::npos)
{
if(loc != i)
++count;
loc = s2.find(s1[i], loc + 1);
}
}
return count;
}
add your if condition inside the for loop,
int counter(string s1, string s2){
int count = 0;
int i, j;
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(i!=j && s2[j] == s1[i]){
count += 1;
}
}
}
}
return count;
}
You can detect duplicate elements by implementing Levenshtein distance algorithms.
int levenshtein(const char *s, int ls, const char *t, int lt){
int a, b, c;
/* if either string is empty, difference is inserting all chars
* from the other
*/
if (!ls) return lt;
if (!lt) return ls;
/* if last letters are the same, the difference is whatever is
* required to edit the rest of the strings
*/
if (s[ls] == t[ls])
return levenshtein(s, ls - 1, t, lt - 1);
/* else try:
* changing last letter of s to that of t; or
* remove last letter of s; or
* remove last letter of t,
* any of which is 1 edit plus editing the rest of the strings
*/
a = levenshtein(s, ls - 1, t, lt - 1);
b = levenshtein(s, ls, t, lt - 1);
c = levenshtein(s, ls - 1, t, lt );
if (a > b) a = b;
if (a > c) a = c;
return a + 1;}
So I have to solve one USACO problem involving computing all the primes <= 100M and printing these of them which are palindromes while the restrictions are 16MB memory and 1 sec executions time. So I had to make a lot of optimisations.
Please take a look at the following block of code:
for(int i = 0; i < all.size(); ++i)
{
if(all[i] < a) continue;
else if(all[i] > b) break;
if(isPrime(all[i]))
{
char buffer[50];
//toString(all[i], buffer);
int c = all[i];
log10(2);
buffer[3] = 2;
//buffer[(int)log10(all[i])+1] = '\n';
//buffer[(int)log10(all[i])+2] = '\0';
//fputs(buffer, pFile);
}
}
Now, it executes in the satisfying 0.5 sec range, but when I change log10(2) to log10(all[i]) it skyrockets nearly to 2 seconds! For no apparent reason. I'm assigning all[i] to the variable c and it doesn't slow down the execution at all, but when I pass all[i] as parameter, it makes the code 4 times slower! Any ideas why this is happening and how I can fix it?
Whole code:
/*
ID: xxxxxxxx
PROG: pprime
LANG: C++11
*/
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <cstring>
#include <algorithm>
#include <list>
#include <ctime>
#include <cstdio>
using namespace std;
typedef struct number Number;
ifstream fin("pprime.in");
ofstream fout("pprime.out");
int MAXN = 100000000;
unsigned short bits[2000000] = {};
vector<int> primes;
vector<int> all;
int a, b;
short getBit(int atPos)
{
int whichNumber = (atPos-1) / 16;
int atWhichPosInTheNumber = (atPos-1) % 16;
return ((bits[whichNumber] & (1 << atWhichPosInTheNumber)) >> atWhichPosInTheNumber);
}
void setBit(int atPos)
{
int whichNumber = (atPos-1) / 16;
int atWhichPosInTheNumber = (atPos-1) % 16;
int old = bits[whichNumber];
bits[whichNumber] = bits[whichNumber] | (1 << atWhichPosInTheNumber);
}
void calcSieve()
{
for(int i = 2; i < MAXN; ++i)
{
if(getBit(i) == 0)
{
for(int j = 2*i; j <= (MAXN); j += i)
{
setBit(j);
}
primes.push_back(i);
}
}
}
int toInt(list<short> integer)
{
int number = 0;
while(!integer.empty())
{
int current = integer.front();
integer.pop_front();
number = number * 10 + current;
}
return number;
}
void toString(int number, char buffer[])
{
int i = 0;
while(number != 0)
{
buffer[i] = number % 10 + '0';
number /= 10;
}
}
void DFS(list<short> integer, int N, int atLeast)
{
if(integer.size() > N)
{
return;
}
if(!(integer.size() > 0 && (integer.front() == 0 || integer.back() % 2 == 0)) && atLeast <= integer.size())
{
int toI = toInt(integer);
if(toI <= b) all.push_back(toInt(integer));
}
for(short i = 0; i <= 9; ++i)
{
integer.push_back(i);
integer.push_front(i);
DFS(integer, N, atLeast);
integer.pop_back();
integer.pop_front();
}
}
bool isPrime(int number)
{
for(int i = 0; i < primes.size() && number > primes[i]; ++i)
{
if(number % primes[i] == 0) return false;
}
return true;
}
int main()
{
int t = clock();
ios::sync_with_stdio(false);
fin >> a >> b;
MAXN = min(MAXN, b);
int N = (int)log10(b) + 1;
int atLeast = (int)log10(a) + 1;
for(short i = 0; i <= 9; ++i)
{
list<short> current;
current.push_back(i);
DFS(current, N, atLeast);
}
list<short> empty;
DFS(empty, N, atLeast);
sort(all.begin(), all.end());
//calcSieve
calcSieve();
//
string output = "";
int ends = clock() - t;
cout<<"Exexution time: "<<((float)ends)/CLOCKS_PER_SEC<<" seconds";
cout<<"\nsize: "<<all.size()<<endl;
FILE* pFile;
pFile = fopen("pprime.out", "w");
for(int i = 0; i < all.size(); ++i)
{
if(all[i] < a) continue;
else if(all[i] > b) break;
if(isPrime(all[i]))
{
char buffer[50];
//toString(all[i], buffer);
int c = all[i];
log10(c);
buffer[3] = 2;
//buffer[(int)log10(all[i])+1] = '\n';
//buffer[(int)log10(all[i])+2] = '\0';
//fputs(buffer, pFile);
}
}
ends = clock() - t;
cout<<"\nExexution time: "<<((float)ends)/CLOCKS_PER_SEC<<" seconds";
ends = clock() - t;
cout<<"\nExexution time: "<<((float)ends)/CLOCKS_PER_SEC<<" seconds";
fclose(pFile);
//fout<<output;
return 0;
}
I think you've done this backwards. It seems odd to generate all the possible palindromes (if that's what DFS actually does... that function confuses me) and then check which of them are prime. Especially since you have to generate the primes anyway.
The other thing is that you are doing a linear search in isPrime, which is not taking advantage of the fact that the array is sorted. Use a binary search instead.
And also, using list instead of vector for your DFS function will hurt your runtime. Try using a deque.
Now, all that said, I think that you should do this the other way around. There are a huge number of palindromes that won't be prime. What's the point in generating them? A simple stack is all you need to check if a number is a palindrome. Like this:
bool IsPalindrome( unsigned int val )
{
int digits[10];
int multiplier = 1;
int *d = digits;
// Add half of number's digits to a stack
while( multiplier < val ) {
*d++ = val % 10;
val /= 10;
multiplier *= 10;
}
// Adjust for odd-length palindrome
if( val * 10 < multiplier ) --d;
// Check remaining digits
while( val != 0 ) {
if(*(--d) != val % 10) return false;
val /= 10;
}
return true;
}
This avoids the need to call log10 at all, as well as eliminates all that palindrome generation. The sieve is pretty fast, and after that you'll only have a few thousand primes to test, most of which will not be palindromes.
Now your whole program becomes something like this:
calcSieve();
for( vector<int>::iterator it = primes.begin(); it != primes.end(); it++ ) {
if( IsPalindrome(*it) ) cout << *it << "\n";
}
One other thing to point out. Two things actually:
int MAXN = 100000000;
unsigned short bits[2000000] = {};
bits is too short to represent 100 million flags.
bits is uninitialised.
To address both these issues, try:
unsigned short bits[1 + MAXN / 16] = { 0 };
How would I add two binary numbers in C++? What is the correct logic?
Here is my effort, but it doesn't seem to be correct:
#include <iostream>
using namespace std;
int main()
{
int a[3];
int b[3];
int carry = 0;
int result[7];
a[0] = 1;
a[1] = 0;
a[2] = 0;
a[3] = 1;
b[0] = 1;
b[1] = 1;
b[2] = 1;
b[3] = 1;
for(int i = 0; i <= 3; i++)
{
if(a[i] + b[i] + carry == 0)
{
result[i] = 0;
carry = 0;
}
if(a[i] + b[i] + carry == 1)
{
result[i] = 0;
carry = 0;
}
if(a[i] + b[i] + carry == 2)
{
result[i] = 0;
carry = 1;
}
if(a[i] + b[i] + carry > 2)
{
result[i] = 1;
carry = 1;
}
}
for(int j = 0; j <= 7; j++)
{
cout<<result[j]<<" ";
}
system("pause");
}
Well, it is a pretty trivial problem.
How to add two binary numbers in c++. what is the logic of it.
For adding two binary numbers, a and b. You can use the following equations to do so.
sum = a xor b
carry = ab
This is the equation for a Half Adder.
Now to implement this, you may need to understand how a Full Adder works.
sum = a xor b xor c
carry = ab+bc+ca
Since you store your binary numbers in int array, you might want to understand bitwise operation.
You can use ^ for XOR,| operator for OR, & operator for AND.
Here is a sample code to calculate the sum.
for(i = 0; i < 8 ; i++){
sum[i] = ((a[i] ^ b[i]) ^ c); // c is carry
c = ((a[i] & b[i]) | (a[i] & c)) | (b[i] & c);
}
Since you were asking about C++, you deserve a C++ answer. Use bitsets:
#include <bitset>
#include <iostream>
int main() {
std::bitset<5> const a("1001");
std::bitset<5> const b("1111");
// m here is a mask to extract the lsb of a bitset.
std::bitset<5> const m("1");
std::bitset<5> result;
for (auto i = 0; i < result.size(); ++i) {
std::bitset<5> const diff(((a >> i)&m).to_ullong() + ((b >> i)&m).to_ullong() + (result >> i).to_ullong());
result ^= (diff ^ (result >> i)) << i;
}
std::cout << result << std::endl;
}
This works for arbitrarily long bit sets.
You could use "Bitwise OR" operation to reduce the code since
1 or 1 = 1
1 or 0 = 1
0 or 1 = 1
0 or 0 = 0
You could also convert both number to decimal sum and them go back to binary again.
Converting decimal to binary
int toBinary (unsigned int num, char b[32])
{
unsigned int x = INT_MIN; // (32bits)
int i = 0, count = 0;
while (x != 0)
{
if(x & num) // If the actual o bit is 1 & 1 = 1 otherwise = 0
{
b[i] = '1';
count++;
}
else b[i] = '0';
x >>=1; // pass to the left
i++;
}
return count;
}
There is a bug :
if(a[i]+b[i]+carry==1)
{
result[i]=1;
carry=0;
}
Also u might want to print in reverse
for(int j=6; j>=0; j--)
{
cout<<result[j]<<" ";
}
Your arrays are one item too small for your indexing.
int a[3] only has 3 elements, so a[3] = 1 is invalid (it has undefined behaviour) since it's accessing the 4th element, which doesn't exist.
Likewise for the other arrays.
That means that the whole program has undefined behaviour, i.e. it can do anything or nothing at all.
(What's probably happening in your case is that writing outside the arrays is overwriting the other variables.)
You're also not initialising the result array, so its content is just some random data.
Since you only update 4 of its elements but print all of them (and more), the output will be random data as well.
Following were the errors in your code and fixed code is also below"
int a[] was of size 3 so it cannot store at the 3rd index. use int a[4].
if(a[i]+b[i]+carry==1) wrong values were assigned in this check update result[i]=1; carry=0.
The sequence of checks is reversed.
The last carry was not stored in the result.
The addition result stored in the result array was in reverse order so printed it in reverse.
here is the working piece of code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a[4];
int b[4];
int carry=0;
int result[5];
a[0]=1;
a[1]=0;
a[2]=0;
a[3]=1;
b[0]=1;
b[1]=1;
b[2]=1;
b[3]=1;
for(int i=0; i<4; i++)
{
if(a[i]+b[i]+carry==3)
{
result[i]=1;
carry=1;
}
if(a[i]+b[i]+carry==2)
{
result[i]=0;
carry=1;
}
if(a[i]+b[i]+carry==1)
{
result[i]=1;
carry=0;
}
if(a[i]+b[i]+carry==0)
{
result[i]=0;
carry=0;
}
}
result[4]=carry;
for(int j=4; j>=0; j--)
{
cout<<result[j];
}
cout<<endl;
return 0;
}
#include <stdio.h>
int main()
{
long binary1, binary2;
int i = 0, remainder = 0, sum[20];
printf("Enter the first binary number: ");
scanf("%ld", &binary1);
printf("Enter the second binary number: ");
scanf("%ld", &binary2);
while (binary1 != 0 || binary2 != 0)
{
sum[i++] =(binary1 % 10 + binary2 % 10 + remainder) % 2;
remainder =(binary1 % 10 + binary2 % 10 + remainder) / 2;
binary1 = binary1 / 10;
binary2 = binary2 / 10;
}
if (remainder != 0)
sum[i++] = remainder;
--i;
printf("Sum of two binary numbers: ");
while (i >= 0)
printf("%d", sum[i--]);
getch();
return 0;
}
Repeatedly do
(x, y) <- ((x & y) << 1, x ^ y)
until x is 0. y is the answer.
you should do this
for(int i = 3; i >= 0; i--)
{
if(a[i] + b[i] + carry == 0)
{
result[i] = 0;
carry = 0;
}
else if(a[i]+b[i]+carry==1)
{
result[i]=1;
carry=0;
}
else if(a[i] + b[i] + carry == 2)
{
result[i] = 0;
carry = 1;
}
else if(a[i] + b[i] + carry > 2)
{
result[i] = 1;
carry = 1;
}
printf("%d",result[i]);
}
A non-conventional solution, but it works:
int main() {
int A[] = { 0, 0, 0, 1, 1, 0, 1, 0};
int B[] = { 0, 0, 0, 0, 1, 1, 0, 0};
int size = sizeof(A)/sizeof(*A);
int C[size+1];
int t = 0;
for(int i = size-1; i > -1; i--){
C[i+1] = A[i]+B[i]+t;
t = C[i+1]/2;
C[i+1] %= 2;
}
C[0] = t;
}
What if their sizes are not the same? Also, you would want to allow the user to input the binary numbers (in this case representing integers) as integers and not as elements of arrays. Here is a piece of code that accomplishes those :-)
#include <iostream>
using namespace std;
// Add two numbers in binary
void sumBinary(int num1, int num2, int* sum12){
int mod1 = 0;
int mod2 = 0;
int carry = 0;
int factor = 1;
int flag = 0;
*sum12 = 0;
while (!flag){
mod1 = num1 % 10;
mod2 = num2 % 10;
num1 /= 10;
num2 /= 10;
if ((carry + mod1 + mod2) == 2){
*sum12 += 0;
carry = 1;
}
else if ((carry + mod1 + mod2) == 3){
*sum12 += factor;
carry = 1;
}
else if ((carry + mod1 + mod2) == 0){
*sum12 += 0;
carry = 0;
}
else{
*sum12 += factor;
carry = 0;
}
factor *= 10;
if ((num1 == 0) && (num2 == 0)){
*sum12 += carry*factor;
flag = 1; }
}
}
void main(){
int num1, num2, sum12;
cout << "Enter the first binary integer number: ";
cin >> num1;
cout << "Enter the second binary integer number: ";
cin >> num2;
sumBinary(num1, num2, &sum12);
cout << "The sum in binary form is :" << sum12 << endl;
}
A simple way :
int getBit(string s, int index)
{
if(index >= 0) return (s[index] - '0');
else return 0;
}
string addBinary(string a, string b)
{
if(a.size() > b.size()) while(a.size() > b.size()) b = "0" + b;
else if(b.size() > a.size()) while(b.size() > a.size()) a = "0" + a;
int l = max(a.size()-1, b.size() - 1);
string result = "";
int s=0;
while(l>=0 || s==1)
{
s += getBit(a, l) + getBit(b, l) ;
result = char(s % 2 + '0') + result;
s /= 2;
l--;
}
return result;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0);
int num1=12, num2=45, sum=0;
bool b1, b2, carry=0;
for(int i=0;i<32;i++){
b1=( 1<<i ) & num1;
b2=( 1<<i ) & num2;
sum = (b1 ^ b2 ^ carry) ? sum ^ (1<<i) : sum;
carry = ((b1 & b2) | (b1 & carry) | (b2 & carry));
}
cout<<sum;
return 0;
}
Easy to understand code
Add Two Binary Numbers (input datatype = int)
#include <iostream>
using namespace std;
int power(int a, int b)
{
int ans = 1;
while (b)
{
ans *= a;
b--;
}
return ans;
}
int main()
{
int n1, n2, carry = 0, ans = 0, rem1, rem2, remsum = 0, i;
cout << "Enter First Number : ";
cin >> n1;
cout << "Enter Second Number : ";
cin >> n2;
for (i = 0; n1 != 0 || n2 != 0; i++, n1 /= 10, n2 /= 10)
{
rem1 = n1 % 10;
rem2 = n2 % 10;
remsum = rem1 + rem2 + carry;
if (remsum == 2)
{
carry = 1;
remsum = 0;
}
else if (remsum == 3)
{
carry = 1;
remsum = 1;
}
else if (remsum == 0)
{
carry = 0;
remsum = 0;
}
else if (remsum == 1)
{
carry = 0;
remsum = 1;
}
ans = remsum * power(10, i) + ans;
}
ans = carry * power(10, i) + ans;
cout << ans;
return 0;
}