Long arithmetics - delete-file

Do something with it guys
They ask to add something
because it looks like my post is mostly code.
I hope it's enough.
There's no way to delete it.
Solong sum;
sum = 0;
for (int i = 0; i != 10; ++i) {
if ((i != 0) && (i != 8)) {
sum = sum + n2[i];
}
}
std::cout << sum;
std::cout << std::endl;
}

These are the problems that punched me in the face looking at your code -- so I might have missed a few less obvious things.
operator = (const int & b), ignores the argument's value and just makes the low-order word zero. So I'm thinking you want number[0] = b;. You also need to update size. You should also probably take care of the case when b overflows your radix, setting size and populating higer-order words.
In operator +, a radix digit overflow is detected and the carry flag is set, but the result's digit is never reduced by the value represented by the carry to the next digit:
if (res.number[i] >= res.radix) {
overDecimal = 1;
}
So this needs something like res.number[i] -= res.radix
Also, high-order words beyond its size are used when one argument has a smaller size than the other. The assignment operators do not bother to make sure that their high-order words, above size are set to zero, so you either need to make sure they are set to zero everywhere else, or ignore these non-zero high-order words in this function.
In the loop in void operator <<, your index i starts at the last element, but is updated by incrementing:
for (int i=a.size-1; ...; ++i) { ...
So I'm guessing this needs to be changed to --i
Some other problems:
Both operator = (... should return Solong& instead of void, with return *this; at the end.
operator << (std::ostream& out, const Solong &a) should return std::ostream& instead of void, with return out; at the end.

First: Your program caused a segmentation fault in this function:
> void operator << (std::ostream& out, const Solong &a) {
> for (int i = a.size - 1; i != -1 || (i != a.size - 1 && a.number[a.size - 1] == 0); ++i) {
x > out << a.number[i];
> }
> }
You can find this line by using a debugger. On linux you may want to use gdb. If you are using some IDE, it should be integrated there. I'm not sure what you want to do in this function. Maybe you could just write this?
for (int i = a.size - 1; i >= 0; --i) out << a.number[i];
The program dosen't crash anymore after changing this. I got -1087373312 as result for 42 but you have undefined behavior in your application. I get another result each time I run it. Now I will show some other things I would change. It did work for me after doing this:
I would use std::vector to store the numbers. This container would hold the size for you and you can change it by using resize:
class Solong {
private:
int radix = 10;
std::vector<int> number;
I have to change the constructor then:
public:
Solong() :
number(1, 1) // are you shure you want initialize it with 1 instead of 0?
{}
You may also want to have a constructor to set the initial value.
Solong(const int &value)
{
*this = value;
}
The operator<< sould return a reference to out:
friend Solong operator+ (const Solong &a, const Solong &b);
friend std::ostream &operator<< (std::ostream &out, const Solong &a);
Since I'm not using an array in this class anymore, I can use the implicit definition of operator=(const Solong &b). I would just remove the custom definition of operator=(const Solong &b) from the class.
I think you want to assign b to number instead of 0 in the function operator=(const int &b). You should return a reference to the object itself as well. Since you only allow 0-9 per int, you have to ensure this, too.
void operator= (int b) {
this->number.clear();
while (b > 0) {
this->number.push_back(b % radix);
b = b / radix;
}
}
};
For operator+ there are multiple things:
I have to use resize of number now.
If you want to put the definition in a header file, you have to specify inline.
The condition || overDecimal seems wrong to me, since they can cause a segmentation fault.
You have to check if a.number[i] and b.number[i] is valid before reading this value.
And you should change res.number[i] if there is an overflow
Here is my updated implementation:
inline Solong operator+ (const Solong &a, const Solong &b) {
Solong res;
res.number.resize(std::max(a.number.size(), b.number.size()));
int overDecimal = 0;
for (std::size_t i = 0; i < res.number.size(); ++i) {
int aDigit = (a.number.size() > i ? a.number[i] : 0);
int bDigit = (b.number.size() > i ? b.number[i] : 0);
res.number[i] = aDigit + bDigit + overDecimal;
overDecimal = 0;
if (res.number[i] >= res.radix) {
overDecimal = 1;
res.number[i] = res.number[i] % res.radix;
}
}
if (overDecimal)
res.number.push_back(overDecimal);
return res;
}
Finally I fixed operator<< just like written above, added the keyword inline and return a reference to out:
inline std::ostream &operator<< (std::ostream &out, const &a) {
for (int i = a.number.size() - 1; i >= 0; --i) {
out << a.number[i];
}
return out;
}
I would also change i to std::size_t and use the whole size of int for one digit. Not just 10 values per int. I would then changed the name of overDecimal to overflowedDigit of cource since there would be no decimalism anymore. You should also consider that you are not supporting negative numbers right now. But all this would add some complexity and I don't want descripe it now.

Related

Count distinct pairs of strings that contain at least one common character at the same position

Is there a more efficient way to count distinct pairs of strings in an array that have at least one common character at the same position. The strings will always have the same length of 3. For example,
"abc", acb": counts
"bun", "fun": counts
"xyz", "yzx": doesn't count
"one", "two": doesn't count
I've tried writing a function that checks if they match and then count them using for loops, but it doesn't seem to be so efficient, especially when the array is huge.
bool match(std::string a, std::string b) {
for (int i = 0; i < 3; i++) {
if (a.at(i) == b.at(i)) {
return true;
}
}
return false;
}
int main() {
const int count = 100000;
std::string strings[count] = {...};
long long int matches = 0;
for (int i = 0; i < count; i++) {
for (int j = i + 1; j < count; j++) {
if (match(strings[i], strings[j])) {
matches++;
}
}
}
}
So, is there a more efficient way to achieve this?
Heres the list (assuming the strings has 3 chars):
is actual the only one that might not be already done by your compiler: pass the std::string by const&, so that you don't need to copy them every time you call the function
bool match(const std::string& a, const std::string& b){...}
avoid useless branches in your code (can be optimized already by some branch prediction algorithm):
// from
if (match(strings[i], strings[j])) {
matches++;
}
// to
matches = matches + match(strings[i], strings[j];
loop unrolling (which can been done already by your compiler):
bool match(std::string a, std::string b) {
return a.at(0) == b.at(0) || a.at(1) == b.at(1) || a.at(2) == b.at(2);
}
You can also try to parallelize those conditions (depends on architecture, can be done already by the compiler) using | and so all the conditions can be done in parallel by ALU, instead using | must be performed step by step (short circuit evaluation):
bool match(std::string a, std::string b) {
return a.at(0) == b.at(0) | a.at(1) == b.at(1) | a.at(2) == b.at(2);
}
Compile using the highest optimization (can increase the compilation time), using -O3
use pre-increment instead of post-increment (post increment will generate a second variable to return every time you use it, pre-increment no):
for (int i = 0; i < count; ++i) {
for (int j = i + 1; j < count; ++j) {
}
}
by this line std::string strings[count] = {...}; I suppose you are using initializarer list, and so the computation can actually be performed at compile time if you use std::string_view and so at runtime there is no compilation to perform (this works only if the strings are known at compile time)
decrease cache misses, but this depends 100% on architecture
inline the function (so that your program don't have to do a jump every time to call match):
// from:
bool match(const std::string& a, const std::string& b){...}
//to:
inline bool match(const std::string& a, const std::string& b){...}
use operator[] instead of .at() because it does not make any kind of bounds checking
bool match(std::string a, std::string b) {
return a[0] == b[0] | a[1] == b[1] | a[2] == b[2];
}

Logical operation between all elements in array

I want to compare all items in my array using a boolean operator in the most efficient way. Currently, I have something like this :
bool myFunction(int i)
{
bool *myArray = {true, true, false, false, true};
//suppose we know that i = 5 and that i is the length of the array...
return myArray[0] && myArray[1] && myArray[2] && myArray[3] && myArray[4];
}
Since the size of the array is not fixed, the value of 'i' can change and my return statement would no longer be working, so I would have to implement something like this
bool myFunction(int i)
{
bool *myArray = //some other array of bools
//should work with any value of i
bool result = myArray[0];
for (int a = 1; a < i; ++a)
{
result &= myArray[i];
}
return result;
}
I was wondering if there was a better way to do this other than making a for loop and going through each elements and comparing the value of the next item in list with the stored result from the previous two items. Like some bitwise operators that would make this easy or something, anything to take out the loop.
You probably need to know that &= is not a logical operator; it is the "bitwise and" operator. As long as you only use it on booleans, I guess it will work ok; but C won't stop a value other than 1 or 0 from slipping into the array, so you should probably not make that assumption. Semantically if you're doing a logical or you want && instead of &.
That said, you can certainly use short-circuiting to refine what you're doing. Once you've found a single 0 (false), nothing from then on is going to make your aggregate go back to 1 (true), so you might as well stop.
for (int a = 1; result && a < i; ++a)
{
result &= myArray[i];
}
Other than that, there's not much you can improve. Not sure why you're averse to a loop, but if you want to combine an unknown number of values you're going to have to iterate. You might find (or write) some utility function to do it, but it'll be using a loop internally anyway. (Unless it tries to leverage a vector processor that natively does what you want, maybe... but that would be rather pointless and, if you truly don't have a limit on number of values, will still involve a loop.)
You can use all_of (replacestd::begin(myArray) + i with std::end(myArray) if you want to check entire array and not first i elements):
#include <vector>
#include <algorithm>
bool myFunction(int i)
{
std::vector<bool> myArray = { true, true, false, false, true };
return std::all_of(std::begin(myArray), std::begin(myArray) + i, [](bool elem) { return elem; });
}
I would change the condition of your for-loop so you won't continue if you encounter a false value and use an iterator instead of an index.
bool myFunction(int i) {
bool myArray[i] = //some other array of bools
//should workwith any value of i
bool result;
bool * a;
for (a = myArray, result = *a; a < myArray+i && result; result=*(++i)) {}
//no need to use the AND operator since we stop if we meet one false
return result;
}
Or if you really prefer with index:
bool myFunction(int i) {
bool myArray[i] = //some other array of bools
//should workwith any value of i
bool result;
unsigned int a;
for (a = 0, result = myArray[a]; a < i && result; result=myArray[++i]) {}
//no need to use the AND operator since we stop if we meet one false
return result;
}
Maybe I'm wrong, but I wouldn't use the bitwise AND assignment (&=) if it's not on bit range operation, it's not really relevant on the bool type though.
You can exit the loop as soon as you encounter false:
for (int a = 0; a < i; a++)
{
if (!myArray[i])
return false;
}
return true;
If you're allowed to change the last value in the array, then here's a trick for optimizing it:
If the last value in the array is false, then return false
Write false into the last entry in the array
Iterate the array until you encounter false
Write true into the last entry in the array
If you stopped before the last entry, then return false
Return true
The code:
int a;
if (!myArray[i-1])
return false;
myArray[i-1] = false;
for (a = 0; a < i; a++)
{
if (!myArray[i])
break;
}
myArray[i-1] = true;
return a != i-1;
This yields one branch per iteration instead of two branches per iteration.
If you're allowed to allocate i+1 entries, then you can get rid of the "last entry swapping" part:
int a;
myArray[i] = false;
for (a = 0; myArray[i]; i++);
return a != i;
You can also get rid of the additional arithmetic embedded in myArray[i]:
bool *arrayPtr;
myArray[i] = false;
for (arrayPtr = myArray; *arrayPtr; arrayPtr++);
return arrayPtr != myArray+i;
If the compiler doesn't already apply it, then this function will do so for sure. On the other hand, it might make it harder on the optimizer to unroll the loop, so you will have to verify that in the generated assembly code...
You can use a boost::dynamic_bitset, it has a member fuction any() that will return true if any bits in this bitset are set. And none() will return true if no bits are set.
But the implementation of any() is:
template <typename Block, typename Allocator>
bool dynamic_bitset<Block, Allocator>::any() const
{
for (size_type i = 0; i < num_blocks(); ++i)
if (m_bits[i])
return true;
return false;
}
So you have inside a for loop!
But if you are searching for something like parallel computing, you may want to use arrayfire:
For example it has an algorithm that do it.
template<typename T >
T af::allTrue( const array & in )
//C++ Interface for checking if all values in an array are true.

For loop acting on vector of integers is behaving strangely

#include <iostream>
#include <vector>
std::vector<int> normalize(std::vector<int> a) {
for (int j = a.size() - 1; j > 0; --j) {
while (a[j] > 9) {
a[j] = a[j] - 10;
std::cout << '!'; //Just to test if the loop is executed (the correct # of times)
++a[j - 1];
}
}
// checks that the last digit isnt too large, makes new digit otherwise
if (a[0] > 9) {
a.insert(a.begin(), 0);
while (a[1] > 9) {
a[1] -= 10;
++a[0];
}
}
return a;
}
// for debugging convenience
void printVector(std::vector<int> a) {
for (int i = 0; i < a.size(); ++i) {
std::cout << a[i] << ' ';
}
std::cout << std::endl;
}
int main()
{
std::vector<int> a;
a.push_back(1); a.push_back(2); a.push_back(33);
normalize(a);
printVector(a);
return 0;
}
This program represents large integers as lists of digits, The normalize function would change {1,2,33} to {1,5,3}, representing 153, for instance. I'm new to C++ so I'm not using classes and I'm not using any big integer headers that would have this all much better implemented.
Returns: !!!1 2 33
as though the vector has not been changed. But then how would the "std::cout '!'" line print the correct number of times, or even the while loop terminate at all?
In your function
std::vector<int> normalize(std::vector<int> a)
you are passing a by value, so it won't be modified once the function exits. To make it work, you should use your current implementation as
auto result = normalize(a); // now we get the result
printVector(result); // and display it
To avoid making an un-necessary copy, you should pass the agument by const reference:
std::vector<int> normalize(std::vector<int> const& a)
If you want to modify the parameter that's passed to your function, you should pass by reference:
std::vector<int> normalize(std::vector<int>& a) // now we can modify a
However, it's a good idea to implement functions as black boxes without side effects (if possible), as it will make testing and multi-threading much easier, so I'd suggest passing by const reference then returning the result.
Your function uses pass-by-value. This means that the call normalize(a); does not modify a, it modifies a copy of a.
To fix this there are two ways:
Make the call a = normalize(a);
Make the function have void return type, and use pass-by-reference (put a & in the function prototype before the parameter name).
The first way is more natural but unfortunately has performance problems for large vectors, so most people would prefer the second way
NB. You currently don't handle the possibility of a[0] > 9 after the insert and adjustment; and it would be simpler to store the least-significant digit first, then you can append instead of inserting at the front, and you wouldn't need to divide your algorithm up into the two parts.

Function to print all elements of stack?

I want to print all the elements of a character stack. This is my function:
void print_stack(stack<char> c)
{
stack<char> a = c;
for (unsigned int i = 0; i < a.size(); i++) {
std::cout<<a.top();
a.pop();
}
}
Currently, it is printing only the first a.size() - 1 elements and not the last element. I am having trouble figuring out why this is the case.
Your loop is wrong, consider what happens to a when you do a.pop() if a.size() was 3, it is now 2, so your loop will iterate one less time. You should do this:
while (!a.empty()) {
std::cout<<a.top();
a.pop();
}
Also you dont need to copy c, since your function signiture is void print_stack(stack<char> c) not void print_stack(stack<char> &c) you are creating a copy of c for the scope of this function anyway. Which means this would be sufficient:
void print_stack(stack<char> c) {
while (!c.empty()) {
std::cout<<c.top();
c.pop();
}
}
Here is a live example.
for (unsigned int i = 0; i < c.size(); i++)
or
while(a.size() > 0)
You could also simply do
std::stack<int> c;
std::cout << c; //[a, b, c]
Though you can't format it, you'll be able to get the representation of it.

Difference between code generated using a template function and a normal function

I have a vector containing large number of elements. Now I want to write a small function which counts the number of even or odd elements in the vector. Since performance is a major concern I don't want to put an if statement inside the loop. So I wrote two small functions like:
long long countOdd(const std::vector<int>& v)
{
long long count = 0;
const int size = v.size();
for(int i = 0; i < size; ++i)
{
if(v[i] & 1)
{
++count;
}
}
return count;
}
long long countEven(const std::vector<int>& v)
{
long long count = 0;
const int size = v.size();
for(int i = 0; i < size; ++i)
{
if(0 == (v[i] & 1))
{
++count;
}
}
return count;
}
My question is can I get the same result by writing a single template function like this:
template <bool countEven>
long long countTemplate(const std::vector<int>& v1)
{
long long count = 0;
const int size = v1.size();
for(int i = 0; i < size; ++i)
{
if(countEven)
{
if(v1[i] & 1)
{
++count;
}
}
else if(0 == (v1[i] & 1))
{
++count;
}
}
return count;
}
And using it like this:
int main()
{
if(somecondition)
{
countTemplate<true>(vec); //Count even
}
else
{
countTemplate<false>(vec); //Count odd
}
}
Will the code generated for the template and non-template version be the same ? or will there be some additional instructions emitted?
Note that the counting of numbers is just for illustration hence please don't suggest other methods for counting.
EDIT:
Ok. I agree that it may not make much sense from performance point of view. But atleast from maintainability point of view I would like to have only one function to maintain instead of two.
The templated version may and, very probably, will be optimized by the compiler when it sees a certain branch in the code is never reached. The countTemplate code for instance, will have the countEven template argument set to true, so the odd branch will be cut away.
(sorry, I can't help suggesting another counting method)
In this particular case, you could use count_if on your vector:
struct odd { bool operator()( int i )const { return i&1; } };
size_t nbOdd = std::count_if( vec.begin(), vec.end(), odd() );
This can also be optimized, and writes way shorter :) The standard library developers have given possible optimization much thought, so better use it when you can, instead of writing your own counting for-loop.
Your template version will generate code like this:
template <>
long long countTemplate<true>(const std::vector<int>& v1)
{
long long count = 0;
const int size = v1.size();
for(int i = 0; i < size; ++i)
{
if(true)
{
if(v1[i] & 1)
{
++count;
}
}
else if(0 == (v1[i] & 1))
{
++count;
}
}
return count;
}
template <>
long long countTemplate<false>(const std::vector<int>& v1)
{
long long count = 0;
const int size = v1.size();
for(int i = 0; i < size; ++i)
{
if(false)
{
if(v1[i] & 1)
{
++count;
}
}
else if(0 == (v1[i] & 1))
{
++count;
}
}
return count;
}
So if all optimizations are disabled, the if will in theory still be there. But even a very naive compiler will determine that you're testing a constant, and simply remove the if.
So in practice, no, there should be no difference in the generated code. So you can use the template version and don't worry about this.
I guess that good compiler will cut redundant code in your template as countEven is compile time constant and it is very simple to implement such optimization during template instantiation.
Anyway it seems pretty strange. You wrote a template but do "dynamic switching" inside.
May be try something like that:
struct CountEven {}
struct CountOdd {}
inline void CountNum(int & num, long long & count, const CountEven &)
{
if(num & 1)
{
++count;
}
}
inline void CountNum(int & num, long long & count, const CountOdd &)
{
if(0 == (num & 1))
{
++count;
}
}
template <class T>
long long countTemplate(const std::vector<int>& v1)
{
long long count = 0;
const int size = v1.size();
for(int i = 0; i < size; ++i)
{
CountNum(v1[i], count, T());
}
return count;
}
It will select necessary CountNum() function version on compilation stage:
int main()
{
if(somecondition)
{
countTemplate<CountEven>(vec); //Count even
}
else
{
countTemplate<CountOdd>(vec); //Count odd
}
}
Code is messy, but I think you got the idea.
This will depend on how smart the compiler optimizer is. The compiler might be able to see that really the if-statement is redundant and only one branch of it is executed and optimize the whole thing.
The best way to check is to try and look at the assembly - this code will not produce too much of machine code.
The first thing that comes to my mind are the two optimization "rules":
Don't optmized prematurely.
Don't do it yet.
The point is that sometimes we bother about a performance bottleneck which will never happen in practice. There are studies that say that 20 percent of the code is responsible for 80 percent of the software execution time. Of course this doesn't mean you pessimize prematurely, but I don't think that's your case.
In general, you should do this kind of optmization only after you have actually run a profiler on your program and identified the real bottlenecks.
Regarding your function versions, as other have said this depends on your compiler. Just remember that with the template approach you won't be able to switch calls at runtime (template is a compile-time tool).
A final note: long long is not standard C++ (yet).
If you care about optimization issues try to make it like the following:
template <bool countEven>
long long countTemplate(const std::vector<int>& v1)
{
long long count = 0;
const int size = v1.size();
for ( int i = 0; i < size; ++i ) {
// According to C++ Standard 4.5/4:
// An rvalue of type bool can be converted to an rvalue of type int,
// with false becoming zero and true becoming one.
if ( v1[i] & 1 == countEven ) ++count;
}
return count;
}
I believe that the code above will be compiled in the same code as without templates.
Use STL, Luke :-) It's even as example in reference
bool isOdd(int i)
{
return i%2==1;
}
bool isEven(int i)
{
return i%2==0;
}
std::vector<int>::size_type count = 0;
if(somecondition)
{
count = std::count_if(vec.begin(), vec.end(), isEven);
}
else
{
count = std::count_if(vec.begin(), vec.end(), isOdd);
}
In general, the outcome will be much the same. You are describing an O(n) iteration over the linear memory of the vector.
If you had a vector of pointers, suddenly the performance would be way worse because the memory locality of reference would be lost.
However, the more general thing is that even netbook CPUs can do gazallions of operations per second. Looping over your array is most unlikely to be performance-critical code.
You should write for readability, then profile your code, and consider doing more involved hand-tweaked things when the profiling highlights the root cause of any performance issue you have.
And performance gains typically come from algorithmic changes; if you kept count of the number of odds as you added and removed elements from the vector, for example, it would be O(1) to retrieve...
I see that you're using long long for counter, and that probably means that you expect huge number of elements in vector. In that case, I would definitely go for template implementation (because of code readability) and just move that if condition outside for loop.
If we assume that compiler makes no optimization whatsoever, you would have 1 condition and possibly more than 2 billion iterations through vector. Also, since the condition would be if (true) or if (false) the branch prediction would work perfectly and execution would be less than 1 CPU instruction.
I'm pretty sure that all compilers on the market have this optimization, but I would quote my favorite when it comes to performance: "Premature optimization is the root of all evil" and "There're only 3 rules of optimization: Measure, measure and measure".
If you absolutely absurdly care about fast looking code:
(a clever compiler, or one otherwise hinted at using directives or intrinsics, could do this in parallel using SIMD; CUDA and OpenCL would of course eat this for breakfast!)
int count_odd(const int* array,size_t len) {
int count = 0;
const int* const sentinal = array+len;
while(array<sentinal)
count += (*array++ & 1);
return count;
}
int count_even(const int* array,size_t len) {
return len-count_odd(array,len);
}