I am looking for a good way to round an int in Qt to the nearest 5.
e.g:
8 -> 10
12 -> 10
13 -> 15
15 -> 15
17 -> 15
and so on
Rounding in C++ to the nearest integer number usually is done via:
static_cast<int>(number + 0.5);
Now, to round it to the next 5, I would bring it into the system where we can apply this rounding rule (i.e. 5 -> 1, 6 -> 1.2) and then bring it back into the system where 5 really is 5:
int roundToNearestFive(int number)
{
return static_cast<int>(number / 5. + .5) * 5;
}
I find this formulation easiest.
Here a possible solution:
#include<iostream>
int toNearest5(int i) {
int r = i%5, o = 0;
if(r) {
o = r/5. >= .5 ? 5 : 0;
}
return (i-r+o);
}
int main() {
using namespace std;
cout << toNearest5(8) << endl;
cout << toNearest5(12) << endl;
cout << toNearest5(13) << endl;
cout << toNearest5(15) << endl;
cout << toNearest5(17) << endl;
}
The idea is to get the number and round it to the lowest multiple of 5 (you can do that by removing the remainder), that is:
int remainder = i%5;
int rounded = i - remainder;
Now, you can check the remainder and add 5 to the rounded number if the remainder is greater than 2.5, otherwise add 0.
In order to check it, I've divided the remainder by 5 (its upper bound), so that to get a number in [0,1[ and check it with 0.5 to know how to round the original number.
It follows a more compact version of the same function:
int toNearest5(int i) {
int j = i%5;
return (i - j + (j/5. >= .5 ? 5 : 0));
}
I don't know if the Qt framework offers something similar out of the box, but it's a matter of an one line function, you can easily write it for yourself.
Related
My pointer array doesn't store my data correctly. I created a file that stored 10 integers, and it only stored the 10th and prints it out 10 times.
Any help would be appreciated, and I apologize if formatting is incorrect as this is my first time using this site.
void displayPointer(vector<int*>& ptrvect) {
for (int i = 0; i <= ptrvect.size() - 1; i++) {
cout << setw(6) << *ptrvect[i];
}
}
void displayArray(vector<int>& vect) {
for (int i = 0; i <= vect.size() - 1; i++) {
cout << setw(6) << vect[i];
}
}
int main(){
ifstream myfile("arrayData.txt");
int values;
vector<int> vect;
vector<int*> ptrvect;
while (myfile >> values) {
ptrvect.push_back(&values);
vect.push_back(values);
}
displayArray(vect);
cout << endl;
displayPointer(ptrvect);
}
The purpose of my code is to sort a pointer vector and leave my original vector untouched, but I realized my pointer vector only has one unique integer from my list before the sorting even occurs.
Ex: arrayData.txt values are 1 3 9 4 8 2 10 48 3 21 and only 21 is printed 10 times when my displayPointer function is called.
How do i add minimum and maximum values for an integer? I want an integer to never go down below zero like negative and never goes above 100
Here is the example:
int hp = 100;
std::cout << "You cast healing magic to yourself!" << std::endl;
hp += 20;
mp -= 25;
For example the health is 100 but when a healing magic is cast it became 120. The thing i want is i want it to stay as 100 no matter how many healing magic are cast upon.
You can use std::clamp:
hp = std::clamp(hp + 20, 0, 100);
mp = std::clamp(mp - 25, 0, 100);
You can use std::clamp as suggested by #TedLyngmo if you are using a compiler which supports C++ 17. If not, then you can write a simple function to manage the limits for hp and mp:
void change(int& orig, int val)
{
int temp = orig + val;
if (temp <= 0)
temp = 0;
else if (temp >= 100)
temp = 100;
orig = temp;
}
int main()
{
int hp = 40, mp = 40;
std::cout << "You cast healing magic to yourself!" << std::endl;
change(hp, 50);
change(mp, -25);
std::cout << hp << " " << mp << std::endl;
}
I believe what you are saying is whatever the healing magic is you want to display 100 or your hp the way it is. If so you can store the 20 and 25 as variables and create another var with the same value as ur original one and play around with that. Don't change the value of ur original one and so you get to display that.
//this approach is based on finding all the subsets of a set having n elements by finding subsets of n-1 elements. and so on through recursion..
int sum_subset(int set[], vector<int>& subset, int sum, int n, int l=0)
{
//for edge case of sum=0
if (sum = 0) return 1;
int s = 0;
//base condition of recursion
if (l == n) {
for (int x:subset) {
s += x;
}
return (s==sum)? 1: 0;
}
//calling the recursion for ->not including the nth element of the set of n elements in the subset of n-1 elements
int a = sum_subset(set, subset, sum, n, l+1);
//including nth element in the subset
subset.push_back(set[l]);
//calling the recursion for -> including the nth element of the set of n elements in the subset of n-1 elements
int b = sum_subset(set, subset, sum, n, l+1);
return a + b;
}
int main() {
int n;
cout << "enter the size of set" << endl;
cin >> n;
int set[n];
cout << "enter the set elements" << endl;
for(int i = 0; i < n; i++) {
cin >> set[i];
}
cout << "enter the sum " << endl;
int sum;
cin >> sum;
vector<int> subset{0};
int ans = sum_subset(set, subset, sum, n);
cout << "subsets having sum =" << sum << "are->" << ans << endl;
}
//output
enter the size of set
5
enter the set elements
1
2
2
1
3
enter the sum
3
subsets having sum =3are->1
You are assigning your sum variable the value 0 instead of comparing the values:
//for edge case of sum=0
if (sum = 0) return 1;
int s = 0;
This itself hides another problem: you never remove the values from the subset vector. For example, the first time you push the value into your subset, you leave your subset equal to {3}. Then you just add more and more values, and this "subset" will never give you the sum equal 3.
One more problem that doesn't affect your program, but is important. In the line below you don't create an empty vector, but you create a vector with one zero element in it, the the vector is equal to {0}:
vector<int> subset{0};
I found a strange behavior of C ternary operator (?:).
In the following code, the expected values of both b and c should be 0, but b is -2.
I checked the C operator precedence, and made sure minus(-) is higher than greater than or equal to (>=), which is higher than the conditional operator (?:). Could anyone kindly explain why the values of b and c are different?
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
int main() {
int i;
vector<int> a;
for (i = 0; i < 29; ++i)
a.push_back(i);
int b = 27 - a.size() >= 0 ? 27 - a.size() : 0;
int c = 27 - 29 >=0 ? 27 - 29 : 0;
cout << b << endl;
cout << c << endl;
return 0;
}
After looking on the document page of vector, the return type of method size() is size_t which is equal to an unsigned long long.
So, when you do 27 - a.size() this will cause overflow, making the result of the 27 - a.size() >= 0 operator be True. It got nothing to do with C operator precedence.
To prove that, you can do:
#include <iostream>
using std::cout;
using std::endl;
int main() {
unsigned long long tmp = 29;
cout << 27 - tmp << endl; //(this will be a super large integer.)
return 0;
}
Solution:
The solution is simple, you can simply add a typecasting (int) before a.size() in the condition of the ternary operator.
It can be looks like this:
int b = 27 - (int) a.size() >= 0 ? 27 - a.size() : 0;
For class, Im making a program that manages a hotel. Im getting a run-time error when my program gets to this function:Vector iterator not dereferencable. I used the debugger to find the problem area, but I cant figure out what is wrong with it. Any Suggestions?
Customer & ListOfCustomers::getByID(int id)
{
if(!sortedByID)sortByID();
vector<Customer>::iterator iter;
Customer cus;
cus.customerID=id;
iter = lower_bound(customers.begin(),customers.end(),cus,compareCustomersByID);
if( (*iter).customerID == id ) // <---DEBUGGER SAYS ERROR HERE IN THIS LINE
{
return *iter;
}
else
{
return NullCustomer();
}
}
Here is the lower_bound function. It is Inside #include algorithm
template<class _FwdIt,
class _Ty,
class _Pr> inline
_FwdIt lower_bound(_FwdIt _First, _FwdIt _Last,
const _Ty& _Val, _Pr _Pred)
{// find first element not before _Val, using _Pred
// _DEBUG_ORDER_PRED(_First, _Last, _Pred);
return (_Rechecked(_First,
_Lower_bound(_Unchecked(_First), _Unchecked(_Last), _Val, _Pred,
_Dist_type(_First))));
}
EDIT: added a space so that the lower_bound function would be formatted correctly as code.
You are using the lower_bound function for searching. Its purpose is a little different than that. This is what lower_bound does:
Returns an iterator pointing to the first element in the sorted range [first,last) which does not compare less than value.
And another definition from here:
Specifically, it returns the first position where value could be inserted without violating the ordering.
So for example, if the thing you are looking for is not in the vector, it will return an iterator that points after the last item in the vector, and that iterator can't be dereferenced because it does not exist.
Take a look at this example:
int myints[] = {10,20,30,30,20,10,10,20};
vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20
vector<int>::iterator low;
sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30
low=lower_bound (v.begin(), v.end(), 60); // ^it will point here
cout << "lower_bound at position " << int(low- v.begin()) << endl;
As you can see from the output, the iterator will point to the 9th element in the vector (index 8). But the vector only has 8 elements (indexed 0-7). The explanation for this is that you can insert the new item in the vector at index 8 without violating the ordering.
I think that what you really want is the find function. Here is an example:
int myints[] = {10,20,30,30,20,10,10,20};
vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20
vector<int>::iterator find_it1 = find(v.begin(), v.end(), 30);
vector<int>::iterator find_it2 = find(v.begin(), v.end(), 80);
if(find_it1 == v.end())
cout << "30 not found" << endl;
else
cout << "30 found at position " << int(find_it1 - v.begin()) << endl;
if(find_it2 == v.end())
cout << "80 not found" << endl;
else
cout << "80 found at position " << int(find_it2 - v.begin()) << endl;
Here is the output:
30 found at position 2
80 not found