My code doesn't seem to work and I cannot understand why.
When the user enters a number to search for its location it doesn't show anything. If anyone could explain it to me I would greatly appreciate it.
void Array::binarySearch(vector<int> vect)
{
int search_val;
int high = (int)vect.size();
int low = 0;
int mid = 0;
bool found = false;
cout << "Enter Number to search : ";
cin>>search_val;
while (low <= high && !found) {
mid = (high + low)/2;
if (search_val > vect[mid]) {
low = mid + 1;
} else if (search_val < vect[mid]) {
high = mid - 1;
} else {
cout << "Number you entered " << search_val << " was found in position " << mid << endl;
found = true;
}
}
if (!found) {
cout << " The value isn't found " << endl;
}
}
sorted algo:
void Array::arrSort(vector<int> vect)
{
for (unsigned int i = 0; i < vect.size()-1; i++)
{
for (unsigned int j = 0; j < vect.size()-i-1; j++)
{
if (vect[j] > vect[j+1])
{
int x = vect[j+1];
vect[j+1] = vect[j];
vect[j] = x;
}
}
}
cout<<"Sorted output is "<<endl;
printArr(vect);
}
Your arrSort function takes its parameter by value, so it receives (and sorts) a copy of the original array.
To sort the array you're passing in, take the parameter by reference:
void Array::arrSort(vector<int> &vect)
As someone has pointed out, you must ensure that you are performing binary search on a sorted array. Perhaps, you should build and test each algorithm separately to ensure correctness before combining them together.
Check out std::sort to get your binary search function working, then work on your sort function––or vice versa.
Also, if you have found the item you are looking for say, vect[mid] == search_val you can go ahead and return true (or print like you've done) and terminate the algorithm.
Related
if ( n % 2 == 0)
cout << n << " is even.";
else
cout << n << " is odd.";
I know how to check if the numbers are odd, but unsure of how to write the rest of the code.
bool isOdd(int int_arr[], int arr_size)
{
bool is_all_odd = true;
for(int i = 0; i < arr_size; i++)
{
if(int_arr[i] % 2 == 0)
{
is_all_odd = false;
break;
}
}
return is_all_odd;
}
You'll want to take in the array like you mentioned, the size, and traverse through it. In this case we just assume all is odd, and check for an even, if we find an even number we change the return value, stop traversing and return.
First of all, sorry for the mis-worded title. I couldn't imagine a better way to put it.
The problem I'm facing is as follows: In a part of my program, the program counts occurences of different a-zA-Z letters and then tells how many of each letters can be found in an array. The problem, however, is this:
If I have an array that consists of A;A;F;A;D or anything similar, the output will be this:
A - 3
A - 3
F - 1
A - 3
D - 1
But I am required to make it like this:
A - 3
F - 1
D - 1
I could solve the problem easily, however I can't use an additional array to check what values have been already echoed. I know why it happens, but I don't know a way to solve it without using an additional array.
This is the code snippet (the array simply consists of characters, not worthy of adding it to the snippet):
n is the size of array the user is asked to choose at the start of the program (not included in the snippet).
initburts is the current array member ID that is being compared against all other values.
burts is the counter that is being reset after the loop is done checking a letter and moves onto the next one.
do {
for (i = 0; i < n; i++) {
if (array[initburts] == array[i]) {
burts++;
}
}
cout << "\n\n" << array[initburts] << " - " << burts;
initburts++;
burts = 0;
if (initburts == n) {
isDone = true;
}
}
while (isDone == false);
Do your counting first, then loop over your counts printing the results.
std::map<decltype(array[0]), std::size_t> counts;
std::for_each(std::begin(array), std::end(array), [&counts](auto& item){ ++counts[item]; });
std::for_each(std::begin(counts), std::end(counts), [](auto& pair) { std::cout << "\n\n" << pair.first << " - " pair.second; });
for (i = 0; i < n; i++)
{
// first check if we printed this character already;
// this is the case if the same character occurred
// before the current one:
bool isNew = true;
for (j = 0; j < i; j++)
{
// you find out yourself, do you?
// do not forget to break the loop
// in case of having detected an equal value!
}
if(isNew)
{
// well, now we can count...
unsigned int count = 1;
for(int j = i + 1; j < n; ++j)
count += array[j] == array[i];
// appropriate output...
}
}
That would do the trick and retains the array as is, however is an O(n²) algorithm. More efficient (O(n*log(n))) is sorting the array in advance, then you can just iterate over the array once. Of course, original array sequence gets lost then:
std::sort(array, array + arrayLength);
auto start = array;
for(auto current = array + 1; current != array + arrayLength; ++current)
{
if(*current != *start)
{
auto char = *start;
auto count = current - start;
// output char and count appropriately
}
}
// now we yet lack the final character:
auto char = *start;
auto count = array + arrayLength - start;
// output char and count appropriately
Pointer arithmetic... Quite likely that your teacher gets suspicious if you just copy this code, but it should give you the necessary hints to make up your own variant (use indices instead of pointers...).
I would do it this way.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s;
vector<int> capCount(26, 0), smallCount(26, 0);
cout << "Enter the string\n";
cin >> s;
for(int i = 0; i < s.length(); ++i)
{
char c = s.at(i);
if(c >= 'A' && c <= 'Z')
++capCount[(int)c - 65];
if(c >= 'a' && c <= 'z')
++smallCount[(int)c - 97];
}
for(int i = 0; i < 26; ++i)
{
if(capCount[i] > 0)
cout << (char) (i + 65) << ": " << capCount[i] << endl;
if(smallCount[i] > 0)
cout << (char) (i + 97) << ": " << smallCount[i] << endl;
}
}
Note: I have differentiated lower and upper case characters.
Here's is the sample output:
output
How can I edit this function to find multiple modes? Right now if there are multiple, it will display the smallest.
Example
Input 5 5 2 2
Output 5 2
What it actually does
Input 5 5 1 1
Output 1
void calculateMode(int array[], int big)
{
int counter = 1;
int max = 0;
int mode = array[0];
for (int pass = 0; pass < big - 1; pass++)
{
if ( array[pass] == array[pass+1] )
{
counter++;
if ( counter > max )
{
max = counter;
mode = array[pass];
}
} else
counter = 1; // reset counter.
}
cout << "The mode is: " << mode << endl;
}
Anything helps!
I like also the stdlib option as one of the comments refers. However, I tried to solve this problem without using it as you (as an exercise). I had as a requirement to have a constant array as a function parameter, so I could not order it (nor remove the constant nor copy it in a new non-const one). In addition, if there are multiple modes or no elements, I had to return zero.
At the end a came up with something like the following. Hopefully, it might help.
#include <iostream>
#include <stdexcept>
template <typename T> T mode(const T *values, size_t length) {
// check if it has zero length
if (!length)
return 0;
if (!values)
throw std::invalid_argument{"Invalid input array"};
int count{}, maxOccurrences{};
int multipleModes{};
T mode{};
// check every element unless the mode's occurrences are greater than the
// remaining list
for (int k{}; k < length && maxOccurrences <= (length - k); ++k) {
// reset the count for every individual element
count = 0;
// count the number of occurrences
for (int i{}; i < length; ++i) {
if (values[k] == values[i])
count++;
}
if (count > maxOccurrences && mode != values[k]) {
mode = values[k];
maxOccurrences = count;
multipleModes = 0;
/*std::cout << "Count:" << count << " - MaxOccur:" << maxOccurrences
<< " - Mode:" << mode << std::endl;*/
}
if (count == maxOccurrences && mode != values[k]) {
// if the array has multiple modes
multipleModes = 1;
}
}
if (multipleModes == 1)
return 0;
else
return mode;
}
Thanks for you attention!
you can try adding this
else if (counter==max){
mode += array[pass]
}
can't test it on my own system. see if it's of any help.
So what it's supposed to do is be able to take in a const char* str change it to an int then have it be converted back into a string for the output. But it is also supposed to be able to add and subtract these together. I'm passing my first two tests but something is going on with my addition, its giving me a negative number close to the answer but not the right one. Shortened it up a bit.
//For testing
int main()
{
BigInt result;
BigInt num1("999");
BigInt num2("4873");
BigInt num3("-739");
checkTest("Test 1", "999", num1.convertToString());
checkTest("Test 2", "-739", num3.convertToString());
result = num3.add(num4);
checkTest("Test 3", "-10610", result.convertToString());
return 0;
}
Here is where I'm having trouble
#include <iostream>
using namespace std;
class BigInt
{
public:
//An empty constructor, the {} is an empty body
BigInt() {}
BigInt(const char*);
BigInt add(const BigInt&);
BigInt operator+(const BigInt&);
BigInt subtract(const BigInt&);
BigInt operator-(const BigInt&);
string convertToString();
private:
static const int NUM_DIGITS = 100;
int numArr[NUM_DIGITS + 1];
void tensComplement();
};
BigInt::BigInt(const char* str) {
// TODO: CONVERT C-STRING TO BIGINT
int len = strlen(str) - 1;
int zero = NUM_DIGITS - 1;
for (int i = 0; i < NUM_DIGITS; i++){
numArr[i] = 48;
}
for (int i = len; i >= 0; i--){
numArr[zero] = str[i];
zero--;
}
}
BigInt BigInt::add(const BigInt& rightOperand) {
BigInt objToReturn("0");
// TODO: ADD LOGIC HERE
int carry = 0;
for (int i = 100; i > 0; i--){
int left = this->numArr[i] - 48;
int right = rightOperand.numArr[i] - 48;
int total = left + right;
total += carry;
if (total > 9){
carry = 1;
}else{
carry = 0;
}
total = total % 10;
objToReturn.numArr[i] = total + 48;
}
//num1 is the this object
cout << this->numArr[NUM_DIGITS];
//num2 is the rightOperand object
cout << rightOperand.numArr[NUM_DIGITS];
return objToReturn;
}
BigInt BigInt::operator+(const BigInt& rightOperand){
return add(rightOperand);
}
string BigInt::convertToString(){
// TODO: VALUE IN numArr CONVERTED TO STRING
int count = 0;
string str;
if(numArr[0] == 57){
tensComplement();
}
for (int i = 0; i < NUM_DIGITS; i++){
if(numArr[i] == 48 && count == 0){
}else{
str.push_back(numArr[i]);
count++;
}
}
return str;
}
void BigInt::tensComplement(){
// TODO: TENS COMPLEMENT OF THIS NUMBER
for (int i = 0; i <= 100; i++) {
numArr[i] = 9 - numArr[i];
}
numArr[NUM_DIGITS] += 1;
for(int i = NUM_DIGITS; i >= 1; i--){
if(numArr[i] == 10){
numArr[i] = 0;
numArr[i - 1] += 1;
}
}
if(numArr[0] == 1){
numArr[0] = 9;
}
}
//This helps with testing.
bool checkTest(string testName, string whatItShouldBe, string whatItIs) {
if (whatItShouldBe == whatItIs) {
cout << "Passed " << testName << " last digit was: " << whatItIs.at(whatItIs.length()-1) << endl;
return true;
}
else {
if (whatItShouldBe == "") {
cout << "**Failed test " << testName << " ** " << endl << " Output was "<< whatItIs << endl << " Output should have been blank. " << endl;
} else {
cout << "**Failed test " << testName << " ** " << endl << " Output was "<< whatItIs << endl << " Output should have been " << whatItShouldBe << endl;
}
return false;
}
}
This looks like "home-work" but any way.
You would probably benefit from detecting negative values in the constructor and storing that information in a flag. This makes it easier to decide how to use the number in calculations.
As Roddy said you would probably benefit from keeping the digits as numbers instead of characters, reasonably you would be implementing more calculations than displays in BigInt and you will not need to convert things for each calculation, just imagine what it would be like to handle multiplication and division like you do add.
You might benefit from implementing the subtract method before trying to make "add" do subtraction.
I would guess you have two main problems with subtraction,
the four permutations of signs and "borrowing" instead of carry.
Have you planed for any compare method?
main() for testing would give you more value if you kept all your tests in it.
The main in your question have only one assert.
If you keep the asserts for the already implemented functionality you ensure that it keeps working while you add new behavior.
Try to figure out your edge cases and keep a test for each.
Also try to remember that you do not need to implement the whole functionality at once, verifying a small piece that you can see how to do might help you to reason about the rest of the problem.
Your "checkTest" function returns a boolean, use it to count the number of failed tests and return that to give you the ability to fail the build when any test fails.
You need to have a return value telling if any test failed, because in a larger build test-failures will disappear in the noise unless they "scream" at you, e.g. by failing the build.
I hope this helps you find a solution and learn from the problem.
I'm trying to write a program for university. The goal of the program is to make a nurse schedule for a hospital. However, i'm really stuck for the moment. Below you can find one function of the program.
The input for the function is a roster which consists of the shift each nurse has to perform on each day. In this example, we have 32 rows (32 nurses) and 28 columns (representing 28 days). Each cell contains a number from 0 to 6, indicating a day off (0) or a certain shift (1 to 6).
The function should calculate for each day, how many nurses are scheduled for a certain shift. For example, on the first day, there are 8 nurses which perform shift 2, 6 shift 3 and so forth. The output of the function is a double vector.
I think the function is mostly correct but when I call it for different rosters the program always gives the first roster gave.
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> nurses_per_shift;
int nbr_nurses_free = 0;
int nbr_nurses_shift1 = 0;
int nbr_nurses_shift2 = 0;
int nbr_nurses_shift3 = 0;
int nbr_nurses_shift4 = 0;
int nbr_nurses_shift5 = 0;
int nbr_nurses_shift6 = 0;
for (int j = 0; j < get_nbr_nurses(); j++)
{
if (roster1[j][i] == 0)
nbr_nurses_free += 1;
if (roster1[j][i] == 1)
nbr_nurses_shift1 += 1;
if (roster1[j][i] == 2)
nbr_nurses_shift2 += 1;
if (roster1[j][i] == 3)
nbr_nurses_shift3 += 1;
if (roster1[j][i] == 4)
nbr_nurses_shift4 += 1;
if (roster1[j][i] == 5)
nbr_nurses_shift5 += 1;
if (roster1[j][i] == 6)
nbr_nurses_shift6 += 1;
}
nurses_per_shift.push_back(nbr_nurses_shift1);
nurses_per_shift.push_back(nbr_nurses_shift2);
nurses_per_shift.push_back(nbr_nurses_shift3);
nurses_per_shift.push_back(nbr_nurses_shift4);
nurses_per_shift.push_back(nbr_nurses_shift5);
nurses_per_shift.push_back(nbr_nurses_shift6);
nurses_per_shift.push_back(nbr_nurses_free);
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
}
Here you can see the program:
Get_shift_assignment() and schedule_LD are other rosters.
void test_schedule_function()
{
calculate_nbr_nurses_per_shift(schedule_LD);
calculate_nbr_nurses_per_shift(get_shift_assignment());
calculate_coverage_deficit();
}
One more function you need to fully understand the problem is this one:
void calculate_coverage_deficit()
{
int deficit = 0;
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> deficit_day;
for (int j = 0; j < get_nbr_shifts(); j++)
{
deficit = get_staffing_requirements()[j] - nbr_nurses_per_shift_per_day[i][j];
deficit_day.push_back(deficit);
}
nurses_deficit.push_back(deficit_day);
}
cout << "Day 1, shift 1: there is a deficit of " << nurses_deficit[0][0] << " nurses." << endl;
cout << "Day 1, shift 2: there is a deficit of " << nurses_deficit[0][1] << " nurses." << endl;
cout << "Day 1, shift 3: there is a deficit of " << nurses_deficit[0][2] << " nurses." << endl;
cout << "Day 1, shift 4: there is a deficit of " << nurses_deficit[0][3] << " nurses." << endl;
}
So the problem is that each time I run this program it always gives me the deficits of the first roster. In this case, this is Schedule_LD. When I first run the function with input roster get_shift_assignment() than he gives me the deficits for that roster.
Apparently the nbr_nurses_per_shift_per_day[][] vector is not overwritten the second time I run the function and I don't know how to fix this... Any help would be greatly appreciated.
Let me try to summarize the comments:
By using global variables to return values from your functions it is very likely, that you forgot to remove older results from one or more of your global variables before calling functions again.
To get around this, return your results from the function instead.
Ex:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<int> nbr_nurses_per_shift_per_day; // Create the result vector
... // Do your calculations
return nbr_nurses_per_shift_per_day;
}
or if you do not want to return a vector:
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1, vector<vector<int>> nbr_nurses_per_shift_per_day)
{
... // Do your calculations
}
But clearly, the first variant is a lot less error-prone (in the second example you can forget to clear nbr_of_nurses again) and most compilers will optimize the return nbr_nurses_per_shift_per_day so the whole vector does not get copied.
The second possible issue is that ´get_nbr_days()´ might return numbers that are larger or smaller than the actual size of your vector. To work around this, use either the size() method of vector or use iterators instead.
Your first function would then look like this:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<vector<int>> nbr_nurses_per_shift_per_day;
for (vector<vector<int>>::iterator shiftsOnDay = roster1.begin(); shiftsOnDay != roster1.end(); ++shiftsOnDay)
{
vector<int> nurses_per_shift(6, 0); // Create vector with 6 elements initialized to 0
for (vector<int>::iterator shift = shiftsOnDay->begin(); shift != shiftsOnDay->end(); ++shift)
{
if (*shift == 0)
nurses_per_shift[5]++;
else
nurses_per_shift[*shift - 1]++; // This code relies on shift only containing meaningful values
}
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
return nbr_nurses_per_shift_per_day;
}