Overload operator [] - c++

I overloaded an operator [], but it's not working as I would like.
class A{
int *const e;
const int row, column;
public:
int rows() const
{
return row;
}
int columns() const
{
return column;
}
int size() const
{
return row * column;
}
A(int r, int c)
: row(r), column(c), e(new int[r*c])
{
for (int i = 0; i < r*c; i++)
{
e[i] = 0;
}
}
virtual int *const operator[ ](int r)
{
return &e[r*row];
}
}
For example:
If I wrote:
A a(2, 5)
a[0][0] = 1; // OK
a[0][1] = 2; // OK
a[0][2] = 3; // It's assigned a [0][2] == 3 but also [1][0] == 3
I could not find the problem. It should assigned a value 3 only to [0][2]
What's wrong with this code ?

Because a[0][2] and a[1][0] are one and the same. Let's see:
&e[r*row] is the same as &(*(e+(r*row))) (by definition of []) which is the same as (e+(r*row)).
If r is 0, this is just e, and if r is 1, this is (e+row). Which is, given that your row is 2, is e+2.
So a[0] returns e and a[1] returns e+2.
Now a[0][2] is (a[0])[2] is e[2], and a[1][0] is (e+2)[0] is e[2]. See? Same thing.
If row is the number of rows and column is the number of columns, as your intention seems to be, you are better off returning &e[r*column] from your operator[] (because the number of columns is the size of one row).

Related

Question about Dynamic memory allocation in C++ for 3D array

I want to write a fuction to creat a 3D Matrix,but I have a broblem when I try to display it,Please help me,Thanks.
My teacher gave me his codes.His codes can create a 2D array which has Dynamic memory, I want to change his codes to creat a 3D matrix. When I tried to display the Matrix,I realize the array I created is a 2D array,And Because I just begin to use C++,I can't find my mistake.
/*<Array3D.h>*/
#pragma once
#ifndef _ARRAY_3D_H_
#define _ARRAY_3D_H_
//-----------------------------------------
#include <cassert>
#include <vector>
using namespace std;
template<typename T>
class Array3D
{
public:
typedef Array3D<T> _Myt;
Array3D()
: m_nRows(0)
, m_nCols(0)
, m_nDepths(0)
{}
Array3D(size_t r, size_t c,size_t d)
{
Resize(r, c, d);
}
//Allocating memory size
void Resize(size_t r, size_t c,size_t d)
{
if (r == m_nRows && c == m_nCols && d==m_nDepths) { return; }
bool bValid = r > 0 && c > 0 && d>0;
if (!bValid) return;
m_nRows = r;
m_nCols = c;
m_nDepths = d;
m_v.resize(m_nRows * m_nCols * m_nDepths);
}
const T* operator[](size_t r) const
{
assert(r >= 0 && r < m_nRows);
return &(*(m_v.begin() + (r * m_nCols * m_nDepths)));
}
T* operator[](size_t r)
{
assert(r >= 0 && r < m_nRows);
return &(*(m_v.begin() + (r * m_nCols * m_nDepths)));
}
//Gets the start position of a one-dimensional array
const T* GetRawPointer() const { return &(m_v[0]); }
T* GetRawPointer() { return &(m_v[0]); }
long Rows() const
{
return static_cast<long>(m_nRows);
}
long Cols() const
{
return static_cast<long>(m_nCols);
}
long Depths() const
{
return static_cast<long>(m_nDepths);
}
long TotalSize() const
{
return static_cast<long>(m_nRows * m_nCols * m_nDepths);
}
void ClearUp()
{
m_nRows = 0;
m_nCols = 0;
m_nDepths = 0;
m_v.clear();
}
bool IsEmpty() const { return m_v.empty(); }
protected:
vector<T> m_v;// Internally a one-dimensional is used
size_t m_nRows;
size_t m_nCols;
size_t m_nDepths;
};
<Matrix3D.h>
#pragma once
#include "Array3D.h"
class Matrix3D
{
public:
Matrix3D(int r = 0, int c = 0, int d = 0)
{
setSize(r, c, d);
}
void setSize(int r, int c, int d) { m_data3D.Resize(r, c, d); }
void clear() { m_data3D.ClearUp(); }
int rows() const { return m_data3D.Rows(); }
int cols() const { return m_data3D.Cols(); }
int Depths() const { return m_data3D.Depths(); }
void display() const;
//Operator Overloading
float* operator[](int rIndex) { return m_data3D[rIndex]; }
const float* operator[](int rIndex) const { return m_data3D[rIndex]; }
private:
Array3D<float> m_data3D;
};
#include "Matrix3D.h"
#include <iostream>
using namespace std;
void Matrix3D::display() const
{
if (m_data3D.IsEmpty())
{
cout << "empty matrix" << endl;
return;
}
cout << "------------------------" << endl;
const int rows = this->rows();
const int cols = this->cols();
const int Depths = this->Depths();
cout << rows << "x" << cols << "x" << Depths << endl;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
for(int k = 0 ;k < Depths; k++)
{
cout << m_data3D[i][j][k] << ' '; /*This section will pose an error "E0142"*/
}
cout << endl;
}
}
}
I am going to guess that your teachers class was Array2D and that you mostly just added m_nDepths to it to turn it into Array3D. If this assumption is not right, then my answer here is most likely going to be completely wrong.
But if I am right, then his operator[] looked something like:
T* operator[](size_t r)
{
assert(r >= 0 && r < m_nRows);
return &(*(m_v.begin() + (r * m_nCols)));
}
Which means that when you then do m_data2D[i][j], what happens is that the first [i] applies to the Array2D. This, as shown above, returns a pointer (in your case likely a float*). The [j] is then applied to this pointer, which results in some pointer arithmetic that results in a float (for a float *x; x[y] means *(x+y)).
In other words, your teacher stores his 2D array line by line in a 1D array, and when you [] into it you get a pointer to the right line that you can then further [] into.
This is all fine.
The problem is when you add a third dimension to this and try the same approach: The first [] still returns a float* (but this time to the correct 2D matrix), the second [] returns a float (the first element in the correct line of the 2D matrix), and the third [] tries to apply to a float - which it cannot, and you get the error.
There are two ways to fix this:
Change the return type of Array3D::operator[] to return some kind of 2D array type whose operator[] works like the original Array2D.
Abandon the operator[] approach and replace it with a member function that takes 3 arguments and returns the correct element right away. I think this is what I would prefer myself.
For the second option, something like (not tested, rather large chance I messed up the order of the arguments):
T element(size_t x, size_t y, size_t z) const
{
assert(x >= 0 && x < m_nDepths);
assert(y >= 0 && y < m_nCols);
assert(z >= 0 && z < m_nRows);
return *(m_v.begin() + (x * m_nCols * m_nDepths +
y * m_nCols +
z));
}
T& element(size_t x, size_t y, size_t z)
{
assert(x >= 0 && x < m_nDepths);
assert(y >= 0 && y < m_nCols);
assert(z >= 0 && z < m_nRows);
return *(m_v.begin() + (x * m_nCols * m_nDepths +
y * m_nCols +
z));
}
Which turns cout << m_data3D[i][j][k] << ' '; into cout << m_data3D.element(i,j,k) << ' ';

Recursive Backtracking Does Not Back Track

I have been struggling to solve the following question using Recessive Backtracking in C++. The problem is that it does not backtrack. I tracked my algorithm manually on a paper and it works on the paper. So problem is I don't know how to implement that in C++. Any help will be appreciated.
Question:
Given a 2-dimensional grid representing elevations of a map, determine the lowest and highest points and whether there is a path between them that never goes down.
Input
Your program will receive the following command line arguments:
<fname> File name for the 2-dimensional map
<M> Number of rows
<N> Number of columns
Output
Your program should write 5 values to the standard output: Lr Lc Hr Hc YESNO where Lr Lc are the row and column of the lowest point in the grid, Hr Hc are the row and column of the highest point in the grid, and YESNO is the word: yes if there is a path from the lowest point to the highest point that never goes down and no if there is no such path. Specifically, the path starts at the lowest point and can only go from a point to one of its 4-neighbors (left, right, up, or down) that does NOT have a lower elevation than the point. Input will be such that there is a unique solution.
The problem is with the "path" function.
#include <iostream>
#include <fstream>
#include<string>
#include <vector>
#include <algorithm>
#include <iostream>
#include<sstream>
// using namespace std;
void ReadFile(std::string fname, std::vector<std::vector<int>> *const vec_2d);
// What about min? row and col are initially the min, but then get updated
void min_max(std::vector<std::vector<int>> *const vec_2d,
std::vector<int> &vec_1d,
int num_rows,
int num_cols,
int &row,
int &col,
int &idx_i_max,
int &idx_j_max,
int &cur_val); //grid is vec_2d??????
int path(std::vector<int> vec_1d,
int row,
int col,
int num_rows,
int num_cols,
int idx_i_max,
int idx_j_max,
int &cur_val); // bool *visited is a pointer type bool which could be a 2-d array??
int main(int argc, char *argv[])
{
std::vector<std::vector<int>> vec_2d;
std::vector<int> vec_1d;
// declare variables
int num_rows, num_cols, row, col, idx_i_max, idx_j_max, cur_val;
std::string fname;
// get .txt file containing the grid
fname = argv[1]; //string of file name
num_rows = atoi(argv[2]); // convert argument strings to integers
num_cols = atoi(argv[3]);
// bool visited[100][100];
//2D vector initialized with user defined size
// std::vector<std::vector<int>> visited(num_rows, std::vector<int>(num_cols));
ReadFile(fname, &vec_2d); //reading the .txt file and assigning to vec_2d
min_max(&vec_2d,
vec_1d,
num_rows,
num_cols,
row,
col,
idx_i_max,
idx_j_max,
cur_val);
path(vec_1d, row, col, num_rows, num_cols, idx_i_max, idx_j_max, cur_val);
}
void ReadFile(std::string fname, std::vector<std::vector<int>> *const vec_2d)
{ //it is a pointer to a vector,therefore, after end of func, it will still exist // Create the input filestream - opens the file & prepares it for reading
std::ifstream file(fname);
std::string str; // Temporary string to hold a single line of the file
while (std::getline(file, str))
{ // Reads all lines in the file, 1 at at time
std::vector<int> new_row; // Creates a temporary vector to represent one row
std::istringstream ss(str); // Converts our string into a stringstream
int token; // Temp int to store a converted value from a line
while (ss >> token)
{ // Reads all values from the stringstream (current row), converts to int
new_row.push_back(token); // Adds the converted value to the row
}
vec_2d->push_back(new_row); // Pushes our constructed vector of ints to the 2D vector
}
}
void min_max(std::vector<std::vector<int>> *const vec_2d,
std::vector<int> &vec_1d,
int num_rows,
int num_cols,
int &row,
int &col,
int &idx_i_max,
int &idx_j_max,
int &cur_val)
{ //I dont need any argument for this func
//Converting 2-d vec to 1-d to find loc of min and max
for (int i = 0; i < (*vec_2d).size(); i++)
{
for (int j = 0; j < (*vec_2d)[i].size(); j++)
{
vec_1d.push_back((*vec_2d)[i][j]);
}
}
// finding the max and min values in the grid vector and save thier index (max_idx and min_idx)
int max_idx, min_idx; // Initialize two int for index of max and min values
//
int maxElementIndex = std::max_element(vec_1d.begin(), vec_1d.end())
- vec_1d.begin(); //max elem index //I need to convert 2d to 1d vector to use this func
int minElementIndex = std::min_element(vec_1d.begin(), vec_1d.end())
- vec_1d.begin(); //min elem index
//convert 1-d vec idx to 2-d vec idx
idx_i_max = (maxElementIndex / num_cols) + 1; //actual idx + 1
idx_j_max = (maxElementIndex % num_cols) + 1; //actual idx + 1
int idx_i_min = (minElementIndex / num_cols) + 1; //actual idx + 1
int idx_j_min = (minElementIndex % num_cols) + 1; //actual idx + 1
// The initial current value is the minimum
cur_val = *std::min_element(vec_1d.begin(), vec_1d.end());
//loc of min will be our start point as below
row = idx_i_min; //actual idx + 1
col = idx_j_min; //actual idx + 1
// print i and j idx of min and max respectively (with a space after each)
std::cout << idx_i_min << " ";
std::cout << idx_j_min << " ";
std::cout << idx_i_max << " ";
std::cout << idx_j_max << " "; //This prints are working fine
// A recursive backtracking function to go over all cells. base case is when all directions are impossible, then retuen 0
}
//row and col will be changed in every recursion. should they be const???
int path(std::vector<int> vec_1d,
int row,
int col,
int num_rows,
int num_cols,
int idx_i_max,
int idx_j_max,
int &cur_val)
{
// std::cout<<"test"<<std::endl;
std::cout << std::endl << row << " " << col << std::endl; // it atops at the second cell
// std::cout<<cur_val<<std::endl;//it prints the start point twice
// if the evaluating neighbor cell is equal to max value
if (row == idx_i_max && col == idx_j_max)
{ //base case
std::cout << "yes";
return 1;
}
else
{
cur_val = vec_1d[((row - 1) * num_cols) + (col - 1)]; //updating the current value
//Checking the north neighbor (COND1)
if (row - 1 > 0
&& vec_1d[((row - 1 - 1) * num_cols) + (col - 1)] >= cur_val)
{ //if the north cell is -1
vec_1d[((row - 1) * num_cols) + (col - 1)] = -1; // making the current cell as visited
path(vec_1d,
row - 1,
col,
num_rows,
num_cols,
idx_i_max,
idx_j_max,
cur_val);
return 1;
}
//Checking the south neighbor(COND2)
if (row + 1 <= num_rows
&& vec_1d[((row + 1 - 1) * num_cols) + (col - 1)] >= cur_val)
{
vec_1d[((row - 1) * num_cols) + (col - 1)] = -1;
path(vec_1d,
row + 1,
col,
num_rows,
num_cols,
idx_i_max,
idx_j_max,
cur_val);
return 1;
}
//Checking the west neighbor(COND3)
if (col - 1 > 0
&& vec_1d[((row - 1) * num_cols) + (col - 1 - 1)] >= cur_val)
{
vec_1d[((row - 1) * num_cols) + (col - 1)] = -1;
path(vec_1d,
row,
col - 1,
num_rows,
num_cols,
idx_i_max,
idx_j_max,
cur_val);
return 1;
}
//Checking the east neighbor(COND4)
if (col + 1 <= num_cols
&& vec_1d[((row - 1) * num_cols) + (col + 1 - 1)] >= cur_val)
{
vec_1d[((row - 1) * num_cols) + (col - 1)] = -1;
path(vec_1d,
row,
col + 1,
num_rows,
num_cols,
idx_i_max,
idx_j_max,
cur_val);
return 1;
}
// return 0;
}
// FORGET ABOUT PRINTING YES/NO. FOCUS ON THE PRINT OF CURRENT CELL
// if(path){
// std::cout<<"yes";
// }
// else{
// std::cout<<"no";
// }
}
Here's a hint:
^ g++ Foo.cpp -Wall --std=c++17 -o Foo
Foo.cpp: In function ‘void min_max(std::vector<std::vector<int> >*, std::vector<int>&, int, int, int&, int&, int&, int&, int&)’:
Foo.cpp:107:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < (*vec_2d).size(); i++)
~~^~~~~~~~~~~~~~~~~~
Foo.cpp:110:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < (*vec_2d)[i].size(); j++)
~~^~~~~~~~~~~~~~~~~~~~~
Foo.cpp:117:9: warning: unused variable ‘max_idx’ [-Wunused-variable]
int max_idx, min_idx; // Initialize two int for index of max and min values
^~~~~~~
Foo.cpp:117:18: warning: unused variable ‘min_idx’ [-Wunused-variable]
int max_idx, min_idx; // Initialize two int for index of max and min values
^~~~~~~
Foo.cpp: In function ‘int path(std::vector<int>, int, int, int, int, int, int, int&)’:
Foo.cpp:273:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
Adding the -Wall flag on your compile will tell the compiler to help you find silly mistakes. I'd fix these warnings and see if your problem goes away.

converting offset notation to pointer arithmetic in 2d arrays c++

So I am attempting to complete an assignment using 2d pointer arrays. I was going through the process when I realized that was one of the requirements was that I was supposed to use pointer arithmetic, but instead I have been using offset notation. So my question for you guys is what is the best method of converting my offset notation into pointer arithmetic without completely rewriting the program???   Also when   transversing through my 2d array what parameters do I call for my outofbounds function in order for it to properly work? Any suggestions would be greatly appreciated and thank you in advance.
//move through string by parsing to insert each char into array element position
void rules(char** boardArr,int &rows, fstream inFile, string &line, int &cols)
{
char* pos;
char ncount;
for(int i = 0; i < rows; i++) //rows
{
getline(inFile, line);
for(int j = 0; j < cols; j++) //cols
{
*(*(boardArr + i )+ j) == pos;//parsing string into bArr
//neighbor check nested for organism
pos = *(*(boardArr + i)+ j);//position of index within
if(*(*(boardArr + i+1)+ j)=='*')//checking pos to the right of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i-1)+ j)=='*')//checking pos to the left of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i)+ j+1)=='*')//checking pos to the above of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i+1)+ j+1)=='*')//checking pos to the above and to the right of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i-1)+ j+1)=='*')//checking pos above and to the left of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i-1)+ j-1)=='*')//checking pos below and to the left of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i-1)+ j)=='*')//checking pos below of pos index
{
//outofbounds()
ncount++;
}
if(*(*(boardArr + i-1)+ j+1)=='*')//checking pos below and to the right of pos index
{
//outofbounds()
ncount++;
}
//row[i, row[i]-1])
//cout<<*(*(boardArr + i)+ j);//assigning position to check for neighbors
}
}
//how to move through 2d array pointer arithmetic style
//boardArr[rows][cols] == *(*(boardArr + rows)+ cols)
//keep relationship between the numbers
//*(())
//If a cell contains an organism and has fewer than 2 neighbors, the organism dies of loneliness.
//A neighbor is an organism in one of the 8 spots (or fewer if on the edge) around a cell
//If a cell contains an organism and has more than 3 neighbors, it dies from overcrowding.
// If an empty location has exactly three neighbors, an organism is born in that location.
//returns nothing
}
bool outofbounds( int &rows, int &cols, int i, int j)
{
if((i >0 && i< rows) && (j < cols && j > 0))
{
return true;
}
else
return false;
}
There are no reasons to use pointer arithmetics for such simple operations.
Just use arr[i][j] to read/write data.
Also you should check for bounds before any read/write operations to the memory. It is dangerous and may crash your program.
Here is my version of How I'll implement such stuff.
#include <iostream>
/* it is good practice to move functions with special context to classes */
class SafeCharMatrix
{
private:
/* your board */
/* `char const* const*` provides that nobody can change data */
char const* const* _ptr;
int _rows;
int _cols;
public:
SafeCharMatrix(char const* const* ptr, int rows, int cols) :
_ptr(ptr), _rows(rows), _cols(cols)
{}
/* valid check bounds algorithm */
bool CheckBounds(int x, int y) const
{
if (x < 0 || x >= _cols)
return false;
if (y < 0 || y >= _rows)
return false;
return true;
}
bool CheckCharSafe(int x, int y, char c) const
{
/* check bounds before read/write acces to memory */
if (!CheckBounds(x, y))
return false;
return _ptr[x][y] == c;
}
int CountNeighborsSafe(int x, int y, char c) const
{
int count = 0;
count += CheckCharSafe(x - 1, y - 1, c) ? 1 : 0;
count += CheckCharSafe(x - 1, y , c) ? 1 : 0;
count += CheckCharSafe(x - 1, y + 1, c) ? 1 : 0;
count += CheckCharSafe(x , y - 1, c) ? 1 : 0;
/* ignore center (x, y) */
count += CheckCharSafe(x , y + 1, c) ? 1 : 0;
count += CheckCharSafe(x + 1, y - 1, c) ? 1 : 0;
count += CheckCharSafe(x + 1, y , c) ? 1 : 0;
count += CheckCharSafe(x + 1, y + 1, c) ? 1 : 0;
return count;
}
};
/* fill you board before this */
void rules(char const* const* boardArr, int rows, int cols)
{
SafeCharMatrix matrix(boardArr, rows, cols);
for (int i = 0; i < rows; ++i) /* y axis */
{
for (int j = 0; j < cols; ++j) /* x axis */
{
int countOfNeighbors = matrix.CountNeighborsSafe(j, i, '*');
/* do whatever you want */
std::cout
<< "x: " << j << ", "
<< "y: " << i << ", "
<< "count: " << countOfNeighbors << "\n";
}
}
}
/* just example of how it can works */
int main()
{
char r1[3] = { 0 , 0 , '*'};
char r2[3] = { 0 , 0 , 0 };
char r3[3] = { '*', 0 , 0 };
char* m[3];
m[0] = r1;
m[1] = r2;
m[2] = r3;
rules(m, 3, 3);
}
Edit:
Don't pass simple arguments like int numbers by reference: int &row. They are to small and compiler can pack them in just one processor register.

How to solve another version of Kakuro

The problem is, in a table of (h+1)*(w+1),the first row contains w values: a[1] ... a[w] which fill in the 2rd ... (w+1)th column. The first column contains h values: b[1] ... b[h] which fill in the 2rd ... (h+1)th row. sum(a[i]) is equal to sum(b[i]).
The question is to give one possible solution: result, so that sum(result[i][K]) for a certain K, is equal to a[i] with result[i][K] != result[j][K] (i != j and 0 < i < h+1). And the same rule for rows. PS: All the integers are positive.
For example:
a[] = {10, 3, 3}, b[] = {9, 7}
// 10 3 3
// 9 6 2 1
// 7 4 1 2
result = {6, 2, 1;
4, 1, 2}
It is like Kakuro but not the same. I cannot figure out which algorithm to apply, if anyone knows how to solve it, please give me some help. Thanks a lot.
You can always solve your problem with backtracking. Basic idea here: from top-to-bottom and left-to-right try a valid value in the partially filled table, backtrack when this value doesn't lead to a solution.
Minimal example in C++ with annotated solve:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
class Problem {
public:
template<class AIter, class BIter>
Problem(AIter abegin, AIter aend, BIter bbegin, BIter bend)
: m_width(std::distance(abegin, aend))
, m_height(std::distance(bbegin, bend))
, m_table(new int[(m_width + 1) * (m_height + 1)])
{
std::fill(m_table.get(), m_table.get() + (m_width + 1) * (m_height + 1), 0);
for(size_t i = 0; i < m_width; ++i)
m_table[i + 1] = *abegin++;
for(size_t j = 0; j < m_height; ++j)
m_table[(j + 1) * (m_width + 1)] = *bbegin++;
}
bool Solve() { return solve(0, 0); }
int operator()(size_t i, size_t j) const;
private:
int a(size_t i) const { return m_table[i + 1]; }
int b(size_t j) const { return m_table[(j + 1) * (m_width + 1)]; }
int get(size_t i, size_t j) const { return m_table[(j + 1) * (m_width + 1) + i + 1]; }
void set(size_t i, size_t j, int value) { m_table[(j + 1) * (m_width + 1) + i + 1] = value; }
int colSum(size_t i) const;
int rowSum(size_t j) const;
bool solve(size_t i, size_t j);
size_t m_width, m_height;
std::unique_ptr<int[]> m_table; // (width + 1) x (height + 1)
};
int Problem::colSum(size_t i) const {
int sum = 0;
for(size_t j = 0; j < m_height; ++j)
sum += get(i, j);
return sum;
}
int Problem::rowSum(size_t j) const {
int sum = 0;
for(size_t i = 0; i < m_width; ++i)
sum += get(i, j);
return sum;
}
// solves column-wise using backtracking
bool Problem::solve(size_t i, size_t j) {
size_t width = m_width, height = m_height;
// past last column?
if(i >= width) {
// found solution
return true;
}
// remainder in column and row
int remColSum = a(i) - colSum(i);
int remRowSum = b(j) - rowSum(j);
// early break
if(remColSum <= 0 || remRowSum <= 0)
return false;
// starting at the minimal required value (1 or remColSum if on last row)
int startValue = j + 1 < height ? 1 : remColSum;
// remaining row sum cannot support the starting value
if(remRowSum < startValue)
return false;
// end value minimum remaining sum
int endValue = remColSum < remRowSum ? remColSum : remRowSum;
// on last element must equal starting value
if(i + 1 == width && j + 1 == height && startValue != endValue)
return false;
// column-wise i.e. next cell is (i, j + 1) wrapped
int nextI = i + (j + 1) / height;
int nextJ = (j + 1) % height;
for(int value = startValue; value <= endValue; ++value) {
bool valid = true;
// check row up to i
for(size_t u = 0; u < i && valid; ++u)
valid = (get(u, j) != value);
// check column up to j
for(size_t v = 0; v < j && valid; ++v)
valid = (get(i, v) != value);
if(!valid) {
// value is invalid in partially filled table
continue;
}
// value produces a valid, partially filled table, now try recursing
set(i, j, value);
// upon first solution break
if(solve(nextI, nextJ))
return true;
}
// upon failure backtrack
set(i, j, 0);
return false;
}
int Problem::operator()(size_t i, size_t j) const {
return get(i, j);
}
int main() {
int a[] = { 10, 3, 3 };
int b[] = { 9, 7 };
size_t width = sizeof(a) / sizeof(*a);
size_t height = sizeof(b) / sizeof(*b);
Problem problem(a, a + width, b, b + height);
if(!problem.Solve()) {
std::cout << "No solution" << std::endl;
}
for(size_t j = 0; j < height; ++j) {
if(j == 0) {
std::cout << " ";
for(size_t i = 0; i < width; ++i)
std::cout << " " << a[i];
std::cout << std::endl;
}
std::cout << b[j];
for(size_t i = 0; i < width; ++i) {
int value = problem(i, j);
if(value == 0)
std::cout << " ";
else
std::cout << " " << value;
}
std::cout << std::endl;
}
return 0;
}

How to add two numbers without using ++ or + or another arithmetic operator

How do I add two numbers without using ++ or + or any other arithmetic operator?
It was a question asked a long time ago in some campus interview. Anyway, today someone asked a question regarding some bit-manipulations, and in answers a beautiful quide Stanford bit twiddling was referred. I spend some time studying it and thought that there actually might be an answer to the question. I don't know, I could not find one. Does an answer exist?
This is something I have written a while ago for fun. It uses a two's complement representation and implements addition using repeated shifts with a carry bit, implementing other operators mostly in terms of addition.
#include <stdlib.h> /* atoi() */
#include <stdio.h> /* (f)printf */
#include <assert.h> /* assert() */
int add(int x, int y) {
int carry = 0;
int result = 0;
int i;
for(i = 0; i < 32; ++i) {
int a = (x >> i) & 1;
int b = (y >> i) & 1;
result |= ((a ^ b) ^ carry) << i;
carry = (a & b) | (b & carry) | (carry & a);
}
return result;
}
int negate(int x) {
return add(~x, 1);
}
int subtract(int x, int y) {
return add(x, negate(y));
}
int is_even(int n) {
return !(n & 1);
}
int divide_by_two(int n) {
return n >> 1;
}
int multiply_by_two(int n) {
return n << 1;
}
int multiply(int x, int y) {
int result = 0;
if(x < 0 && y < 0) {
return multiply(negate(x), negate(y));
}
if(x >= 0 && y < 0) {
return multiply(y, x);
}
while(y > 0) {
if(is_even(y)) {
x = multiply_by_two(x);
y = divide_by_two(y);
} else {
result = add(result, x);
y = add(y, -1);
}
}
return result;
}
int main(int argc, char **argv) {
int from = -100, to = 100;
int i, j;
for(i = from; i <= to; ++i) {
assert(0 - i == negate(i));
assert(((i % 2) == 0) == is_even(i));
assert(i * 2 == multiply_by_two(i));
if(is_even(i)) {
assert(i / 2 == divide_by_two(i));
}
}
for(i = from; i <= to; ++i) {
for(j = from; j <= to; ++j) {
assert(i + j == add(i, j));
assert(i - j == subtract(i, j));
assert(i * j == multiply(i, j));
}
}
return 0;
}
Or, rather than Jason's bitwise approach, you can calculate many bits in parallel - this should run much faster with large numbers. In each step figure out the carry part and the part that is sum. You attempt to add the carry to the sum, which could cause carry again - hence the loop.
>>> def add(a, b):
while a != 0:
# v carry portion| v sum portion
a, b = ((a & b) << 1), (a ^ b)
print b, a
return b
when you add 1 and 3, both numbers have the 1 bit set, so the sum of that 1+1 carries. The next step you add 2 to 2 and that carries into the correct sum four. That causes an exit
>>> add(1,3)
2 2
4 0
4
Or a more complex example
>>> add(45, 291)
66 270
4 332
8 328
16 320
336
Edit:
For it to work easily on signed numbers you need to introduce an upper limit on a and b
>>> def add(a, b):
while a != 0:
# v carry portion| v sum portion
a, b = ((a & b) << 1), (a ^ b)
a &= 0xFFFFFFFF
b &= 0xFFFFFFFF
print b, a
return b
Try it on
add(-1, 1)
to see a single bit carry up through the entire range and overflow over 32 iterations
4294967294 2
4294967292 4
4294967288 8
...
4294901760 65536
...
2147483648 2147483648
0 0
0L
int Add(int a, int b)
{
while (b)
{
int carry = a & b;
a = a ^ b;
b = carry << 1;
}
return a;
}
You could transform an adder circuit into an algorithm. They only do bitwise operations =)
Well, to implement an equivalent with boolean operators is quite simple: you do a bit-by-bit sum (which is an XOR), with carry (which is an AND). Like this:
int sum(int value1, int value2)
{
int result = 0;
int carry = 0;
for (int mask = 1; mask != 0; mask <<= 1)
{
int bit1 = value1 & mask;
int bit2 = value2 & mask;
result |= mask & (carry ^ bit1 ^ bit2);
carry = ((bit1 & bit2) | (bit1 & carry) | (bit2 & carry)) << 1;
}
return result;
}
You've already gotten a couple bit manipulation answers. Here's something different.
In C, arr[ind] == *(arr + ind). This lets us do slightly confusing (but legal) things like int arr = { 3, 1, 4, 5 }; int val = 0[arr];.
So we can define a custom add function (without explicit use of an arithmetic operator) thusly:
unsigned int add(unsigned int const a, unsigned int const b)
{
/* this works b/c sizeof(char) == 1, by definition */
char * const aPtr = (char *)a;
return (int) &(aPtr[b]);
}
Alternately, if we want to avoid this trick, and if by arithmetic operator they include |, &, and ^ (so direct bit manipulation is not allowed) , we can do it via lookup table:
typedef unsigned char byte;
const byte lut_add_mod_256[256][256] = {
{ 0, 1, 2, /*...*/, 255 },
{ 1, 2, /*...*/, 255, 0 },
{ 2, /*...*/, 255, 0, 1 },
/*...*/
{ 254, 255, 0, 1, /*...*/, 253 },
{ 255, 0, 1, /*...*/, 253, 254 },
};
const byte lut_add_carry_256[256][256] = {
{ 0, 0, 0, /*...*/, 0 },
{ 0, 0, /*...*/, 0, 1 },
{ 0, /*...*/, 0, 1, 1 },
/*...*/
{ 0, 0, 1, /*...*/, 1 },
{ 0, 1, 1, /*...*/, 1 },
};
void add_byte(byte const a, byte const b, byte * const sum, byte * const carry)
{
*sum = lut_add_mod_256[a][b];
*carry = lut_add_carry_256[a][b];
}
unsigned int add(unsigned int a, unsigned int b)
{
unsigned int sum;
unsigned int carry;
byte * const aBytes = (byte *) &a;
byte * const bBytes = (byte *) &b;
byte * const sumBytes = (byte *) ∑
byte * const carryBytes = (byte *) &carry;
byte const test[4] = { 0x12, 0x34, 0x56, 0x78 };
byte BYTE_0, BYTE_1, BYTE_2, BYTE_3;
/* figure out endian-ness */
if (0x12345678 == *(unsigned int *)test)
{
BYTE_0 = 3;
BYTE_1 = 2;
BYTE_2 = 1;
BYTE_3 = 0;
}
else
{
BYTE_0 = 0;
BYTE_1 = 1;
BYTE_2 = 2;
BYTE_3 = 3;
}
/* assume 4 bytes to the unsigned int */
add_byte(aBytes[BYTE_0], bBytes[BYTE_0], &sumBytes[BYTE_0], &carryBytes[BYTE_0]);
add_byte(aBytes[BYTE_1], bBytes[BYTE_1], &sumBytes[BYTE_1], &carryBytes[BYTE_1]);
if (carryBytes[BYTE_0] == 1)
{
if (sumBytes[BYTE_1] == 255)
{
sumBytes[BYTE_1] = 0;
carryBytes[BYTE_1] = 1;
}
else
{
add_byte(sumBytes[BYTE_1], 1, &sumBytes[BYTE_1], &carryBytes[BYTE_0]);
}
}
add_byte(aBytes[BYTE_2], bBytes[BYTE_2], &sumBytes[BYTE_2], &carryBytes[BYTE_2]);
if (carryBytes[BYTE_1] == 1)
{
if (sumBytes[BYTE_2] == 255)
{
sumBytes[BYTE_2] = 0;
carryBytes[BYTE_2] = 1;
}
else
{
add_byte(sumBytes[BYTE_2], 1, &sumBytes[BYTE_2], &carryBytes[BYTE_1]);
}
}
add_byte(aBytes[BYTE_3], bBytes[BYTE_3], &sumBytes[BYTE_3], &carryBytes[BYTE_3]);
if (carryBytes[BYTE_2] == 1)
{
if (sumBytes[BYTE_3] == 255)
{
sumBytes[BYTE_3] = 0;
carryBytes[BYTE_3] = 1;
}
else
{
add_byte(sumBytes[BYTE_3], 1, &sumBytes[BYTE_3], &carryBytes[BYTE_2]);
}
}
return sum;
}
All arithmetic operations decompose to bitwise operations to be implemented in electronics, using NAND, AND, OR, etc. gates.
Adder composition can be seen here.
For unsigned numbers, use the same addition algorithm as you learned in first class, but for base 2 instead of base 10. Example for 3+2 (base 10), i.e 11+10 in base 2:
1 ‹--- carry bit
0 1 1 ‹--- first operand (3)
+ 0 1 0 ‹--- second operand (2)
-------
1 0 1 ‹--- total sum (calculated in three steps)
If you're feeling comedic, there's always this spectacularly awful approach for adding two (relatively small) unsigned integers. No arithmetic operators anywhere in your code.
In C#:
static uint JokeAdder(uint a, uint b)
{
string result = string.Format(string.Format("{{0,{0}}}{{1,{1}}}", a, b), null, null);
return result.Length;
}
In C, using stdio (replace snprintf with _snprintf on Microsoft compilers):
#include <stdio.h>
unsigned int JokeAdder(unsigned int a, unsigned int b)
{
return snprintf(NULL, 0, "%*.*s%*.*s", a, a, "", b, b, "");
}
Here is a compact C solution. Sometimes recursion is more readable than loops.
int add(int a, int b){
if (b == 0) return a;
return add(a ^ b, (a & b) << 1);
}
#include<stdio.h>
int add(int x, int y) {
int a, b;
do {
a = x & y;
b = x ^ y;
x = a << 1;
y = b;
} while (a);
return b;
}
int main( void ){
printf( "2 + 3 = %d", add(2,3));
return 0;
}
short int ripple_adder(short int a, short int b)
{
short int i, c, s, ai, bi;
c = s = 0;
for (i=0; i<16; i++)
{
ai = a & 1;
bi = b & 1;
s |= (((ai ^ bi)^c) << i);
c = (ai & bi) | (c & (ai ^ bi));
a >>= 1;
b >>= 1;
}
s |= (c << i);
return s;
}
## to add or subtract without using '+' and '-' ##
#include<stdio.h>
#include<conio.h>
#include<process.h>
void main()
{
int sub,a,b,carry,temp,c,d;
clrscr();
printf("enter a and b:");
scanf("%d%d",&a,&b);
c=a;
d=b;
while(b)
{
carry=a&b;
a=a^b;
b=carry<<1;
}
printf("add(%d,%d):%d\n",c,d,a);
temp=~d+1; //take 2's complement of b and add it with a
sub=c+temp;
printf("diff(%d,%d):%d\n",c,d,temp);
getch();
}
The following would work.
x - (-y)
This can be done recursively:
int add_without_arithm_recursively(int a, int b)
{
if (b == 0)
return a;
int sum = a ^ b; // add without carrying
int carry = (a & b) << 1; // carry, but don’t add
return add_without_arithm_recursively(sum, carry); // recurse
}
or iteratively:
int add_without_arithm_iteratively(int a, int b)
{
int sum, carry;
do
{
sum = a ^ b; // add without carrying
carry = (a & b) << 1; // carry, but don’t add
a = sum;
b = carry;
} while (b != 0);
return a;
}
Code to implement add,multiplication without using +,* operator;
for subtraction pass 1's complement +1 of number to add function
#include<stdio.h>
unsigned int add(unsigned int x,unsigned int y)
{
int carry=0;
while (y != 0)
{
carry = x & y;
x = x ^ y;
y = carry << 1;
}
return x;
}
int multiply(int a,int b)
{
int res=0;
int i=0;
int large= a>b ? a :b ;
int small= a<b ? a :b ;
for(i=0;i<small;i++)
{
res = add(large,res);
}
return res;
}
int main()
{
printf("Sum :: %u,Multiply is :: %d",add(7,15),multiply(111,111));
return 0;
}
The question asks how to add two numbers so I don't understand why all the solutions offers the addition of two integers? What if the two numbers were floats i.e. 2.3 + 1.8 are they also not considered numbers? Either the question needs to be revised or the answers.
For floats I believe the numbers should be broken into their components i.e. 2.3 = 2 + 0.3 then the 0.3 should be converted to an integer representation by multiplying with its exponent factor i.e 0.3 = 3 * 10^-1 do the same for the other number and then add the integer segment using one of the bit shift methods given as a solution above handling situations for carry over to the unit digits location i.e. 2.7 + 3.3 = 6.0 = 2+3+0.7+0.3 = 2 + 3 + 7x10^-1 + 3x10^-1 = 2 + 3 + 10^10^-1 (this can be handled as two separate additions 2+3=5 and then 5+1=6)
With given answers above, it can be done in single line code:
int add(int a, int b) {
return (b == 0) ? a : add(a ^ b, (a & b) << 1);
}
You can use double negetive to add two integers for example:
int sum2(int a, int b){
return -(-a-b);
}
Without using any operators adding two integers can be done in different ways as follows:
int sum_of_2 (int a, int b){
int sum=0, carry=sum;
sum =a^b;
carry = (a&b)<<1;
return (b==0)? a: sum_of_2(sum, carry);
}
// Or you can just do it in one line as follows:
int sum_of_2 (int a, int b){
return (b==0)? a: sum_of_2(a^b, (a&b)<<1);
}
// OR you can use the while loop instead of recursion function as follows
int sum_of_2 (int a, int b){
if(b==0){
return a;
}
while(b!=0){
int sum = a^b;
int carry = (a&b)<<1;
a= sum;
b=carry;
}
return a;
}
int add_without_arithmatic(int a, int b)
{
int sum;
char *p;
p = (char *)a;
sum = (int)&p[b];
printf("\nSum : %d",sum);
}