I want to change the condition, but I can't - c++

Problem: Children are taught to add multi-digit numbers from right to left, one digit at a time. Many find the “carry” operation, where a 1 is carried from one digit position to the next, to be a significant challenge. Your job is to count the number of carry operations for each for a set of addition problems so that educators my assess their difficulty.
Input: Each line of input contains two unsigned integers less than 10 digits. The last line of input contains “0 “0.
Input Examples: For each line of input except the last, compute the number of carry operations that result from adding the two numbers and print them in the format shown below.
This is the original code that satisfies inputs which are less than 10 digits
#include <iostream>
#include <cstdio>
#include <cstdlib>
int main(void){
unsigned int n1, n2, remain_n1, remain_n2, carry;
while(1)
{
std::cin >> n1 >> n2;
if(n1 == 0 && n2 == 0)
break;
int carry = 0;
int count = 0;
int sum = 0;
while(n1 != 0 || n2 != 0)
{
remain_n1 = n1 % 10;
remain_n2 = n2 % 10;
if(carry == 1)
remain_n1++;
sum = remain_n1 + remain_n2;
carry = 0;
if(sum >= 10){
carry = carry + 1;
count = count + 1;
}
n1 = n1 / 10;
n2 = n2 / 10;
}
if(count == 0)
std::cout << "No carry operation." << std::endl;
else if(count == 1)
std::cout << count << " " << "carry operation" << std::endl;
else
std::cout << count << " " << "carry operations" << std::endl;
}
return 0;
}
The problem input says less than 10 digits, but I want to change to satisfy the condition whatever input comes. And this is my code. How should I fix this?
std:;string n1, n2;
while(1){
std:;cint >> n1 >> n2;
if(n1 == "0" && n2 == "0")
break;
int max_len = n1.szie();
if (max_len < n2.size())
max_len = n2.size();
int nn1[max_len] - {0);
int nn2[max_len] = {0};
for(int i = 0; i < n1.size(); i++)
nn1[max_len - n1.size() + i]; = n1[i] - '0';
}

You don't need any extra storage for numbers, you can use the strings' digits directly and convert as you go.
Something like this, perhaps:
std::cin >> a >> b;
int carry = 0;
int count = 0;
// Iterate in reverse.
for (auto ia = a.rbegin(), ib = b.rbegin(); ia != a.rend() && ib != b.rend(); ++ia, ++ib)
{
int sum = (*ia - '0') + (*ib - '0') + carry;
carry = sum >= 10;
count += carry;
}

Related

Finding Twos complement,

Here is the code to compute: anyone, with help to convert a signed integer to its binary equivalent (8 bits) (in 2's complement) and vice versa. The program should be able t0 first read in either a signed integer or a binary number (always in 2's complement) provided by the user
For example, when I input 00110101 to convert to signed decimal, I will get 203. But the correct answer is 53.
#include <iostream>
#include <string>
using namespace std;
string decimalToBinary(int);
string findTwosComplement(string);
string decimalToBinary(int n) {
if (n < 0)
n = 256 + n;
string res = "";
while (n > 0)
{
res = string(1, (char)(n % 2 + 48)) + res;
n = n / 2;
}
return res;
}
string decimalToBinary(int n) {
if (n < 0)
n = 256 + n;
string res = "";
while (n > 0)
{
res = string(1, (char)(n % 2 + 48)) + res;
n = n / 2;
}
return res;
}
string findTwosComplement(string s)
{
int num = s.length();
int i;
for (i = num - 1; i >= 0; i--)
if (s[i] == '1')
break;
if (i == -1)
return '1' + s;
for (int j = i - 1; j >= 0; j--)
{
if (s[j] == '1')
s[j] = '0';
else
s[j] = '1';
}
return s;
}
I am assuming you want this for didactic purpose, other wise you just do (signed char) n.
The two complements is -2<<(n-1) + sum(2<<k for 0 <= k < n-1) so for 8-bit you have the usual binary representation for the numbers 0 <= N < 128 the difference is that the most significant bit is not adding 128, but subtracting 128. This is why it can represent numbers -128 <= N < 128. Important thing is that you can increase the width of the number by replicating the signal digit. C++ numbers are already 2-complements 32-bit numbers, so for the numbers in the valid range the 24 most significant bits are either all '0' or all '1', so you can just slice the bits there.
#include <iostream>
#include <string>
using namespace std;
string decimalToBinary(int n) {
// C++ integers are already in 2-complements so you only have to
// extract the bits.
if((n < -128) || (n >= 128)){
std::cerr << "The number "<< n << " does not fit into a 8-bit 2-complement representation" << std::endl;
}
string res = "";
for(int i = 0; i < 8; ++i){
res = string(1, (char)(((n >> i) & 1) + '0')) + res;
}
return res;
}
int binaryToDecimal(string s) {
// The most significant bit is the signal
int result = -((int)(s[0] - '0'));
for(int i = 1; i < s.size(); ++i){
result = 2*result + ((int)(s[i] - '0'));
}
return result;
}
int main(){
int input;
while(cin){
cout << "> ";
cin >> input;
string binary = decimalToBinary(input);
int output = binaryToDecimal(binary);
cout << input << " -> " << binary << " -> " << output << endl;
}
}

Addition of Array with different integer

Is there any way to add the sum of 2 binary numbers with this code ?
The end result I got when I add 12 and 24 is 010FF6F8(36). Which is different each time I add it up.
Everything works fine until the end when I wanted to add both of the binary numbers that I input into the sum of binary.
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int x1[10], x2[10], n1, n2, i, j, d1[10],d2[10];
int s1, s2;
cout << "\nEingabe Dezimalzahl 1 : ";
cin >> n1;
s1 = n1;
for (i = 0; n1 > 0; i++)
{
x1[i] = n1 % 2;
n1 = n1 / 2;
}
cout << "Dual : ";
for (i = i - 1; i >= 0; i--)
{
cout << x1[i];
d1[i] = x1[i];
}
cout << "\nEingabe Dezimalzahl 2 : ";
cin >> n2;
s2 = n2;
for (j = 0; n2 > 0; j++)
{
x2[j] = n2 % 2;
n2 = n2 / 2;
}
cout << "Dual : ";
for (j = j - 1; j >= 0; j--)
{
cout << x2[j];
d2[j] = x2[j];
}
cout << endl;
cout << "\nTest Addition und Zuweisung : \n";
cout << "-------------------------------\n";
int sumBin[10], sumDez;
int k = 0;
for (i = i - 1; i >= 0; i--)
{
for (j = j - 1; j >= 0; j--)
{
sumBin[k] = d1[i] + d2[j];
}
}
sumDez = s1 + s2;
cout << "zahl1 + zahl2 : " << sumBin << " (" << sumDez << ") \n";
}
I will paste now your source code with comments, where the errors are. I did this, while reading line by line. Without using a debugger.
I do strongly recommend that you do the same. Read line by line, and check what will happen.
Additionally. Please use a debugger. That will help you tremendously.
#include<iostream>
#include<cmath>
// Do not open the complete namespace
// Do not use this statement
using namespace std;
int main()
{
// You define a bunch of variables, which are not needed here
// Variables shall be defined, shortly before they are used
// And only in the scope, where they are elevant
// All variables shall be initialized. Always
// C-Style array shall be avoided, Used std::vector or std::array instead
// Magic numbers, like 10 shall be avoided. USe constexpr
int x1[10], x2[10], n1, n2, i, j, d1[10], d2[10];
int s1, s2;
cout << "\nEingabe Dezimalzahl 1 : ";
// Always check the result of an input operation. What if the user enters XXX
cin >> n1;
s1 = n1;
// This will work, but it is not the convential way for a for loop
for (i = 0; n1 > 0; i++)
{
x1[i] = n1 % 2;
n1 = n1 / 2;
}
// After this loop, i has a certain value
cout << "Dual : ";
// In this loop you decrement i
for (i = i - 1; i >= 0; i--)
{
cout << x1[i];
d1[i] = x1[i];
}
// And now, after this loop, i will be -1. Always
cout << "\nEingabe Dezimalzahl 2 : ";
cin >> n2;
s2 = n2;
// Same as above
for (j = 0; n2 > 0; j++)
{
x2[j] = n2 % 2;
n2 = n2 / 2;
}
cout << "Dual : ";
// Strange loop. Source of error. But will work here
for (j = j - 1; j >= 0; j--)
{
cout << x2[j];
d2[j] = x2[j];
}
// Now j is -1. Always
cout << endl;
cout << "\nTest Addition und Zuweisung : \n";
cout << "-------------------------------\n";
// Variable definition without initialization.
// Again. C-Style array and magic number
int sumBin[10], sumDez;
int k = 0;
// Remember from above? i is -1. Always.
// The following loop will never execute, becuase you set i to -2 in the beginning and then want to
// run the loop until i>=0. i is nver >= 0. The loop will not rund
for (i = i - 1; i >= 0; i--)
{
for (j = j - 1; j >= 0; j--)
{
sumBin[k] = d1[i] + d2[j];
}
}
sumDez = s1 + s2;
// std::cout cannot emit all avlues of the array. That you must do manually
cout << "zahl1 + zahl2 : " << sumBin << " (" << sumDez << ") \n";
}
Also you addition algorithm is not correct. You need to add bit by bit and include a carry over bit.
#include<iostream>
constexpr unsigned int MaxNumberOfBits = 128;
int main() {
// Inform user aout this program and what to do
std::cout << "\nSumming 2 number as binaries\n\nPlease enter 2 integer values:\n";
// Here we will store our 2 decimal numbers
unsigned int number1{};
unsigned int number2{};
// Read the 2 decimal numbers and check, if OK
if (std::cin >> number1 >> number2) {
// Ok, we read the 2 numbers. Now, we want to convert them to binary values
// Number 1. Resulting array to store value.
unsigned int binArray1[MaxNumberOfBits] = {};
// Bit index
unsigned int index1{};
// Process complete number 1
while ((number1 > 0) && (index1 < MaxNumberOfBits)) {
binArray1[index1] = number1 % 2;
number1 /= 2;
++index1;
}
// Number 2. Resulting array to store value.
unsigned int binArray2[MaxNumberOfBits] = {};
// Bit index
unsigned int index2{};
// Process complete number 1
while ((number2 > 0) && (index2 < MaxNumberOfBits)) {
binArray2[index2] = number2 % 2;
number2 /= 2;
++index2;
}
// Now, calculate the result. Here, we will store result
unsigned int binResult[MaxNumberOfBits+1] = {};
// Go over all bits
// Use carry bit
unsigned int carryBit{};
// Get maximunm index to avoid to do unessary work
const unsigned int maxIndex = ((index1 > index2) ? index1 : index2) + 1;
// Add all single bits
for (unsigned int i{}; i < maxIndex; ++i) {
// Add bit from each number + carry bit
binResult[i] = binArray1[i] + binArray2[i] + carryBit;
// Calculate the carray bit
carryBit = (binResult[i] > 1) ? 1U : 0U;
// Handle overflow
binResult[i] %= 2;
}
// Output in reverse order
std::cout << "\nResult: ";
for (unsigned int i{ maxIndex+1 }; i > 0; --i) {
std::cout << binResult[i-1];
}
std::cout << "\n\n";
}
else {
std::cerr << "\n\n*** Error: Could not read the 2 integers\n";
}
return 0;
}
1.
for (i = i - 1; i >= 0; i--)
{
for (j = j - 1; j >= 0; j--)
{
sumBin[k] = d1[i] + d2[j];
}
}
The i and j in this loop are both -1, so they did not enter the loop.
2.
cout << "zahl1 + zahl2 : " << sumBin << " (" << sumDez << ") \n";
The sumBin you output is the address, not the content. So the value is different every time。

Are there any exceptions that I may have missed in this problem?

Recently I've been working on this problem on SPOJ:
Given a set of N integers A = {1, 2, 3, …, N} and an integer S, your task is find a way to insert an operator '+' or '-' to every neighbor pair of A, that the result of the expression after insert equal to S.
WARNING: You can't put any operators in front of 1.
Input:
A single line, including N and S (1 ≤ N ≤ 500, |S| ≤ 125250)
Output:
If there are way(s) to insert, output any of them, otherwise output “Impossible” (without quotes).
Example:
Input:
9 5
Output:
1-2+3-4+5-6+7-8+9
Input:
5 6
Output:
Impossible
I've already been messing up with these code, but SPOJ always yields that I've done this problem in the wrong way. I think there might be exceptions that I haven't found out.
int main()
{
int n;
cin >> n;
int a[501] = { };
int sum = 0;
for (int i = 1; i <= n; i++)
{
a[i] = 1;
sum += i;
}
int s;
cin >> s;
int aim = sum - s;
if ((aim % 2 != 0) || (s < -sum + 2) || (s > sum) || (s == -sum + 4) || (s == sum - 1))
{
cout << "Impossible" << endl;
return 0;
}
int c = n;
while (aim != 0)
{
if (aim >= c)
{
if (aim - 2 * c != 2)
{
aim -= (2 * c);
a[c] = -1;
c--;
}
else
{
a[c - 1] = -1;
a[2] = -1;
aim -= (2 * c + 2);
}
}
else
{
a[aim / 2] = -1;
aim = 0;
}
}
for (int i = 1; i <= n; i++)
if (a[i] == 1)
if (i == 1)
cout << i;
else
cout << "+" << i;
else
cout << "-" << i;
return 0;
}
You are subtracting 2 * c from aim after checking if aim >= c.
Changing the check to aim >= 2 * c will improve your program.

C++ : Why do I have to add a boolean expression?

The code is:
int main() {
int n, largest = 1;
cout << "enter :" << endl;
cin >> n;
int i = n - 1;
while(i > 0) {
if (n % i == 0){
largest = i;
}
i--;
}
cout << largest << endl;
system("pause");
return 0;
}
Why do these error occur? This code keeps making errors and my professor said that I should add a boolean expression. But I do not know why and where I have to add it?
(Inspired by Alexandrescu's CppCon 2019 talk)
Recall, that the control check on the loop is not necessary - we know that X % 1 is 0 for any X. Also, in-line with Alexandrescu's commitment to endless loops, we could rewrite the loop as following (it will have an added bonus of making it correct, but also will improve it's performance):
if (n <= 1) {
return;
}
largest = n - 1;
for (;; --largest) {
if (n % largest == 0)
break;
}
// Here largest is usable
Rewrite this loop
while( i > 0){
if ( n % i == 0){
largest = i;
}
i --;
}
for example like
while( i > 0 && n % i != 0 ) i--;
if ( i ) largest = i;
Also instead of the type int you should use the type unsigned int. Otherwise the user can enter a negative number. In this case the loop does not make sense.
Using your approach the program can look for example the following way
#include <iostream>
int main()
{
unsigned int n = 0, largest = 1;
std::cout << "enter a non-negative number: ";
std::cin >> n;
if ( n != 0 )
{
unsigned int i = n - 1;
while ( i > 0 && n % i != 0 ) i--;
if ( i ) largest = i;
}
std::cout << "The largest own divisor is " << largest << std::endl;
return 0;
}

C++ binary input as a string to a decimal

I am trying to write a code that takes a binary number input as a string and will only accept 1's or 0's if not there should be an error message displayed. Then it should go through a loop digit by digit to convert the binary number as a string to decimal. I cant seem to get it right I have the fact that it will only accept 1's or 0's correct. But then when it gets into the calculations something messes up and I cant seem to get it correct. Currently this is the closest I believe I have to getting it working. could anyone give me a hint or help me with what i am doing wrong?
#include <iostream>
#include <string>
using namespace std;
string a;
int input();
int main()
{
input();
int decimal, x= 0, length, total = 0;
length = a.length();
// atempting to make it put the digits through a formula backwords.
for (int i = length; i >= 0; i--)
{
// Trying to make it only add the 2^x if the number is 1
if (a[i] = '1')
{
//should make total equal to the old total plus 2^x if a[i] = 1
total = total + pow(x,2);
}
//trying to let the power start at 0 and go up each run of the loop
x++;
}
cout << endl << total;
int stop;
cin >> stop;
return 0;
}
int input()
{
int x, x2, count, repeat = 0;
while (repeat == 0)
{
cout << "Enter a string representing a binary number => ";
cin >> a;
count = a.length();
for (x = 0; x < count; x++)
{
if (a[x] != '0' && a[x] != '1')
{
cout << a << " is not a string representing a binary number>" << endl;
repeat = 0;
break;
}
else
repeat = 1;
}
}
return 0;
}
I don't think that pow suits for integer calculation. In this case, you can use shift operator.
a[i] = '1' sets the value of a[i] to '1' and return '1', which is always true.
You shouldn't access a[length], which should be meaningless.
fixed code:
int main()
{
input();
int decimal, x= 0, length, total = 0;
length = a.length();
// atempting to make it put the digits through a formula backwords.
for (int i = length - 1; i >= 0; i--)
{
// Trying to make it only add the 2^x if the number is 1
if (a[i] == '1')
{
//should make total equal to the old total plus 2^x if a[i] = 1
total = total + (1 << x);
}
//trying to let the power start at 0 and go up each run of the loop
x++;
}
cout << endl << total;
int stop;
cin >> stop;
return 0;
}
I would use this approach...
#include <iostream>
using namespace std;
int main()
{
string str{ "10110011" }; // max length can be sizeof(int) X 8
int dec = 0, mask = 1;
for (int i = str.length() - 1; i >= 0; i--) {
if (str[i] == '1') {
dec |= mask;
}
mask <<= 1;
}
cout << "Decimal number is: " << dec;
// system("pause");
return 0;
}
Works for binary strings up to 32 bits. Swap out integer for long to get 64 bits.
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
string getBinaryString(int value, unsigned int length, bool reverse) {
string output = string(length, '0');
if (!reverse) {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << i)) != 0) {
output[i] = '1';
}
}
}
else {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << (length - i - 1))) != 0) {
output[i] = '1';
}
}
}
return output;
}
unsigned long getInteger(const string& input, size_t lsbindex, size_t msbindex) {
unsigned long val = 0;
unsigned int offset = 0;
if (lsbindex > msbindex) {
size_t length = lsbindex - msbindex;
for (size_t i = msbindex; i <= lsbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << (length - offset));
}
}
}
else { //lsbindex < msbindex
for (size_t i = lsbindex; i <= msbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << offset);
}
}
}
return val;
}
int main() {
int value = 23;
cout << value << ": " << getBinaryString(value, 5, false) << endl;
string str = "01011";
cout << str << ": " << getInteger(str, 1, 3) << endl;
}
I see multiple misstages in your code.
Your for-loop should start at i = length - 1 instead of i = length.
a[i] = '1' sets a[i] to '1' and does not compare it.
pow(x,2) means and not . pow is also not designed for integer operations. Use 2*2*... or 1<<e instead.
Also there are shorter ways to achieve it. Here is a example how I would do it:
std::size_t fromBinaryString(const std::string &str)
{
std::size_t result = 0;
for (std::size_t i = 0; i < str.size(); ++i)
{
// '0' - '0' == 0 and '1' - '0' == 1.
// If you don't want to assume that, you can use if or switch
result = (result << 1) + str[i] - '0';
}
return result;
}