Reading dynamically allocated arrays into lists - c++

Currently, I have been reading lists of data from a binary data file programmatically as follows:
tplR = (double*) malloc(sampleDim[0]*sizeof(double));
printf("tplR = %d\n", fread(tplR, sizeof(double), sampleDim[0], dfile));
However, as I want to use find_if() function on those lists, I would need to get tplR into a list type in stl. In terms of general C++ programming practice, is it usually good practice to make tplR into a list only when I really have to?
If I do make another member variable, for example, tplRList, what would be the easiest way of pushing all sampleDim[0] number of double precision entries into tplRList from tplR? Pushing them one by one until the incremental counter is equal to sampleDim[0]?
Thanks in advance.

You can use find_if with the array like this:
bool equals(int p)
{
return p == 9;
}
int main(int argc,char *argv[])
{
int a[10];
for(int i = 0; i < 10; ++i)
{
a[i] = i;
}
int* p = std::find_if(a, a+10, equals);
cout<<*p;
return 0;
}

You're mistaken in your assumptions. std::find_if() merely requires an iterator, not necessarily an STL iterator. As it happens, double* supports both * and ++, so it too is an iterator.

bool checkValue(double val);
std::find_if(tplR, tplR + sampleDim[0], checkValue);

#include <boost/lambda/lambda.hpp\>
using namespace boost::lambda;
static const double whateverValueYouWant(12.);
double *const tplR = (double*) malloc(sampleDim[0]*sizeof(double));
const size_t actualItemsRead = fread(tplR, sizeof(double), sampleDim[0], dfile);
printf("tplR = %d\n", actualItemsRead );
const double *begin = tplR;
const double *const end = tplR + actualItemsRead;
const double *const foundItem = std::find_if( begin, end, _1== whateverValueYouWant);
if( foundItem!=end )
{
//value found
}
else
{
//no such value
}

Related

C++ templated function to add int at the end of an array [duplicate]

I have the following array:
int a1[] = {1,2,3,4,5,6};
I would like to know how can I append any number to the front, and to the back of this array. In JavaScript, there is unshift() and push(). Is there anything like that in C++?
In C++, arrays are a kind of type, and the array size is part of the type. Therefore, the size of an array object is part of this object's type and not modifiable at runtime.
To manage dynamic collections of objects in C++, you would usually use a container class. There are several useful containers included in the standard library; the most important one is std::vector, which manages a dynamic, contiguously stored sequence of elements — essentially a resizable array!
A JavaScript array is much closer to a C++ vector (or perhaps to a hash map) than to a C++ array.
Unlike Javascipt arrays, which are all-purposed arrays, C++ gives you few types of consecutive containers.
In your example, you demonstrated the use of built-in arrays also known as C-arrays. they are basically size-immutable arrays, and other than being a line of bytes which holds up variables value, they have no special features.
For flexible high-level arrays, use either std::vector, or the less known-but-really-awsome std::deque.
Also, get familiar with std::array which is a good subsitute for built-in arrays.
You can't do it directly, but if you like, you can write a simple code to manage it:
#include <stdlib.h>
#include<stdarg.h>
#include <iostream>
using namespace std;
typedef struct int_array
{
int *ptr;
int len;
int_array(int n_args, ...)
{
ptr = NULL;
len = 0;
va_list ap;
va_start(ap, n_args);
for (int i = 1; i <= n_args; i++) {
push(va_arg(ap, int));
}
va_end(ap);
}
int operator[](int idx) const
{
return ptr[idx];
}
void push(int value)
{
ptr = (int*)(len ? realloc(ptr, (len + 1)*sizeof(int)) : malloc(sizeof((len + 1))));
ptr[len++] = value;
}
void unshift(int value)
{
ptr = (int*)(len ? realloc(ptr, (len+1)*sizeof(int)) : malloc(sizeof(len+1)));
for (int i = len++; i > 0; i--)
{
ptr[i] = ptr[i-1];
}
ptr[0] = value;
}
}IntArray;
int main(int argc, char** argv)
{
IntArray arr(6/* initial len */, 1, 2, 3, 4, 5, 6);
arr.push(7);
arr.push(8);
arr.unshift(0);
arr.unshift(-1);
for (int i = 0; i < arr.len;i++)
{
cout << arr[i] << endl;
}
return 0;
}

recursive binary search in c++ using a bool function

I have an school assignement that requires me to create a recursive Binary search function. I'm not allowed to change the function signature.
My experience with pointer isn't the best and i think my problem lies there.
I get an Stackoveflow but i dont really understand way
bool contains(const int* pBegin, const int* pEnd, int x)
{
int length = pEnd - pBegin;//gives me the length of the array
const int* pMid = pBegin + (length / 2);
if(length == 1)
{
if(*pMid != x)
return false;
return true;
}
else if(x < *pMid)
return contains(pBegin, pMid-1, x);
else
return contains(pMid, pEnd, x);
}
void main(){
setlocale(LC_ALL, "swedish");
int arr[10];
for(int i = 0; i < 10; ++i)
arr[i] = i;
bool find = contains(&arr[0], &arr[10], 3);//arr[10] points to the index after the array!
cout <<"found = "<< find << endl;
system("pause");
}
Can somebody please explain to me what I'm doing wrong, and how i could do it in a better way?
Stack overflow is due to too deep recursion.
Its unlikely your array is large enough to really be a problem, so what you have is unbounded recursion ... contains() keeps calling itself and fails to detect this.
Look at how this is possible, and add assertions.
Your code assumes
pEnd > pBegin
Your code doesn't handle this possibility.
#include <assert.h>
bool contains( ... )
{
assert(pBegin > pEnd);
...
Now, it will abort if this assumption is incorrect.
There are two possibities for (pEnd > pBegin) being false, namely "<" or "==".
What does your code do in these two cases?
Spoiler below..
Length can be zero and isn't handled.

C++: Append to front, add to back array of int's

I have the following array:
int a1[] = {1,2,3,4,5,6};
I would like to know how can I append any number to the front, and to the back of this array. In JavaScript, there is unshift() and push(). Is there anything like that in C++?
In C++, arrays are a kind of type, and the array size is part of the type. Therefore, the size of an array object is part of this object's type and not modifiable at runtime.
To manage dynamic collections of objects in C++, you would usually use a container class. There are several useful containers included in the standard library; the most important one is std::vector, which manages a dynamic, contiguously stored sequence of elements — essentially a resizable array!
A JavaScript array is much closer to a C++ vector (or perhaps to a hash map) than to a C++ array.
Unlike Javascipt arrays, which are all-purposed arrays, C++ gives you few types of consecutive containers.
In your example, you demonstrated the use of built-in arrays also known as C-arrays. they are basically size-immutable arrays, and other than being a line of bytes which holds up variables value, they have no special features.
For flexible high-level arrays, use either std::vector, or the less known-but-really-awsome std::deque.
Also, get familiar with std::array which is a good subsitute for built-in arrays.
You can't do it directly, but if you like, you can write a simple code to manage it:
#include <stdlib.h>
#include<stdarg.h>
#include <iostream>
using namespace std;
typedef struct int_array
{
int *ptr;
int len;
int_array(int n_args, ...)
{
ptr = NULL;
len = 0;
va_list ap;
va_start(ap, n_args);
for (int i = 1; i <= n_args; i++) {
push(va_arg(ap, int));
}
va_end(ap);
}
int operator[](int idx) const
{
return ptr[idx];
}
void push(int value)
{
ptr = (int*)(len ? realloc(ptr, (len + 1)*sizeof(int)) : malloc(sizeof((len + 1))));
ptr[len++] = value;
}
void unshift(int value)
{
ptr = (int*)(len ? realloc(ptr, (len+1)*sizeof(int)) : malloc(sizeof(len+1)));
for (int i = len++; i > 0; i--)
{
ptr[i] = ptr[i-1];
}
ptr[0] = value;
}
}IntArray;
int main(int argc, char** argv)
{
IntArray arr(6/* initial len */, 1, 2, 3, 4, 5, 6);
arr.push(7);
arr.push(8);
arr.unshift(0);
arr.unshift(-1);
for (int i = 0; i < arr.len;i++)
{
cout << arr[i] << endl;
}
return 0;
}

Cplusplus std::set of bidimensional array

I'm new to C++ and I need to use Set from the STL but I'm struggling with the concept.
I have an array like this int my_data[3]
I want to create (don't know if this is possible) a set with space for 3 ints and that the key for the set would be the int that is stored on the first column.
I also want to make a custom sort.
This is what I've tried but with no success.
struct sort_set {
bool operator() (const int& a, const int& b) const {
int* arr1 = (int*) a;
int* arr2 = (int*) b;
int diff = arr2[1] - arr1[1];
if (diff) {
return true;
} else if (diff == 0) {
int diff2 = arr2[2] - arr1[2];
if (diff2) {
return false;
}
}
return arr1[0] < arr2[0];
}
};
set<int[3],sort_set> data;
Can someone point me in the right direction?
You cannot have arrays as elements of containers. They're not assignable nor copyable.
Use std::array<int, 3> if you have C++11 avaliable, or define a custom class otherwise.

What is the best way of comparing a string variable to a set of string constants?

if statement looks too awkward, because i need a possibility to increase the number of constatnts.
Sorry for leading you into delusion by that "constant" instead of what i meant.
Add all your constants to a std::set then you can check if the set contains your string with
std::set<std::string> myLookup;
//populate the set with your strings here
set<std::string>::size_type i;
i = myLookup.count(searchTerm);
if( i )
std::cout << "Found";
else
std::cout << "Not found";
Depends whether you care about performance.
If not, then the simplest code is probably to put the various strings in an array (or vector if you mean you want to increase the number of constants at run time). This will also be pretty fast for a small number of strings:
static const char *const strings[] = { "fee", "fie", "fo", "fum" };
static const int num_strings = sizeof(strings) / sizeof(char*);
Then either:
int main() {
const char *search = "foe";
bool match = false;
for (int i = 0; i < num_strings; ++i) {
if (std::strcmp(search, strings[i]) == 0) match = true;
}
}
Or:
struct stringequal {
const char *const lhs;
stringequal(const char *l) : lhs(l) {}
bool operator()(const char *rhs) {
return std::strcmp(lhs, rhs) == 0;
}
};
int main() {
const char *search = "foe";
std::find_if(strings, strings+num_strings, stringequal(search));
}
[Warning: I haven't tested the above code, and I've got the signatures wrong several times already...]
If you do care about performance, and there are a reasonable number of strings, then one quick option would be something like a Trie. But that's a lot of effort since there isn't one in the standard C++ library. You can get much of the benefit either using a sorted array/vector, searched with std::binary_search:
// These strings MUST be in ASCII-alphabetical order. Don't add "foo" to the end!
static const char *const strings[] = { "fee", "fie", "fo", "fum" };
static const int num_strings = sizeof(strings) / sizeof(char*);
bool stringcompare(const char *lhs, const char *rhs) {
return std::strcmp(lhs, rhs) < 0;
}
std::binary_search(strings, strings+num_strings, "foe", stringcompare);
... or use a std::set. But unless you're changing the set of strings at runtime, there is no advantage to using a set over a sorted array with binary search, and a set (or vector) has to be filled in with code whereas an array can be statically initialized. I think C++0x will improve things, with initializer lists for collections.
Put the strings to be compared in a static vector or set and then use std::find algorithm.
The technically best solution is: build a 'perfect hash function' tailored to your set of string constants, so later there are no collisions during hashing.
const char * values[]= { "foo", "bar", ..., 0 };
bool IsValue( const std::string & s ) {
int i = 0;
while( values[i] ) {
if ( s == values[i] ) {
return true;
}
i++;
}
return false;
}
Or use a std::set.