arrays and functions - c++

my assignment requires me to write a function that reads in a title and return the corresponding fee to the calling function. if the title is not in the list, return -1.0.
this is what i have got at the moment:
struct eventType
{
string title;
double fees;
};
eventType eventTable[10];
int findFees (string newTitle, string newFees)
{
int Index = 0;
int flag;
while (Index < 9) && (eventTable[Index].title != newTitle))
Index = Index + 1;
if (eventTable[Index].title == newTitle)
{
eventTable[Index].fees = newFees;
flag = 0;
}
else
flag = -1;
return flag;
}
is anything missing?
update
after looking at the advice u guys have given, i have adopted and changed the codes to:
double findFees (string title)
{
for (int Index = 0 ; Index < 10 ; Index++)
{
if (eventTable[Index].title == title)
{
return eventTable[Index].fees;
}
}
return -1.0;
}
I'm not sure if this is correct either but I do not need a new title or new fees since these values are to be found within eventTable, and return it.
corrections?

I don't want to give away the answer for you, but here are two things you should keep in mind:
When you have a conditional or a loop, you need to surround statements in { and } so that the compiler knows which statements go inside the loop.
Second, C++ is a type-safe language, meaning that if you are assigning variables to a value of a different type, your program won't compile, look through your code and see if you can find anything wrong on that front

It should be:
while (Index < 10)
And you said it should return the fee, but it returns 0 when found. (This is ok, since you are passing in the fee, why return it too?)
I would also change the signature of the function to be:
int findFees (const string &newTitle, const string &newFees)
and while you are at it, have it return a "bool" instead of a flag to denote success since:
if(findFees(blahTitle, blahFees))
sounds a lot better than:
if(findFees(blahTitle, blahFees) == 0)
when checking for whether the title is found.

It seems to me your function does not return the fees, as you described.
It looks like it updates the eventTable, changing the fee stored there, and returns a flag if the update was done successfully.
Please clarify. Do you want to find the fee stored in the eventTable and return it? Or do you want to update the eventTable with new data? Or a hybrid of both.
Still, for a noob, your code is well structured and reasonably well written.

You could simplfy it as so.
int flag = -1;
int Index = 0;
while(Index <= 9)
{
if(eventTable[Index].title == newTitle)
{
eventTable[Index].fees = newFees;
flag = 0
break;
}
}
return flag;

eventTable[Index].fees = newFees;
This won't work because fees is a double and newFees is a string. Also you didn't say anything about changing the fees, so I'm confused by that line.
If you want to return the fees of the item you found, you should just put return eventTable[Index].fees; at that point and change the return value of the function to float.

Your description (return the fee, or -1.0 if not found) does not match your code:
struct eventType
{
string title;
double fees;
};
eventType eventTable[10];
double findFees (string newTitle)
{
for (int Index = 0 ; Index < 10 ; Index++)
{
if (eventTable[Index].title == newTitle)
{
return eventTable[Index].fees;
}
}
return -1.0;
}

The only error I see is
while (Index < 9) && (eventTable[Index].title != newTitle))
should probably be:
while ((Index < 10) && (eventTable[Index].title != newTitle))
Note the missing '('. Otherwise you miss matching the last entry in the array.
I would probably write the function something like:
double findFees (const string& title, double newFee)
{
for (int i = 0; i < 10; i++)
{
if (eventTable[i].title == title)
{
eventTable[i].fees = newFee;
return newFee;
}
}
return -1.0;
}
This way you will not iterate through the entire array if you already found the item you where searching for.

Related

Error: Char 34: runtime error: addition of unsigned offset to 0x603000000070 overflowed to 0x60300000006c (stl_vector.h) (C++)

I have been trying to solve the sorted Squares leetcode problem (https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3240/), and I am mostly through it. However, I get the above error. Following is my code
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int start = 0;
int end = nums.size()-1;
vector<int> final(nums.size());
int finalIdx = final.size()-1;
int sqr = 0;
while(start<=end){
if (abs(nums[start])<abs(nums[end])){
sqr = nums[end]*nums[end];
final[finalIdx] = sqr;
finalIdx--;
end--;
}
if (abs(nums[start])>abs(nums[end])){
sqr = nums[start]*nums[start];
final[finalIdx] = sqr;
finalIdx--;
start++;
}
else if(abs(nums[start])==abs(nums[end])){
sqr = nums[end]*nums[end];
final[finalIdx] = sqr;
finalIdx--;
final[finalIdx] = sqr;
finalIdx--;
start++;
end--;
}
return final;
}
}
};
The issue lies in my loop condition I believe. When I change the condition to start<end, I have no compile error, but the first element of the output array (final) is always 0, which I assume is by default. However, when I try to do start<=end in order to add a condition that handles the start==end case, I get the above error. I would like to understand why this is happening so I can rectify the issue. Thanks!
First, that's not a "compile error" ; it's a runtime error (and the error message reported says as much.
That said, the issue stems from the condition of start <= end landing on the = part of that condition. Eventually that is guaranteed to happen, save for one very specific set of circumstances:
start = (end-1)
abs(num[start]) == abs(num[end])
When that happens, your code will dump two values to the output vector, and both increment start and decrement end. The start and end indexes effectively swap values, the while condition is no longer true, and the loop will now cleanly exit.
In all other circumstances start and end will eventually land on the same index. When that happens your dual-push logic will dump the same value twice into the target vector, and that is where the issue manifests. There is only one value left to push (and start and end both reference it by index). Therefore you're going to push one more value into your target vector than you have space for, and the runtime exception ensues.
The fix is simple. Stop trying to be smart about short circuiting in three different conditions when in reality you only need one and a master-else. The computational requirements are the same no matter what, and in the end all you need is this:
class Solution
{
public:
std::vector<int> sortedSquares(std::vector<int> const &nums)
{
std::vector<int> final(nums.size());
int start = 0;
int end = nums.size()-1;
int finalIdx = final.size()-1;
while(start<=end)
{
if (abs(nums[end]) < abs(nums[start]))
{
final[finalIdx--] = nums[start]*nums[start];
++start;
}
else
{
final[finalIdx--] = nums[end]*nums[end];
--end;
}
}
return final;
}
};
If you really want all three conditions in your code, it is possible, but not warranted, and the special case circumstances don't justify doing it. Regardless, see below:
class Solution
{
public:
std::vector<int> sortedSquares(std::vector<int> const &nums)
{
std::vector<int> final(nums.size());
int start = 0;
int end = nums.size() - 1;
int finalIdx = final.size() - 1;
while (start <= end)
{
if (abs(nums[start]) < abs(nums[end]))
{
final[finalIdx--] = nums[end] * nums[end];
end--;
}
else if (abs(nums[end]) < abs(nums[start]))
{
final[finalIdx--] = nums[start] * nums[start];
start++;
}
else // !(a<b || b<0) implies (a == b)
{
int sqr = final[finalIdx--] = nums[end] * nums[end];
if (end != start)
{
final[finalIdx--] = sqr;
}
--end;
++start;
}
}
return final;
}
};

C++ There is a bool return type function returning (24) here

First of all sorry for too much code
Here there is a vector (teamNum) with type class, the class contain a vector (player) with type struct, it is a little complicated, but here in this function I need to check if there is a player in teamNum which contain tName equal to _tname (function parameter) contain (the player) pID equal to _pID (function parameter)
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
if (teamNum[i].tName == _tname)
{
for (int j = 0; j < teamNum[i].player.size(); j++)
{
if (teamNum[i].player[j].pID == _pID)
return true;
}
}
else if (i == (teamNum.size() - 1))
{
return false;
}
}
}
And in the main
int main()
{
cout << "\n" << thereIsSimilarID("Leverpool", 1) << endl;
}
The output is 24 !!!!!
(good note that this happen just when the team (Leverpool) is the last team in the vector teamNum)
Again sorry for too much code but I need to know the bug not only fix the problem I need to learn from you
You encountered undefined behaviour.
If you take the if (teamNum[i].tName == _tname)-branch on the last element, but find no player with the correct pID, you don't return anything. Which means, that the return value is whatever random value is currently in the memory location that should hold the return value. In your case it happens to 24. But theoretically, everything could happen.
The same problem occurs when teamNum is empty.
The solution is to make sure to always return a value from a function (except if it has return type void of course):
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
// In this loop return true if you find a matching element
}
// If no matching element was found we reach this point and make sure to return a value
return false;
}
You should take a look at your compiler settings and enable all the warnings. And often it's good to let it treat certain warnings as errors.

Error: not all control paths return a value

I am writing two functions in a program to check if a string has an assigned numeric code to its structure array or if the given numeric code has an assigned string in the same structure array. Basically, if I only know one of the two, I can get the other. I wrote the following:
int PrimaryIndex::check_title_pos(std::string title) {
bool findPos = true;
if (findPos) {
for (int s = 1; s <= 25; s++) {
if (my_list[s].title == title) {
return s;
}
}
} else {
return -1;
}
}
std::string PrimaryIndex::check_title_at_pos(int pos) {
bool findTitle = true;
if (findTitle) {
for (int p = 1; p <= 25; p++) {
if (my_list[p].tag == pos) {
return my_list[p].title;
}
}
} else {
return "No title retrievable from " + pos;
}
}
However, it says not all control paths have a return value. I thought the else {} statement would handle that but it's not. Likewise, I added default "return -1;" and "return "";" to the appropriate functions handling int and string, respectively. That just caused it to error out.
Any idea on how I can keep this code, as I'd like to think it works but cant test it, while giving my compiler happiness? I realize through other searches that it sees conditions that could otherwise end in no returning values but theoretically, if I am right, it should work fine. :|
Thanks
In the below snippet, if s iterates to 26 without the inner if ever evaluating to true then a return statement is never reached.
if (findPos) {
for (int s = 1; s <= 25; s++) {
if (my_list[s].title == title) {
return s;
}
}
}

if() skipping my variable check

I have following code:
std::vector<std::string> GetSameID(std::vector<string>& allFiles, int id) {
std::vector<std::string> returnVector;
for(std::vector<string>::iterator it = allFiles.begin(); it != allFiles.end(); ++it) {
if(GetID(*it) == id) {
int index = (*it).find("_CH2.raw");
if(index > 0) {
continue; //this works
}
if(0 < ((*it).find("_CH2.raw"))) {
continue; //this doesn't
}
string ext = PathFindExtension((*it).c_str());
if(ext == ".raw") {
returnVector.push_back(*it);
}
}
}
return returnVector;
}
My issue is, why is the if(0 < ((*it).find("_CH2.raw"))) not working that way? My files are named
ID_0_X_0_Y_128_CH1.raw
ID_0_X_0_Y_128_CH2.raw
(different ID, X and Y, for Channel 1 and Channel 2 on the oscilloscope).
When I do it the long way around (assign index, and then check index), it works, I don't understand though why the short version, which is more readable imo, is not working.
According to http://en.cppreference.com/w/cpp/string/basic_string/find, string::find() returns a size_t -- which is an unsigned type -- so it can never be less-than zero.
When it doesn't find something, it returns string::npos, which is also an unsigned type, but when you shove it into an int (implicitly converting it) it becomes a negative value -- this is why your first set of code works.

Searching first specified element in array

I'm trying to make function that has a loop that checks every member of an array made from boolean variables and exits when it finds the first "true" value.
That's what I have now:
bool solids[50];
int a,i;
//"equality" is a function that checks the equality between "a" and a defined value
solids[0] = equality(a,&value_1);
solids[1] = equality(a,&value_1);
solids[2] = equality(a,&value_1);
solids[3] = equality(a,&value_1);
for (i = 0; solids[i] != true; i++)
{
[...]
}
But I have no idea, what should I put into the loop?
My attempt was
for (i = 0; i <= 50; i++)
{
if (solids[i] == true)
{
return true;
break;
} else {
return false;
}
}
,that should return true after the first found true and return false if the array has no member with true value, but it doesn't seem to work in the code.
Is it wrong? If yes, what is the problem?
PS.: I may count the number of trues with a counter but that's not an optimal solve to the problem, since I just look for the FIRST true value and consequently, the program doesn't have to check all the 50 members. Needley to count, how many unnecesary steps should this solve would mean.
here's a short example usage of std::find() as advised by #chris:
bool find_element_in_array() {
bool solids[50];
int length;
/* ... do many operations, and keep length as the size of values inserted in solids */
bool* location = std::find(solids, length, true);
// if element is found return true
if (location != solids + length)
return true;
// else return false
return false;
}
Once you have solids correctly set (it looks like you're currently setting every value to the same thing), you can make a loop that exits on the first true like this:
for (i = 0; i < 50; i++)
{
if (solids[i] == true)
{
return true;
}
}
return false;
I'd also just move the declaration of i into the for loop body, since it's not used outside, but the above answers your question.
return immediately exits the function, so there is no need to break the loop after.
If it's sufficient to exit the function right after the search, you should write something like:
for (int i = 0; i < 50; i++) {
if (solids[i]) return true;
}
return false;
If you need to use the result of the search in the same function, use additional variable:
bool found = false;
for (int = 0; i < 50; i++) {
if (solids[i]) {
bool = true;
break;
}
}
if (found) { ...