how can I find struct data in vector's element? - c++

I am working on client/server project. i am struggling with how to find vector's information in database to match client's account number that requested.
header file
struct storeData
{
int iAccountNumber;
int iPin;
double dBalance;
string sFirstName;
string sLastName;
string sMiddleInitial;
};
vector <storeData> storeDataArray;
storeData dataObj;
in server file..
int MyThread::findAccountNumberInStore(int iAccountNumber)
{
int iIndex = -1;
for(int unsigned i = 0; i <= storeDataArray.size(); i++)
{
//i got error message in if statement. i dont know how to fix it.
if(iAccountNumber == storeDataArray.at(dataObj.iAccountNumber))
{
return i;
}
}
return iIndex; //no account is found...
}
Also how can I store the struct's data in vector (all data in one element)?

From vector.at description:
Returns a reference to the element at position n in the vector.
The function automatically checks whether n is within the bounds of valid elements in the vector, throwing an out_of_range exception if it is not (i.e., if n is greater or equal than its size). This is in contrast with member operator[], that does not check against bounds.
You can read more about this function here:
vector.at
also you can read a discution about it here:
vector::at vs. vector::operator[]
to your practical problem i suggest using it like this:
if(iAccountNumber == storeDataArray.at(i).iAccountNumber)

You almost have it - the bracket is in the wrong place, and you didn't index the vector correctly, you have
if(iAccountNumber == storeDataArray.at(dataObj.iAccountNumber))
Should be
if(iAccountNumber == storeDataArray.at(i).iAccountNumber)
Also I see you use <= on array size check - this is incorrect. Vector bounds are from 0 to size()-1

Related

How would I print the index of an array? C++

I was just wondering how do I print off the Index position of an array? I know there's an if loop involved but I just can't seem to understand it properly.
I want the code to be able to print off what the element of the Array is and the position number. I should also mention that this is for a function as well. Any help will be appreciated. Below is my code
int index_of(string names[], int size)
{
string name;
int index;
for(int i = 0; i < size; i++)
{
if (to_lowercase (names[i]) == to_lowercase(name));
{
return;
}
}
}
What you are trying to do is called "searching".
You have a string which (potentially) is the known content of an entry in an array, but at an unknown index.
What you need to do is to find the index which, used for accessing the entry at that index, yields content which is identical to what you are looking for.
The code you show is more or less pseudo code for doing exactly that.
However, the shown code will not work for the following reasons:
it does not correctly return the index in question, it should return i;
it only returns explicitly in case of finding something, it should, after the loop, return -1;(as a proposal how to communicate failure)
it incorrectly compares (the == operator cannot meaningfully be used on "strings", which in C are only pointers to characters), it should use strncmp(), see e.g. https://en.cppreference.com/w/c/string/byte/strncmp
it does not actually print anything, but I think that is a problem of phrasing your goal and you can easily add a print outside of the shown code, using the (now hopefully correct and correctly returned) return value of the shown function
it has the problem mentioned by Nathan Pierson, see their comment/answer
This is what managed to print the indexes, you guys were actually able to help me understand what I was doing
int index_of(string names[], int size, string name)
{
for(int i = 0; i < size; i++)
{
if (to_lowercase (names[i]) == to_lowercase(name));
{
return i;
}
return -1;
}
}

Is there a way to find the INDEX of the minimum value in an array using a recursive function? C++

I need to find the Index of the minimum number in an array using a recursive function in c++ the function can only get 2 parameters: the pointer to the array and the size of it.
int smallest(int arr[], int num);
I managed to do this but with a helper variable that is static and declared outside the function here is what I got:
static int flag = 0;
int smallest(int* arr, int num) {
if (flag == num - 1)
return flag;
if (arr[num - 1] > arr[flag]) {
return smallest(arr, num - 1);
} else {
flag++;
return smallest(arr, num);
}
}
Now my question is can I do this without the static variable or any other variable other than the num? here is what I got so far:
int smallest(int arr[], int num) {
if (arr != &arr[num - 1])
if (*arr < arr[num - 1])
smallest(arr, num - 1);
else
smallest(arr + 1, num);
return num - 1;
}
It doesn't return the index of the minimum value but it does get to its adress, the function ends when the array pointer address is the same as the address of the minimum value. how can I get it to return the index?
I'm a student and I'm pretty new to C++ I appreciate the help! thanks!
===
edit:
this is originally from a homework assignment but the constraint to not use external help variables or functions is mine! and I'm curious to know if its even possible.
Because this is obviously homework, I'm not going to reveal the ACTUAL answer in entirety, but I'll give some (hopefully) good advice.
With recursion, think first of what your end condition is. That should be an array of 1 element. You return the index 0 in that case because of the array you have, it's the only element, so return the index of it.
if(num == 1)
{
return 0;
}
So then how is that useful to you? Compare it to exactly one other element. That's how you break this down. Your array turns into "one element and MANY" or "It's just one element." If it's just one, return the only value. If it's many, call yourself recursively from the second element (index 1) onward:
int restOfArraySmallest = smallest(arr+1, num-1) + 1;
You need the +1 because you've offset where it starts from. But you know the value in restOfArraySmallest is the index into YOUR arr of the smallest value of everything except the first element. Because your recursive calls don't include the first element, just the rest.
Hopefully that's enough to get you the rest of the way.
Edit: Because the OP has responded and said it wasn't essential to their homework assignment, here's the entire function:
// Recursively finds the index of the smallest element of the passed-in array
int smallest(int* arr, int num)
{
if(num <= 1)
{
return 0; // If we're in the last element, the smallest is the only element
}
// More than one element, so find the least element in all the elements
// past the first element of the array
// Note: the index returned is offset from our current view of the array,
// so add +1 to any returned result so we can index directly from it
int restOfArraySmallest = smallest(arr+1, num-1) + 1;
// Compare the first element in the array to the smallest of the entire rest
// of the array:
if(arr[0] < arr[restOfArraySmallest])
{
// The first element is smaller, it's the smallest, so return that index
return 0;
}
else
{
// The element already found is smaller, so return that index. It's already
// correctly offset
return restOfArraySmallest;
}
}
And that's it. If there's duplicate entries for smallest, it will favor the LAST one.
The trick with recursion is to NOT keep external variables. What you pass as the arguments and RETURN BACK are all the information you have. For some algorithms, it's enough.
Note, if you use recursive functions with datasets big enough, you will eventually get a Stack Overflow. Not the website, the crash type. This algorithm is pretty light in that only one extra variable and the two arguments themselves get allocated each pass, but it adds up eventually.

Counting the elements in a local array

I have a double x[12] which has no elements in it. When the user is prompted, he/she enters a number, which is stored in x.
I want the program to first check if x is empty and if it is, put the user's input in x[0] or if it isn't, put the user's input in the next free index.
I had done this:
...
double x[12];
void AddPayment(double Amount)
{
int i = sizeof(x);
x[i] = Amount;
}
Is it that sizeof() doesn't work with arrays, is there a better way of doing this?
When sizeof is applied to an array, it does not tell you how much data the array holds; it tells you how much data the array could hold. The fact that you did not specify any data to put into your double x[12] has no influence on the size of the array. Therefore, sizeof would return the number of bytes required on your system to hold an array of twelve doubles.
If you would like to keep a count of how many items among 12 have been assigned, add a separate variable for it. Initialize it to zero, and use it to keep track of how many items have been inserted:
size_t x_count = 0;
double x[12];
void AddPayment(double Amount) {
if (x_count == 12) {
// Error; we cannot add more than 12 items.
// Tell the user what's going on and quit,
// or handle the error in some other way.
cerr << "Cannot add more than 12 elements to x[]" << endl;
return;
}
x[x_count++] = Amount;
}
Whether x[12] has values or not, it will always have a size of 12 * sizeof(double).
So using the sizeof() operator is not a good way to accomplish your aim.
A best thing to do would be initialize x[12] with a value that the user cannot enter, say 0, and test for the first available location in the array that has a zero to enter that value.
double x[12] = { 0 };
void AddPayment(double Amount)
{
for (int i = 0; i < 12; i++) {
if (x[i] == 0) {
x[i] = Amount;
break;
}
}
}
I have a double x[12] which has no elements in it.
That's a misconception. double x[12]; creates 12 double elements, leaving their values in an undefined status. So you have 12 uninitialised elements. That's quite different from having no elements.
(The misconception would become even clearer if you had, for example, an array of type std::string. Unlike double, std::string is always initialised to a defined value, an empty string. So std::string x[12] would definitely be 12 strings, not an empty array.)
When the user is prompted, he/she enters a number, which is stored in
x.
I want the program to first check if x is empty and if it is, put the
user's input in x[0] or if it isn't, put the user's input in the next
free index.
I'm really surprised that nobody has suggested this, but an array is the wrong tool for what you are trying to accomplish. You need a container which can grow. You need std::vector:
std::vector<double> x; // starts off empty
void AddPayment(double Amount)
{
x.push_back(Amount); // grows by 1 element
}
std::vector also has a size() member function to tell you the current number of elements. No more sizeof needed.

vector size remaining static after pushback() calls for powerset function

I wrote the following function, as an implementation of this algorithm/approach, to generate the power-set (set of all subsets) of a given string:
vector<string> getAllSubsets(string a, vector<string> allSubsets)
{
if(a.length() == 1)
{
// Base case,
allSubsets.push_back("");
allSubsets.push_back(a);
}
else {
vector<string> temp = getAllSubsets(a.substr(0,a.length()-1),allSubsets);
vector<string> with_n = temp;
vector<string> without_n = temp;
for(int i = 0;i < temp.size()-1;i++)
{
allSubsets.push_back(with_n[i] + a[a.length()-1]);
allSubsets.push_back(without_n[i]);
}
}
return allSubsets;
}
however, someone appears to be going wrong: the size of temp and allSubsets remains static from recursive call to recursive call, when they should be increasing due to the push_back() calls. is there any reason why this would take place?
It's because you have an off-by-one error. Because this occurs in your next-to-base case, you are never inserting any entries.
Since the first invalid index is temp.size(), i < temp.size() means that you will always have a valid index. Subtracting 1 means that you are missing the last element of the vector.
It's worth noting that passing allSubsets in as a parameter is kinda silly because it's always empty. This kind of algorithm simply doesn't require a second parameter. And secondly, you could be more efficient using hash sets that can perform deduplication for you simply and quickly.

Printing the First Array in a Deque of Structs

I have a Deque that contains this kind of stucts.
struct New_Array {
array<array<int,4>,4> mytable;
int h;
};
In this stuct 2 different arrays may have same value of h.
deque<New_Array> Mydeque;
I also know how many different h are in the deque(the value of steps). And how many stucts are in the deque(Mydeque.size()).
I need to print one array for each h. Starting from h=0 till h=steps (steps is a known int value). Each array that is going to be printed must be the closer to the end of the deque.
I tried something like this:
void foo(deque<New_Array> Mydeque, int steps)
for(int i=0; i<steps; i++)
{
deque<New_Array>::iterator it;
it = find(Mydeque.begin(),Mydeque.end(),i);
PrintBoard(*it); // This if a function where you enter the New_Array struct
// and it prints the array
}
}
The above gives me : error C2679: binary '==' : no operator found which takes a right-hand operand of type 'const bool' (or there is no acceptable conversion)
Or something like this:
void foo(deque<New_Array> Mydeque, int steps)
for(int i=0; i<steps; i++)
{
deque<New_Array>::iterator it;
for(unsigned int j=0;j<Mydeque.size();j++)
{
it = find_if(Mydeque.begin(),Mydeque.end(),Mydeque[j].h==i);
PrintBoard(*it);
break;
}
}
The above gives me: error C2064: term does not evaluate to a function taking 1 arguments
EDIT: The deque is not sorted. For each h an array should be printed. This array should be the one that is at this moment closer to the end of the deque.
Remember the last value and skip:
assert(!Mydeque.empty());
int old_h = Mydeque[0].h + 1; // make sure it's different!
for (std::size_t i = 0, end != Mydeque.size(); i != end; ++i)
{
if (Mydeque[i].h == old_h) continue;
print(Mydeque[i]);
old_h = Mydeque[i].h;
}
Firstly, note that you declare your std::array on the stack, so the storage will also be on the stack. This means that iterating over the structure involves loading a (4*4+1)*int for each comparison. If this is performance-sensitive, I would suggest using std::vector since the load will be only of the outer vector pointer and the h when only comparing h.
struct New_Array {
vector<vector<int,4>,4> mytable;
int h;
};
Secondly, if you need to access these tables through their h values, or access all the tables with a given h at once, make it easier for everyone and store them as vectors in a map, or a sorted vector of vectors:
std::map<int,std::vector<New_Array> > rolodex;
rolodex[someNewArray.h].push_back(someNewArray);
If you construct this in-order, then the first item in each vector will be the one to print:
for(auto it : rolodex) {
vector<New_Array> tablesForThisH = it->second;
if(tablesForThisH.begin() != tablesForThisH.end())
PrintBoard(it->second[0]);
}
Since std:map stores (and iterates) its keys in ascending (I think) order, this will run over the different h values in ascending order. Again it will only need to load the stack-stored struct, which is just the h int and the vector header (probably 12 bytes, as mentioned in this question).
Forgive me if the code is wrong, my stl is a little rusty.
Loop through the deque, and insert all elements into a map, using h as the key. Since your set of h values seems to be sequential, you can use a vector instead, but testing whether an element has already been found will be more difficult.
The solution is :
void Find_Solution_Path(deque<New_Array> Mydeque, int steps)
{
for(int i=0; i<steps+1; i++)
{
for(int j=Mydeque.size()-1;j>-1;j--)
{
if (Mydeque[j].h==i)
{
PrintBoard(Mydeque[j]);
cout<<endl;
break;
}
}
}
}