Check the presence of a number in an array with binary search - c++

I have a test assessment that I need to do. There is one question that I have been having trouble with.
I have an array of numbers and I need to find a way to find that number in the array, which I have partially done. The problem becomes in the next step of the project which is that it has to accommodate a million items.
I believe this is binary search. How do I do a binary search or equivalent?
#include <iostream>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <algorithm>
#include <vector>
using namespace std;
class Answer
{
public:
static bool exists(int ints[], int size, int k)
{
for(int i=0; i<size; i++){
if(ints[i]<k){
return true;
}
}
return false;
}
};
The images below gives an idea of what I need and my code
What I need:

Why don't you just use standart lib function?
static bool exists(int ints[], int size, int k)
{
return std::binary_search(ints, ints + size, k);
}

I have already seen you got the answer, but it's never bad to implement binary search yourself, especially on the algorithm course, so may be it will help you to understand the algorithm:
static bool exists(const int ints[], int size, int k) {
int left = 0, right = size-1;
while(right-left>1) {
int middle = (right+left)/2;
if(ints[middle] > k) right = middle;
else left = middle;
}
if(ints[right] == k || ints[left] == k) return true;
return false;
}

Related

how to return a value without exiting a function and storing it subsequently, in c++

Here I'm trying to mimic data feed streaming from stock exchange using random number and subsequently store it in array.
#include <iostream>
#include <array>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <chrono>
#include <ctime>
#include <stdlib.h>
long int prevcntr=0;
using namespace std;
std::pair<long int, double>feedgenerator(long int len)
{
srand(time(0));
for(long int itr=1;itr<=len;itr++)
{
return {itr, (double)rand()/RAND_MAX};
//should continue evaluating the function without exiting
pause(0.001); //To allow some interval for 'makearray' to store it
}
}
template<size_t nn>
std::array<double, nn> makearray(long int cntr, double value, long int len)
{
std::array<double, nn> outarr; // should be able to pass the value of 'len' to 'nn'
long int itr=0;
begin:
while(cntr <= prevcntr)goto begin; // should wait until the next update
outarr[itr] = value;
prevcntr = cntr;
while(itr<len)
{
itr++;
goto begin; // control goes back to the beginning until all the elements of the array are filled with value
}
//should return the array after it is fully filled
return outarr;
}
int main()
{
double *p=new double[];
long int len = 100000;
*p = makearray(feedgenerator(len), len)
// I should be able to call these as nested functions as above
for(int i=0;i<len;i++)
cout<<*p[i]<<"\n";
return 0;
}
Question is how do I return a value without exiting the feedgenerator function. If I try to get all the values at once then it wouldn't mimic the data feed. Data feed is essentially, the same value being updated, sequentially.
To store the data, makearray is being used (vector shouldn't be used as it is extremely slow).
Overall the idea is, feedgenerator should update the same value with an increasing counter (in the real scenario counter will be the time and value will be price etc.) and makearray should store the data (Unless I store the data, the data would be lost, as in the case of data feed from stock exchange) for subsequent analysis.
In makearray, I want to pass the length of the array as an argument of the function, so that it can be controlled by another program. How can it be done is not clear to me.
The code in it's present form, doesn't compile.
Question is how do I return a value without exiting the feedgenerator function
Because you are trying to mimic the data feed stream from stock exchange, so, I think you should consider to use thread. Example:
#include <unistd.h>
#include <deque>
#include <vector>
#include <algorithm>
#include <mutex>
#include <thread>
#include <iostream>
class FeedGenerator {
long int max_length;
std::deque<double> queue;
std::mutex mutex;
std::thread thread;
bool stop;
public:
FeedGenerator(long int len) :
max_length(len), stop(false),
thread(&FeedGenerator::run, this) {
}
virtual ~FeedGenerator() {
stop = true;
thread.join();
}
// Get the latest `len` values
int getData(std::vector<double>& vec, int len) {
std::lock_guard<std::mutex> lock(mutex);
if (queue.empty()) return 0;
int nlen = std::min((size_t)len, queue.size());
vec.resize(nlen);
std::copy(queue.end() - nlen, queue.end(), vec.begin());
return nlen;
}
private:
void run() {
srand(time(0));
while (!stop)
{
{
std::lock_guard<std::mutex> lock(mutex);
queue.push_back((double)rand()/RAND_MAX);
if (queue.size() >= max_length) {
queue.pop_front();
}
}
usleep(1000);
}
}
};
int main()
{
long int len = 100000;
FeedGenerator feedgenerator(len);
sleep(1);
std::vector<double> p;
feedgenerator.getData(p, 10); // get the latest 10 values
for(int i=0;i<p.size();i++)
std::cout << p[i] << std::endl;
return 0;
}

Calculating prime numbers using multi threading

I started to work with threads recently and I tried to run a simple program that uses threads but I get really strange output.
The program writes the prime numbers in the given range with N(parameter to the function)number of threads into the file "PRIMES.txt", if the range <= 1000 the output is fine but if the range is bigger, then the output is something like :
‰‱′″‵‷ㄱㄠ″㜱ㄠ‹㌲㈠‹ㄳ㌠‷ㄴ㐠″㜴㔠″㤵㘠‱㜶㜠‱㌷㜠‹㌸㠠‹㜹ㄠ㄰ㄠ㌰ㄠ㜰ㄠ㤰ㄠ㌱ㄠ㜲ㄠㄳㄠ㜳ㄠ㤳ㄠ㤴ㄠㄵㄠ㜵ㄠ㌶ㄠ㜶ㄠ㌷ㄠ㤷... (much longer)
What would be the problem?
Here is my code :
threads.h :
#include <fstream>
#include <string>
#include <iostream>
#include <thread>
using namespace std;
void writePrimesToFile(int begin, int end, ofstream& file);
void callWritePrimesMultipleThreads(int begin, int end, string filePath, int N);
threads.cpp :
#include "Threads.h"
#include <iostream>
#include <string>
#include <fstream>
#include <thread>
#include <mutex>
#include <vector>
mutex mtx;
void PrimesToFile(int begin, int end, ofstream& file)
{
bool isPrime;
string Primes;
int count = 0;
mtx.lock();
cout << "Thread is running" << endl;
for (int i = begin; i < end; i++)
{
isPrime = true;
for (int j = 2; j < i; j++)
{
if (i%j == 0)
isPrime = false;
}
if (isPrime)
{
Primes.append(to_string(i));
Primes.append(" ");
}
}
file.write(Primes.c_str(), Primes.length());
mtx.unlock();
}
void WritePrimesMultipleThreads(int begin, int end, string filePath, int N)
{
ofstream OP;
OP.open(filePath);
int lastPos = 0;
int destPos = end / N;
thread* TV = new thread[N];
for (int i = 0; i < N; i++)
{
TV[i] = thread(PrimesToFile, lastPos, destPos, ref(OP));
lastPos = destPos;
destPos += end / N;
}
for (int i = 0; i < N; i++)
TV[i].join();
}
Starting point :
#include "Threads.h"
#include <iostream>
#include <string>
#include <fstream>
#include <thread>
void main()
{
WritePrimesMultipleThreads(1, 10000, "PRIMES.txt", 5);
system("PAUSE");
}
Thanks!
Hours of debugging turned out to be in wrong implementation of std::ofstream. Just outputting at the beginning OP << "\n" solved the problem. Compiler is MSVC 2015 update 1. More about about it here. Additionally, you have resource leak, single threading when it is not really intended to, not efficient algorithm of finding primes in a range, compiling errors in your posted code, unnecessary writePrimesToFile function and header files in your header file, you're using using namespace std and may be more problems. I recommend you posting your code at codereview.stackexchange.com to make the code better, because solving this problem is not enough to solve the original problem.
EDIT: You need to flush the stream every time you done writing something.

C++ ~ call to function in client gives error: "identifier ____ is undefined"

I'm coming to you with a problem that has several different files involved. I'm not sure why I'm getting the error specified in the title. Let me put the files below and go from there.
DummyClient.cpp
#include "Gameboard.h" //for Gameboard
#include "Location.h" //for function prototypes
#include "zList.h" //for Zombies
#include <iostream> //for input/output stream
using namespace std;
void main()
{
srand(123456789);
Gameboard myGB;
myGB = Gameboard();
ZombieListClass();
ZombieRec zombieList[MAX_ZOMBIES];
PopulateZombies(zombieList[MAX_ZOMBIES]); // this throws the error here of "Error: identifier "PopulateZombies" is undefined"
}
zList.h
#ifndef ZLIST_H
#define ZLIST_H
#include "Location.h" // for list record
#include "ZombieRec.h"
#include "Gameboard.h"
class ZombieListClass
{
public:
ZombieListClass(); //default constructor
void PopulateZombies(ZombieRec zombieList[]);
bool IsInBounds(int row, int col);
private:
ZombieRec list[MAX_ZOMBIES]; //stores the items in the list
int length; //# of values currently in the list
int currPos; //position of current element
int strength; // health and attack units of a zombie
};
#endif
zList.cpp
#include "zList.h"
ZombieListClass::ZombieListClass() //default constructor
{
length = 0;
currPos = 0;
strength = 5;
LocationRec zombieLoc;
}
void ZombieListClass::PopulateZombies(ZombieRec zombieList[])
{
int row, col;
for (int i = 0; i < MAX_ZOMBIES; i++)
{
row = rand() % MAX_ROW + 1;
col = rand() % MAX_COL + 1;
while (!IsInBounds(row, col))
{
row = rand() % MAX_ROW + 1;
col = rand() % MAX_COL + 1;
}
zombieList[i].currLoc.row = row;
zombieList[i].currLoc.col = col;
}
}
bool ZombieListClass::IsInBounds(int row, int col)
{
if (row == 0 || row == MAX_ROW + 1 || col == 0 || col == MAX_COL + 1)
{
return false;
}
else
{
return true;
}
}
Gameboard.h
#ifndef GAMEBOARD_H
#define GAMEBOARD_H
#include "Location.h"
#include "ZombieRec.h"
#include "zList.h"
const int MAX_ROW = 3; // total number of rows in the board
const int MAX_COL = 3; // total number of cols in the board
class Gameboard
{
public:
Gameboard();
private:
int boardSizeArr[MAX_ROW + 2][MAX_COL + 2];
}; // end Gameboard
#endif
and finally, Gameboard.cpp
#include "Gameboard.h"
Gameboard::Gameboard()
{
// Declares a board with a boundary along the outside
boardSizeArr[MAX_ROW + 2][MAX_COL + 2];
}
I'm not looking to be spoonfed and for somebody to solve my problem for me, I'm trying to figure out what I'm doing wrong so that the remainder of my project isn't as bumpy as it has been this whole time.
Looking back on my error, "identifer "PopulateZombies" is undefined", I can't imagine why it is. Could this have something to do with the scope of how I'm doing things? If I've left any code out (I didn't put everything in there but I think I have everything relevant) just let me know, I'm able to converse back and forth as long as this takes.
Thank you to everybody in advance that tries to help :)
-Anthony
In general, you call the function using a variable, instead of calling it directly if defined in a class:
ZombieListClass zombieList=new ZombieListClass(); // add a variable here
ZombieRec zombieList[MAX_ZOMBIES];
zombieList.PopulateZombies(zombieList[MAX_ZOMBIES]); // See the difference?
I am not sure whether the error you posted is the only error. Here is what I see in your main.cpp
#include "Gameboard.h" //for Gameboard
#include "Location.h" //for function prototypes
#include "zList.h" //for Zombies
#include <iostream> //for input/output stream
using namespace std;
void main()
{
srand(123456789);
Gameboard myGB;
myGB = Gameboard();//The constructor"Gameboard()" is automatically called when you defined
//myGB in the previous line,
ZombieListClass();//see Hai Bi's great answer on this one
ZombieRec zombieList[MAX_ZOMBIES];//ZombieRec is a member of ZombieListClass, use . to access it
PopulateZombies(zombieList[MAX_ZOMBIES]); //Also see Hai Bi's answer
}
My advice is to revisit the concept of constructor and class definition before put your hands on s a problem like this.

Unusual Declaration Error

This seems like a really easy fix, but I can't understand what it's coming from.
Any help fully appreciated!
The following 2 lines of code produce the following errors respectively.
vector <spades::player> players(4, player());
vector <spades::card> deck(52,card());
error: 'player' was not declared in this scope
error: 'card' was not declared in this scope
Below is my card.cpp
#include <iostream>
#include <sys/ioctl.h>
#include <cstdio>
#include <unistd.h>
#include <locale.h>
#include <ncursesw/ncurses.h>
#include "card.h"
namespace spades {
card::card()
{
cardSuit = 0;
cardNum = 0;
}
card::card(int suit, int number)
{
cardSuit = suit;
cardNum = number;
}
}
Below is my player.cpp
#include <iostream> // Stream declarations
#include <vector> //Vectors used to store deck and players hands
#include <string> //String declarations
#include <algorithm> //Shuffle Method
#include <sys/ioctl.h>
#include <cstdio>
#include <unistd.h>
#include <locale.h>
#include <ncursesw/ncurses.h>
#include "player.h"
namespace spades {
using namespace std;
player::player() {
score =0; //total score
bid = NULL; //bid for that round
tricksTaken = 0; //score for thast round
sandBag = 0; //the number of points you win, more than what you bid, every 10th bag = -100
doubleNil = false;
for(int i=0; i<13; i++)
hand.push_back(card());
}
void player::addCard(spades::card b){
for (int i=0; i<hand.size(); i++){
//compare card being played to the ones in your hand to search and determine which one to erase
if((hand.at(i).getCardNum() == 0) &&
(hand.at(i).getSuit() == 0))
{
hand.at(i).setCardNum(b.getCardNum());
hand.at(i).setSuit(b.getSuit());
return;
}
}
}
void player::removeCard(spades::card a) {
for (int i=0; i<hand.size(); i++){
//compare card being played to the ones in your hand to search and determine which one to erase
if((hand.at(i).getCardNum() == a.getCardNum()) &&
(hand.at(i).getSuit() == a.getSuit()))
{
hand.at(i).setCardNum(0);
hand.at(i).setSuit(0);
return;
}
}
}
}
The compiler is actually complaining about the arguments you pass to vector constructors. You specified player() and card() in the constructor arguments, while it is obvious that your types are actually named spades::player and spades::card. You correctly specified the spades:: part in template parameters. Why did you omit the spades:: part from the constructor arguments?
It should be
vector <spades::player> players(4, spades::player());
vector <spades::card> deck(52, spades::card());
It should be noted though that the explicit argument is unnecessary, so you can just do
vector <spades::player> players(4);
vector <spades::card> deck(52);
and get the same result.
Also you don't need the
namespace spades {
}
block in player.cpp, only around you class definition in the header file.
Maybe you ment
using namespace spades;

Code Crashes Immediately After Running

Even at the bare minimum of 10 numbers to input, I get no errors but my code crashes immediately on running. I was also wondering, what should I do if I have a question similar to another question that I've already asked, but on another new problem?
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a[1]=2;
for (int i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime==true) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
}
}
I get no errors but the compiled code crashes immediately.
I changed it to
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a.push_back(2);
for (double i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
}
I addressed all of your problems. It still returns no errors and still crashes.
What makes you think you can do this?
vector<int> a;
a[1]=2;
vector<int> a;
a[1]=2;
You can't access a[1] until you've reserved space for it. You should probably use a.push_back(2) to append 2 to the end of a.
You have declared primer to return int, yet it returns nothing. Either make it void or return the number of primes.
i/a[ii]==floor(i/a[ii]) isn't going to do what you expect. i/a[ii] performs integer division. You should cast i to double before dividing.
if (prime==true) can be changed to simply if (prime), no need to compare a boolean to true.
Please improve your coding style. Use proper indentation and more commonly used variable names: i, j, k instead of i, ii, iii.
Here is another bug:
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
My understanding is that you can only return once from a function, main included. The execution will not loop here because of the return statement.
Did you really want a return statement inside a for loop?