How to convert vector<unsigned long> v; to char buffer[sizeof(unsigned long)*v.size()]; and vice-versa.
i tried with
std::copy(b.begin(), b.end(), buffer);
and v.insert() but result is ambiguous. Could any one suggest how to do this.
If you just need to pass the data to some library function which expects a char*
assert(v.size());
char *p = (char*) &v[0];
otherwise here is some sample code copying data back and forth from std::vector and char*, although I'd suggest sticking to one interface unless you have a reason for doing this.
#include <iostream>
#include <vector>
#include <memory>
#include <assert.h>
int main()
{
size_t count = 20;
std::vector<unsigned int> v;
v.resize(count);
assert(v.size());
// make a vector with the numbers 1 through count
for (size_t index = 0; index < count; ++index)
v[index] = index + 1;
// make a buffer of char[] (using unique_ptr to handle cleanup)
std::unique_ptr<char> buffer(new char[v.size() * sizeof(v[0])]);
// copy from v into a buffer of char[]
memcpy(buffer.get(), &v[0], v.size() * sizeof(v[0]));
// next we get rid of v, and copy the elements back in from the char buffer
v.clear();
// now suppose we have a char array of count unsigned ints (which we do)
// (the count better be right)
// just say it's an unsigned int* and you get pointer arithmetic for unsigned int
unsigned int * pInt = reinterpret_cast<unsigned int*>(buffer.get());
for (size_t index = 0; index < count; ++index)
v.push_back(*pInt++);
// print out as proof
for (auto &x : v)
std::cout << x << " ";
return 0;
}
For example you can try the following approach
#include <iostream>
#include <vector>
#include <cstring>
#include <numeric>
int main()
{
std::vector<unsigned long> v = { 1, 2, 3 };
char *p = new char[sizeof( unsigned long ) * v.size()];
std::accumulate( v.begin(), v.end(), p,
[]( char *p, unsigned long x)
{
return memcpy( p, &x, sizeof( x ) ), p + sizeof( x );
} );
std::vector<unsigned long> v2( v.size() );
char *q = p;
for ( auto &x : v2 )
{
memcpy( &x, q, sizeof( x ) );
q += sizeof( x );
}
for ( auto x : v2 ) std::cout << x << ' ';
std::cout << std::endl;
delete []p;
return 0;
}
The output is
1 2 3
The return statement in the lambda expression can be written also like
return ( char * )memcpy( p, &x, sizeof( x ) ) + sizeof( x );
Or indeed you could copy the whole vector in the character buffer the following way
std::memcpy( p, v.data(), v.size() * sizeof( unsigned long ) );
For example
#include <iostream>
#include <cstring>
#include <vector>
int main()
{
std::vector<unsigned long> v = { 1, 2, 3 };
char *p = new char[sizeof( unsigned long ) * v.size()];
memcpy( p, v.data(), v.size() * sizeof( unsigned long ) );
std::vector<unsigned long> v2( v.size() );
char *q = p;
for ( auto &x : v2 )
{
memcpy( &x, q, sizeof( x ) );
q += sizeof( x );
}
for ( auto x : v2 ) std::cout << x << ' ';
std::cout << std::endl;
delete []p;
return 0;
}
And instead of this loop
char *q = p;
for ( auto &x : v2 )
{
memcpy( &x, q, sizeof( x ) );
q += sizeof( x );
}
you also could use memcpy. For example
memcpy( v2.data(), p, v2.size() * sizeof( unsigned long ) );
Related
I am given a few array of both negative and positive numbers.
I should Find the maximum product obtained from multiplying 2 adjacent numbers in the array.
This is the code I wrote :
#include <vector>
#include <iostream>
using namespace std;
int adjacentElementsProduct(vector<int> inputArray)
{
for(int i = 0; i < inputArray.size(); i++) {
if((inputArray[i] * inputArray[i+1])>(inputArray[i+1] * inputArray[i+2])) {
std::cout << inputArray[i] * inputArray[i+1] << "\n";
} else if((inputArray[i+1] * inputArray[i+2])>(inputArray[i+2] * inputArray[i+3])) {
std::cout << inputArray[i+1] * inputArray[i+2] << "\n";
} else if((inputArray[i+2] * inputArray[i+3])>(inputArray[i+3] * inputArray[i+4])) {
std::cout << inputArray[i+2] * inputArray[i+3] << "\n";
} else if((inputArray[i+3] * inputArray[i+4])>(inputArray[i+4] * inputArray[i+5])) {
std::cout << inputArray[i+3] * inputArray[i+4] << "\n";
} else {
std::cout << "Unknow" << "\n";
} return 1;
}
}
int main() {
adjacentElementsProduct({5, 8});
adjacentElementsProduct({1,2,3});
adjacentElementsProduct({1,5,10,9});
adjacentElementsProduct({5,1,2,3,1,4});
adjacentElementsProduct({4,12,3,1,5});
adjacentElementsProduct({3,6,-2,-5,7,3});
adjacentElementsProduct({9, 5, 10, 2, 24, -1, -48});
adjacentElementsProduct({5, 6, -4, 2, 3, 2, -23});
adjacentElementsProduct({-23, 4, -5, 99, -27, 329, -2, 7, -921});
adjacentElementsProduct({1,0,1,0,1000});
adjacentElementsProduct({1,2,3,0});
return 1 ;
}
Output:
40
6
90
5
48
18
50
30
-20
Unknow
6
The code only compares the product of inputArray[i] * inputArray[i+1] and inputArray[i+1] * inputArray[i+2] But I want to find the maximum product among all the numbers in array.
You want to loop over the input vector and compute the products of adjacent elements.
Then, you want to find the maximum of those products. You don't need all that hardcoded [i+1], [i+2], [i+3], ... shenanigans, you already have something that can get all those numbers for you -- a for loop.
int adjacentElementsProduct(vector<int> inputArray)
{
// Set initial max product to a very small number so that
// it is always replaced by our first product
int maxProduct = std::numeric_limits<int>::min();
for(int i = 0;
i < inputArray.size() - 1; /* because we will be doing i + 1 inside the loop */
i++) {
// Calculate product of this and next element
int product = inputArray[i] * inputArray[i + 1];
if (product > maxProduct)
maxProduct = product; // This product is the greatest so far,
// so keep it and get rid of the old max.
}
return maxProduct;
}
To explain how this works, let's look at the execution of the function for an example input. Let's say we do adjacentElementsProduct({5,1,2,3,1,4});
maxProduct is set to some very large negative number (let's say -99999999)
inputArray.size() is 6. inputArray.size() - 1 is 5.
i = 0. Is 0 < 5? Yes. Go inside loop
product = inputArray[0] * inputArray[1] = 5
is 5 > maxProduct (-99999999)? Yes. Set maxProduct = 5
Increment i to 1.
i = 1. Is 1 < 5? Yes. Go inside loop
product = inputArray[1] * inputArray[2] = 2
is 2 > maxProduct (5)? No.
Increment i to 2.
i = 2. Is 2 < 5? Yes. Go inside loop
product = inputArray[2] * inputArray[3] = 6
is 6 > maxProduct (5)? Yes. Set maxProduct = 6
Increment i to 3.
i = 3. Is 3 < 5? Yes. Go inside loop
product = inputArray[3] * inputArray[4] = 3
is 3 > maxProduct (6)? No.
Increment i to 4.
i = 4. Is 4 < 5? Yes. Go inside loop
product = inputArray[4] * inputArray[5] = 4
is 4 > maxProduct (6)? No.
Increment i to 5.
i = 5. Is 5 < 5? No.
Return maxProduct, which is 6.
I think your function is overkill. You can do this with a running maxima:
const unsigned int length = inputArray.length();
int maximum = inputArray[0] * inputArray[1];
for (unsigned int i = 1U; i < (length - 1U); ++i)
{
const int product = inputArray[i] * inputArray[i + 1];
if (product > maximum) maximum = product;
}
This can be further optimized but that is an exercise for the OP.
Edit 1: Via Pointers
This may be more optimal, but only assembly language will tell (or profiling):
const unsigned int length = inputArray.length();
int const * p_first = &inputArray[0];
int const * p_second = &inputArray[1];
int maximum = (*p_first++) * (*p_second++);
for (unsigned int i = 1u; i < (length - 1); ++i)
{
int product = (*p_first++) * (*p_second++);
if (product > maximum) maximum = product;
}
In the above code fragment, the two array locations are maintained in pointers. The pointers can be maintained in registers. No need to calculate the offset within the loop each time. Incrementing pointers is simple and quick operation. Some processors have instructions that can dereference a pointer and increment in a single instruction. Some compilers may perform this optimization depending on the optimization setting.
Edit 2: Tracking Previous Value
Another optimization is to reduce the memory accesses by about half, by remembering the previous value in the array:
const unsigned int length = inputArray.length();
int previous = inputArray[0];
int next = inputArray[1];
int maximum = previous * next;
previous = next;
for (unsigned int i = 1u; i < length; ++i)
{
next = inputArray[i];
const int product = previous * next;
if (product > maximum) maximum = product;
previous = next;
}
In the above code fragment, the previous array value is remembered in a variable. This eliminates the need to access the array for the previous value; only one array access is required.
The compiler may perform this optimization at higher optimization levels. The proof is to compare the assembly language of the variables fragments.
There's an algorithm in <numeric> that does this for you:
int adjacentElementsProduct(std::vector<int> const & inputArray)
{
// [[assert: inputArray.size > 1 ]]
return std::inner_product(inputArray.begin(), inputArray.end() - 1,
inputArray.begin() + 1,
0,
[](int i, int j) { return std::max(i, j); },
std::multiplies{});
}
which is about as efficient, and readable as it gets.
For starters the function should not output any message. It is the caller of the function will decide whether to output a message or not.
The function should return an iterator or a pair of iterators that point to the two adjacent elements with the maximum product.
As for your function implementation then it has undefined behavior because it can access non-existent elements of the vector.
I can suggest the following function definition as it is shown in the demonstrative program below.
#include <iostream>
#include <utility>
#include <vector>
#include <iterator>
std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator>
adjacentElementsProduct( const std::vector<int> &v )
{
std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator>
p = { std::begin( v ), std::end( v ) };
if (not ( v.size() < 2 ))
{
p.second = std::next( std::begin( v ) );
long long int max_product = static_cast<long long int>( *p.first ) * *p.second;
for (auto prev = p.second, current = std::next( p.second );
current != std::end( v );
std::advance( prev, 1 ), std::advance( current, 1 ))
{
if (max_product < static_cast<long long int>( *prev ) * *current)
{
p = { prev, current };
}
}
}
return p;
}
int main()
{
std::vector<int> v = { 5, 8 };
auto p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1,2,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1,5,10,9 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 5,1,2,3,1,4 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 4,12,3,1,5 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 3,6,-2,-5,7,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 9, 5, 10, 2, 24, -1, -48 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 5, 6, -4, 2, 3, 2, -23 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { -23, 4, -5, 99, -27, 329, -2, 7, -921 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1, 0, 1, 0, 1000 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1,2,3,0 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
}
The program output is
40
6
90
6
48
21
48
30
-14
0
6
If you do not know yet iterators than the function can be defined the following way
#include <iostream>
#include <utility>
#include <vector>
std::pair<std::vector<int>::size_type, std::vector<int>::size_type>
adjacentElementsProduct( const std::vector<int> &v )
{
std::pair<std::vector<int>::size_type, std::vector<int>::size_type>
p = { 0, v.size() };
if (not ( v.size() < 2 ))
{
p.second = 1;
long long int max_product = static_cast<long long int>( p.first ) * p.second;
for (std::vector<int>::size_type i = 3; i < v.size(); i++ )
{
if (max_product < static_cast<long long int>( v[i - 1] ) * v[i] )
{
p = { i - 1, i };
}
}
}
return p;
}
int main()
{
std::vector<int> v = { 5, 8 };
auto p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1,2,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1,5,10,9 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 5,1,2,3,1,4 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 4,12,3,1,5 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 3,6,-2,-5,7,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 9, 5, 10, 2, 24, -1, -48 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 5, 6, -4, 2, 3, 2, -23 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { -23, 4, -5, 99, -27, 329, -2, 7, -921 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1, 0, 1, 0, 1000 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1,2,3,0 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
}
Given a string s = "RADILAMIA" I want to take all the substrings of length 4 (or something else).
If len == 4 then the substrings are: "RADI","ADIL","DILA","ILAM","LAMI","AMIA". It seems easy to do that by using the std::string substr method:
vector<string> allSubstr(string s,int len) {
vector<string>ans;
for(int i=0;i<=s.size()-len;i++) {
ans.push_back(s.substr(i,len));
}
return ans;
}
substr's time complexity is unspecified, but generally linear against the length of the substring.
Can I do this without std::string substr. Any substring and the previous substring differ in only one letter. Is there any better way to reduce the time complexity?
string_view (C++17) has a constant time substr:
vector<string_view> allSubstr(const string_view& s, int len) {
vector<string_view> ans;
and.reserve(s.size() - len + 1);
for (int i = 0 ; i <= s.size() - len; ++i) {
ans.push_back(s.substr(i, len));
}
return ans;
}
Just make sure that s outlives the return value of the function.
There can be millions of different approaches. Here is my algorithm.
vector<string> allSubstr(string s,int len) {
vector<string>ans;
ans.reserve(s.size() - len );
for(size_t i=0;i<=s.size()-len;i++)
{
ans.emplace_back( s.begin() +i, s.begin() + i + len );
}
return ans;
}
It is tested. I mean it wouldn't matter what you are using but emplace_back above can make a difference since there won't be copy cost. Also you add reserve for more performance.
No matter what you do, you still need O(NL) time to write all your substrings into the vector.
The fastest thing would be probably:
vector<string> ans(s.size()-len);
for(int i=0;i<=s.size()-len;i++) {
ans[i] = s.substr(i, len);
}
Because push_back is slowish, and should generally be avoided if possible. It is overused.
PS: maybe this code would be even faster:
vector<string> ans(s.size()-len);
for(int i=0;i<=s.size()-len;i++) {
ans[i].append(s.begin()+i, s.begin()+i+len);
}
Probably you could use an array of chars instead. For example, you have got your word:
char s[] = "RADILAMIA";
To deal with all necessary substrings you can use such approach:
int substLength = 4;
int length = strlen(s);
char buffer[256];
for (int i = 0; i < length - substLength + 1; i++) {
strncpy(buffer, s + i, substLength);
buffer[substLength] = '\0';
cout << buffer << endl;
}
Using the char array you easily can access to the start of any substring by adding the necessary index to the beginning of the array.
It pays to revisit the docos
// string proto(len);
vector<string> result(s.size()-len, string(len, char(32))); // preallocates the buffers
const char *str=s.c_str();
const char* end=str+s.size()-len;
for(size_t i=0; str<end; str++, i++) {
result[i].assign(str, len); // likely to result in a simple copy in the preallocated buffer
}
The complexity is the same O(len*s.size()) - one can only hope for a smaller proportionality factor.
C is not always faster than C++ but #Fomalhaut was right to post the performant core solution in C. Here is my (C program) complete version, based on his algorithm. Without using strncpy, too.
Here it is on the godbolt.
#ifdef __STDC_ALLOC_LIB__
#define __STDC_WANT_LIB_EXT2__ 1
#else
#define _POSIX_C_SOURCE 200809L
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>
//////////////////////////////////////////////////////////////
// array of buffers == a_of_b
typedef struct a_of_b {
const unsigned size;
unsigned count ;
char ** data ;
} a_of_b ;
a_of_b a_of_b_make ( const unsigned size_ )
{
return (a_of_b){ .size = size_, .count = 0, .data = calloc(1, sizeof(char * [size_] ) ) } ;
}
a_of_b * a_of_b_append ( a_of_b * self, const unsigned len_, const char str_[len_] )
{
assert( self->data ) ;
assert( self->size > self->count ) ;
self->data[ self->count ] = strndup( str_, len_ ) ;
self->count += 1;
return self ;
}
a_of_b * a_of_b_print ( a_of_b * self , const char * fmt_ )
{
for (unsigned j = 0; j < self->count; ++j)
printf( fmt_ , self->data[j]);
return self ;
}
a_of_b * a_of_b_free ( a_of_b * self )
{
for (unsigned j = 0; j < self->count; ++j)
free( self->data[j]) ;
free( self->data) ;
self->count = 0 ;
return self ;
}
//////////////////////////////////////////////////////////////
a_of_b breakit ( const unsigned len_, const char input_[len_], const unsigned substLength )
{
assert( len_ > 2 ) ;
assert( substLength > 0 ) ;
assert( substLength < len_ ) ;
const unsigned count_of_buffers = len_ - substLength + 1;
a_of_b rez_ = a_of_b_make( count_of_buffers +1 ) ;
for (int i = 0; i < count_of_buffers ; i++) {
a_of_b_append( &rez_, substLength, input_ + i ) ;
}
return rez_ ;
}
//////////////////////////////////////////////////////////////
static void driver( const char * input_, const unsigned substLength )
{
printf("\n");
a_of_b substrings = breakit( strlen(input_), input_, substLength );
a_of_b_print( & substrings , "%s ");
a_of_b_free( & substrings);
}
//////////////////////////////////////////////////////////////
int main () {
driver( "RADILAMIA", 4) ;
driver( "RADILAMIA", 3) ;
driver( "RADILAMIA", 2) ;
driver( "RADILAMIA", 1) ;
return EXIT_SUCCESS;
}
And the program output is:
RADI ADIL DILA ILAM LAMI AMIA
RAD ADI DIL ILA LAM AMI MIA
RA AD DI IL LA AM MI IA
R A D I L A M I A
Enjoy.
How would it be possible to feed the TEA cipher without exceeding a systems ram with large files?
I have tried doing this however it has all ended with massive failure and hours of tinkering that leads to nothing. So could someone give me an example of how this can be done or any meaningful information on how to do it?
void decodeXtea(unsigned int* v, unsigned int* w, unsigned int* k) {
register unsigned int v0=v[0], v1=v[1], i, sum=0xC6EF3720;
register unsigned int delta=0x9E3779B9;
for(i=0; i<32; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
w[0]=v0; w[1]=v1;
}
void TeaDecode ( const std::string& str, const std::string& key, std::string* out )
{
unsigned int v[2];
unsigned int w[2];
unsigned int k[4];
unsigned int keybuffer [ 4 ];
// Clear buffers
memset ( v, 0, sizeof(v) );
memset ( w, 0, sizeof(w) );
memset ( k, 0, sizeof(k) );
memset ( keybuffer, 0, sizeof(keybuffer) );
out->clear ();
// Count the number of passes that we need
int numBlocks = str.length() / 4;
int numPasses = numBlocks - 1;
if ( numPasses <= 0 )
return;
// Process the key
int len = key.length ();
if ( len > 16 )
len = 16;
memcpy ( keybuffer, key.c_str(), len );
for ( int i = 0; i < 4; ++i )
k[i] = keybuffer[i];
// Create a temporary buffer to store the result
unsigned char* buffer = new unsigned char [ numPasses * 4 + 4 ];
memset ( buffer, 0, numPasses * 4 + 4 );
// Decode it!
const char* p = str.c_str();
v[1] = *(unsigned int*)&p[numPasses * 4];
for ( int i = 0; i < numPasses; ++i )
{
v[0] = *(unsigned int*)&p[(numPasses-i-1)*4];
decodeXtea ( &v[0], &w[0], &k[0] );
*(unsigned int*)&buffer[(numPasses-i-1)*4] = w[0];
v[1] = w[1];
}
out->assign ( (char *)buffer, numPasses*4 );
delete [] buffer;
}
void encodeXtea(unsigned int* v, unsigned int* w, unsigned int* k) {
register unsigned int v0=v[0], v1=v[1], i, sum=0;
register unsigned int delta=0x9E3779B9;
for(i=0; i<32; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
}
w[0]=v0; w[1]=v1;
}
void TeaEncode ( const std::string& str, const std::string& key, std::string* out )
{
unsigned int v[2];
unsigned int w[2];
unsigned int k[4];
unsigned int keybuffer [ 4 ];
// Clear buffers
memset ( v, 0, sizeof(v) );
memset ( w, 0, sizeof(w) );
memset ( k, 0, sizeof(k) );
memset ( keybuffer, 0, sizeof(keybuffer) );
out->clear ();
// Process the key
int len = key.length ();
if ( len > 16 )
len = 16;
memcpy ( keybuffer, key.c_str(), len );
for ( int i = 0; i < 4; ++i )
k[i] = keybuffer[i];
// Copy the input string to a buffer of size multiple of 4
int strbuflen = str.length ();
if ( strbuflen == 0 )
return;
if ( (strbuflen % 4) > 0 )
strbuflen += 4 - (strbuflen % 4);
unsigned char* strbuf = new unsigned char [ strbuflen ];
memset ( strbuf, 0, strbuflen );
memcpy ( strbuf, str.c_str(), str.length() );
// Encode it!
v[1] = 0;
for ( int i = 0; i < strbuflen; i += 4 )
{
v[0] = *(unsigned int*)&strbuf[i];
encodeXtea ( &v[0], &w[0], &k[0] );
out->append ( (char*)&w[0], 4 );
v[1] = w[1];
}
out->append ( (char*)&v[1], 4 );
delete [] strbuf;
}
This fixed it.
void readSystem(string fname,string outFileName,string key,string mode)
{
//size_t buffer_size = 1<<20;
size_t buffer_size;
if(mode == "E")
{
buffer_size = 32;
}
else
{
buffer_size = 36;
}
//char *buffer = new char[buffer_size];
string buffer(buffer_size,'\0');
string data,output;
//data.resize(buffer_size);
// The input
std::ifstream fin(fname,ios::binary);
// The output
ofstream outFile(outFileName,ios::binary);// | ios::app);
// Anti overwrite
if(getSize(outFileName) > 0)
{
cout << "Overwrite error" << endl;
exit(0);
}
while (fin)
{
// Try to read next chunk of data
// fin.read(buffer, buffer_size);
fin.read(&buffer.front(), buffer_size);
// Get the number of bytes actually read
size_t count = fin.gcount();
data = buffer;
//data = encode(data,key);
if(mode == "E")
{
data = encode(data,key);
}
if(mode == "D")
{
data = decode(data,key);
}
//blockXor(data,key);
//outFile.write(data.c_str(),count);
outFile.write(data.c_str(),data.length());
// If nothing has been read, break
if (!count)
break;
// Do whatever you need with first count bytes in the buffer
}
outFile.close();
fin.close();
// delete[] buffer;
}
I have a large array (image) and I need to do many small configurable computations on that data.
I'll post an example here.
NOTE: This is not the actual problem, but a minimal / hopefully illustrative example of what I need to do.
// different functions that can be called based on the configuration
float func1( float* a )
{
return (*a) * (*a);
}
float func2( float* a )
{
return (*a) + (*a);
}
float func3( float* a )
{
return 2 * (*a) * (*a);
}
// my data
float* data = new float[1024*1024];
// function that manages the configurations
int main( )
{
int param1 = 0;
int param2 = 1;
for ( int k = 0; k < 1024*1024; k++ )
{
if ( param1 == 2 && param2 == 0 )
data[k] = func1( data + k );
else if ( param1 == 1 && param2 == 1 )
data[k] = func2( data + k );
else if ( param1 == 0 && param2 == 1 )
data[k] = func3( data + k );
else
continue;
}
}
In my code, it does not make sense to put the loop inside of each function.
However, param1 and param2 remain constant during the loop and they are known at compile time.
Is there a way to remove the influence of the if/elseif statements?
You can move your if-else statement that selects appropriate function to use out of the loop, thus getting to:
#include <functional>
// different functions that can be called based on the configuration
float func1( float* a )
{
return (*a) * (*a);
}
float func2( float* a )
{
return (*a) + (*a);
}
float func3( float* a )
{
return 2 * (*a) * (*a);
}
// my data
float* data = new float[1024*1024];
// function that manages the configurations
int main( )
{
int param1 = 0;
int param2 = 1;
std::function< float( float* )> functionToUse = nullptr;
if ( param1 == 2 && param2 == 0 )
functionToUse = std::function<float(float*)>(func1);
else if ( param1 == 1 && param2 == 1 )
functionToUse = std::function<float(float*)>(func2);
else if ( param1 == 0 && param2 == 1 )
functionToUse = std::function<float(float*)>(func3);
if(functionToUse){
for ( int k = 0; k < 1024*1024; k++ )
{
data[k] = functionToUse( data + k );
}
}
}
As to choosing the function to use during compilation time I'd suggest checking out this question:
if/else at compile time?
Also this question might be of interest:
Is cutting if statements by using function pointers going to be more efficient?
As long as the parameters are const OR the compiler can 100% determine that they variables aren't aliased and thus won't change (harder for the compiler) I would completely expect the optimizer to totally remove the runtime branch and do all the work at compile time.
If however you don't prefer to rely on the optimizer you can use templates:
template <int c1, int c2>
float func(float* a)
{
// No-op.
}
template <>
float func<2, 0>(float* a)
{
return (*a) * (*a);
}
template <>
float func<1, 1>(float* a)
{
return (*a) + (*a);
}
template <>
float func<0, 1>(float* a)
{
return 2 * (*a) * (*a);
}
int main()
{
const int param1 = 0;
const int param2 = 1;
for ( int k = 0; k < 1024*1024; k++ )
{
func<param1, param2>(<float ptr>);
}
}
Maybe something like this
#include <iostream>
#include <map>
#include <functional>
#include <utility>
typedef std::pair<size_t, size_t> pair;
typedef std::map< pair, std::function<float( float* )>> map;
// different functions that can be called based on the configuration
float func1( float* a )
{
return ( *a ) * ( *a );
}
float func2( float* a )
{
return ( *a ) + ( *a );
}
float func3( float* a )
{
return 2 * ( *a ) * ( *a );
}
// my data
float* data = new float[1024 * 1024];
void init( map &myMap )
{
myMap.insert( pair, std::function<float( float* )>>
( pair( 2, 0 ), std::function< float( float* )>( func1 ) ) );
myMap.insert( pair, std::function<float( float* )>>
( pair( 1, 1 ), std::function< float( float* )>( func2 ) ) );
myMap.insert( pair, std::function<float( float* )>>
( pair( 0, 2 ), std::function< float( float* )>( func3 ) ) );
}
// function that manages the configurations
int main( )
{
int param1 = 0;
int param2 = 1;
map myMap;
init( myMap );
for( int k = 0; k < 1024 * 1024; k++ )
{
data[k] = myMap[pair( param1, param2 )]( data + k );
}
}
Given: (In C++)
int main () {
int* ptr;
int ary [10][2];
ptr = ary;
return 0;
}
How would I access ary[0][1] with ptr?
You can't, because the type of ptr is wrong. The variable should be declared as int(*)[2] (pointer to an array of size 2 of integers). Then you could just use ptr[0][1].
#include <cstdio>
int main () {
int (* ptr) [2]; // <--
int ary [10][2];
ptr = ary;
ary[0][1] = 5;
printf("%d\n", ptr[0][1]);
return 0;
}
If you must use an int*, you need to introduce a reinterpret_cast. The array indices are laid out like:
0 1 2 3 2*n 2*n+1
[0][0] [0][1] [1][0] [1][1] ... [n][0] [n][1]
so you could use ptr[1] to get ary[0][1].
#include <cstdio>
int main () {
int* ptr;
int ary [10][2];
ptr = reinterpret_cast<int*>(ary); // <--
ary[0][1] = 5;
printf("%d\n", ptr[1]);
return 0;
}
typedef int tenints[10]; // tenints is an array of 10 ints
int main () {
tenints ary[2]; // array of 2 tenints, same as your int ary[10][2];
tenints* ptr = ary
// ptr[0] or *ptr is the first row
// ptr[1] or *(ptr+1)is the second row
int* ptr2 = ptr[0];
// ptr2[1] or *(ptr2+1) is ary[0][1]
// if you don't want do use as intermediate variable,
// just substitute "*ptr" for "ptr2" in "*(ptr2+1)"
int val = *((*ptr)+1);
return 0;
}
What you want only works when the data is on block which it might not be in all cases. In the context of image processing, you mostly do something like this:
int width = 1024;
int height = 768;
char* img = new char[width*height];
char** img2d = new char*[height];
for (int y = 0; y < height; ++y){
img2d[y] = img + y*width;
}
//set pixel at x=50, y=100
img2d[100][50] = 1;
//does the same
img2d[100*width+50] = 1;
delete[] img;
it is possible, just look at this example ( these are dynamic arrays, but works with static too ):
void bla ( void )
{
const int32_t sx = 50, sy = 30, sz = 50;
uint64_t *** n = NULL;
n = ( uint64_t*** )malloc( sizeof( uint64_t** ) * sx );
for ( int32_t x = 0; x < sx; x++ )
{
*( n + x ) = ( uint64_t** )malloc( sizeof( uint64_t* ) * sy );
for ( int32_t y = 0; y < sy; y++ )
*( *( n + x ) + y ) = ( uint64_t* )malloc( sizeof( uint64_t ) * sz );
}
for ( int32_t x = 0; x < sx; x++ )
for( int32_t y = 0; y < sy; y++ )
for( int32_t z = 0; z < sz; z++ )
*( *( *( n + x ) + y ) + z ) = 1024 * 1024;
}