I am currently trying to complete a project. This code is just a binary search algorithm that i have been using. This is my first search algorithm i have ever done, as i am a self learning programmer i need some advice on how to get this too work. I am using QT creator as an IDE.
I do not get any errors in my code. However, when i run the code the answer is always "No Match Found". Im thinking it has something to do with the array itself as i tested it with 10 integers before and worked perfectly fine.
I know im not very good at explaining this as my english is poor. But if you have any questions please get back to me.
Code Written in C++
#include <iostream>
using namespace std;
float binarySearch(float arr[], int left, int right, float x)
{
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == x)
{
return mid;
}
else if (arr[mid] < x)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
int main()
{
float num;
float output;
float myarr[100] = {44.64978683, 44.62352548, 44.5972165, 44.57086043, 44.54445783,
44.51800925, 44.49151522, 44.46497629, 44.43839299, 44.41176587,
44.38509546, 44.35838228, 44.33162687, 44.30482976, 44.27799146,
44.25111251, 44.22419342, 44.1972347, 44.17023688, 44.14320046,
44.11612596, 44.08901388, 44.06186473, 44.03467901, 44.00745722,
43.98019985, 43.95290742, 43.9255804, 43.89821929, 43.87082457,
43.84339674, 43.81593628, 43.78844366, 43.76091937, 43.73336389,
43.70577768, 43.67816122, 43.65051497, 43.62283941, 43.595135,
43.56740221, 43.53964148, 43.51185328, 43.48403806, 43.45619628,
43.42832838, 43.40043481, 43.37251603, 43.34457246, 43.31660456,
43.28861275, 43.26059748, 43.23255917, 43.20449827, 43.17641519,
43.14831036, 43.12018421, 43.09203716, 43.06386963, 43.03568203,
43.00747477, 42.97924828, 42.95100295, 42.92273919, 42.89445742,
42.86615803, 42.83784141, 42.80950798, 42.78115811, 42.75279222,
42.72441067, 42.69601387, 42.6676022, 42.63917604, 42.61073577,
42.58228177, 42.55381441, 42.52533407, 42.49684112, 42.46833593,
42.43981886, 42.41129027, 42.38275054, 42.35420001, 42.32563904,
42.29706799, 42.26848721, 42.23989705, 42.21129785, 42.18268996,
42.15407372, 42.12544947, 42.09681755, 42.06817829, 42.03953203,
42.01087909, 41.98221981, 41.9535545, 41.9248835, 41.89620711};
while(true)
{
cout << "Please enter an element to search" << endl;
cin >> num;
output = binarySearch(myarr, 0, 100, num);
if (output == -1)
{
cout << "No Match Found" << endl;
}
else
{
cout << "Match found at position: " << output << endl;
}
}
}
The elements of your array myarr is sorted in decending order, so left should be set to mid+1 when current element is larger than target, not smaller.
Wrong:
else if (arr[mid] < x)
Correct:
else if (arr[mid] > x)
Also the array has only 100 elements, so the initial right should be 99, not 100.
Wrong:
output = binarySearch(myarr, 0, 100, num);
Correct:
output = binarySearch(myarr, 0, 99, num);
Related
I am working on a problem in which I'm given a list of numbers representing the diameter of cake layers (for example: 9 12 10 7 4 6 11 5). With this list, I have to find the length of the longest combination of numbers that are equal to or decreasing (stacking cake layers from greatest diameter at the bottom to smallest at the top). You are allowed to skip over numbers, but you can't come back to them. I.e. with the previous list, the length of the longest combination would be 5 with the combination being (12,10,7,6,5).
I believe that the best way to solve this would be feeding the array into a tree and returning the height of the tree. This is currently the code I have, with a working tree implementation above the main
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string sizeInput, transfer; //Strings to hold input and transfer to array
int maxLayers = 0, numOfInputs = 0, numNodes = 0; //ints for holding the max height and the number of inputs by the user
int cakeSizes [30]; //Array holding sizes of the cakes input, no more than 30
cout << "Cake sizes: ";
getline(cin,sizeInput); //Gets input from user and puts into a stringstream
stringstream readInput(sizeInput);
while(readInput >> transfer)
{
cakeSizes[numOfInputs] = stoi(transfer); //Puts the numbers into the array and counts how many were placed
numOfInputs++;
}
for(int i=0; i<numOfInputs; i++) //Puts the array into a tree
{
Tree<int> cakeStack; //Creates tree to hold combination
initialize(cakeStack);
for(int j=i; j<numOfInputs; j++)
{
if(cakeSizes[j]<=cakeSizes[j-1])
{
insert(cakeStack, cakeSizes[j]);
}
}
if(height(cakeStack) > maxLayers) //Checks if the new combination tree's height is greater than the last
{
maxLayers = height(cakeStack);
}
destroy(cakeStack); //Destroys the tree from the previous combination in preparation for new one
}
cout << endl << "You can build a cake with " << maxLayers << " layers.";
}
This actually works for combinations that are always decreasing (like 5,4,2,1 and 8,3,2,1), but it fails when interrupting numbers are thrown in (like with 5,4,2,8,1). I'm almost certain that the problem lies here:
for(int j=i; j<numOfInputs; j++)
{
if(cakeSizes[j]<=cakeSizes[j-1])
{
insert(cakeStack, cakeSizes[j]);
}
}
But I'm unsure of how to implement it an a way that checks all combinations of the array (like skipping numbers that wouldn't give the longest combination), rather than running straight down the list unable to skip numbers.
The tree is definitely the way to go. You build the tree by inserting each value under the smallest node larger than it. Then when the tree is finished you iterate through it looking for the longest path.
What I did in the code below is I made a head node to store the sub trees and it needed a really large value so that all the inputs would fit under it. But then when I print the tree or look for a path I need to ignore that head node, so I have to keep track of the depth.
#include <iostream>
#include <vector>
#include <climits>
struct Tree {
Tree(int value) : value(value) {}
int value;
std::vector<Tree> children;
};
// Recursively check this level of the tree
void insert_node(Tree& node, int value)
{
// if the new value is bigger than where
// we are then stop descending
if (value > node.value)
return;
// if the new value fits under this
// parent then check all the children
bool inserted = false;
for (Tree& child : node.children)
// if we find a child large enough
// then insert ourselves inside
if (value < child.value)
{
insert_node(child, value);
inserted = true;
}
// if the new value fits under this parent but
// not under any of the children then put it here
if (!inserted)
node.children.push_back(value);
}
void print_tree(Tree node,
std::vector<bool> flags = std::vector<bool>(100, true),
bool last = false,
int depth = 0)
{
for (int i = 1; i < depth; ++i)
{
if (flags[i])
std::cout << "| ";
else
std::cout << " ";
}
// Don't print our fake head
if (depth > 0)
{
std::cout << "+- " << node.value << '\n';
if (last) flags[depth] = false;
}
int n = 0;
for (Tree child : node.children)
{
last = (n++ == node.children.size() - 1);
print_tree(child, flags, last, depth + 1);
}
flags[depth] = true;
}
void print_path(std::vector<int> path)
{
std::cout << "Path:";
for (int value : path)
std::cout << " " << value;
std::cout << "\n";
}
void print_paths(Tree node,
std::vector<int>& max_path,
std::vector<int> path = std::vector<int>(),
int depth = 0)
{
// Don't add our fake head
if (depth > 0)
path.push_back(node.value);
if (node.children.size() == 0)
{
print_path(path);
// check if this path is the longest one yet
if (max_path.size() < path.size())
max_path = path;
}
for (Tree child : node.children)
print_paths(child, max_path, path, depth + 1);
}
int main()
{
Tree head(INT_MAX);
std::vector<int> input = {9, 12, 10, 7, 4, 6, 11, 5};
// Build the tree
for (int value : input)
insert_node(head, value);
// Print the tree
std::cout << "Tree:\n";
print_tree(head);
std::cout << "\n";
// Print the paths and
// find the longest one
// and then print it too
std::vector<int> max_path;
print_paths(head, max_path);
std::cout << "\nLongest ";
print_path(max_path);
return 0;
}
I've searched around but can't really understand or find help, since this iterative algorithm will require two stacks (to contain a left_Index and right_Index).
The main recursive way involves having it one side until the left_Index >= right_Index, and recursively doing so for both sides and per subsection (if that makes sense), which I don't understand how to do so exactly since I'm maintaining two stacks and need to see how exactly they relate to one another.
This problem is mostly due to me not understanding the way the normal recursive method words, although when looking at them side by side to see how to approach it, I always get stuck on what to do.
The backstory as to why I'm doing this:
Trying to solve the word ladder problem to go from A to B and decided to make a BST where the connections are connected by singular character differences and lengths. I'm getting the words from a text file containing a lot of the dictionary, and since I'm using a BST as the master list with all vertices the fact that this is a dictionary means every insert will be in order so the tree is right-leaning (so the speeds are slow for inserting O(n^2) which is a big hinderance). I was planning on storing data in an array then making a balanced BST from that since I believe speeds should go faster since insertion will be O(n*logn) which seems great. The problem with that is that I can't use a recursive approach since there's a lot of data leading to stack overflows, so I need to make it iteratively with stacks and loops, but am finding it too difficult.
My bad attempt at a start:
while (lindx.the_front() < rindx.the_back())
{
mid =(lindx.the_front() + rindx.the_back()) / 2;
dictionary.addVertex(vector[mid]);
std::cout << "Pushed " << vector[mid] << '\n';
rindx.push(mid - 1);
}
That basically gets the 1/2's from the left half of the program from a linked stack I made. "the_front()" is the first insertion, "the_back()" is the final/latest insert into the list. The main problem I have is understanding how to make it repeat per half to get all the values.
I need to find my past homework where I've done this but the code is something along the lines of...
void array2balanced(int array[], int lIndex, int rIndex)
{
//base case
if(lIndex > rIndex)
{
return;
}
//recursive cals
else
{
mid = (lIndex+rIndex)/2;
tree.insert(array[mid]);
array2balanced(array, lIndex, mid-1);
array2balanced(array, mid+1, rIndex);
}
}
UPDATE:
Progress so far
void balancedTree(std::vector<std::string> vector, dictionaryGraph &dictionary) // divide and conquer into tree?
{
linkedStack<int> lindx, rindx, midX;
unsigned int l_Index{ 0 }, r_Index{ vector.size() - 1 }, mid{ (l_Index + r_Index) / 2 };;
lindx.push(l_Index);
rindx.push(r_Index);
midX.push(mid);
int testCount{ 0 };
std::cout << "There are " << vector.size() << " words.\n";
while (!midX.empty())
{
mid = midX.pop();
l_Index = lindx.pop();
r_Index = rindx.pop();
std::cout << "inputted " << vector[mid] << '\n';
dictionary.addVertex(vector[mid]);
testCount++;
if (r_Index > l_Index)
{
midX.push((l_Index + mid) / 2);
lindx.push(l_Index);
rindx.push(mid - 1);
}
if (l_Index < r_Index)
{
midX.push((mid + r_Index) / 2);
lindx.push(mid + 1);
rindx.push(r_Index);
}
}
std::cout << testCount << " words were inputted...\n"; // To see how many were inserted
system("pause");
}
Problem I have is some inputs get repeated and some missed.
I don't think you need two stacks. You just need either a one stack or one queue.
Below codes can be tested on Leetcode
Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
One Stack Method
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None
l = len(nums)
node = TreeNode(0)
head = node
s = collections.deque([(node, 0, l)])
while s:
node, left, right = s.pop()
mid = (right + left) // 2
node.val = nums[mid]
if mid < right-1:
node.right = TreeNode(0)
s.append((node.right, mid+1, right))
if left < mid:
node.left = TreeNode(0)
s.append((node.left, left, mid))
return head
One Queue Method
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None
l = len(nums)
node = TreeNode(0)
head = node
q = collections.deque([(node, 0, l)])
while q:
node, left, right = q.popleft()
mid = (right + left) // 2
node.val = nums[mid]
if left < mid:
node.left = TreeNode(0)
q.append((node.left, left, mid))
if mid < right-1:
node.right = TreeNode(0)
q.append((node.right, mid+1, right))
return head
They are implemented using deque. Notice popleft() returns the first element(like stack) and pop() returns the last element(like queue).
This problem is mostly due to me not understanding the way the normal
recursive method words, although when looking at them side by side to
see how to approach it, I always get stuck on what to do.
It takes practice ... and maybe reviewing other peoples work.
require two stacks (to contain a left_Index and right_Index).
My apologies, I do not understand why the OP thinks this. My demo below has only 1 stack called 'todo', perhaps you will find the idea useful.
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
#include "./BTree.hh" // code not provided, used in this MCVE to
// conveniently provide "showTallTreeView()"
typedef std::vector<int> IVec_t;
class T607_t
{
IVec_t m_sortedIVec; // sorted - created with for loop
IVec_t m_recursiveIVec; // extract from sorted by recursion
IVec_t m_iterativeIVec; // extract from sorted by iteration
public:
T607_t() = default;
~T607_t() = default;
int exec(int , char** )
{
fillShowSortedIVec();
fillShowRecursiveIVec();
fillShowIterativeIVec();
showResults();
return 0;
}
private: // methods
The vectors are in class T607_t, so that each is available to any member function.
For this MCVE, I simply create "IVec_t m_sortedIVec;" and fill with a simple for loop:
void fillShowSortedIVec()
{
for (int i=0; i<15; ++i)
m_sortedIVec.push_back (i*100); // create in sorted order
showIVec(m_sortedIVec, "\n m_sortedIVec :");
}
Next (in this MCVE) is the recursive fill and show, and my adaptation of the OP's recursive method to produce the recursive insert sequence:
// ///////////////////////////////////////////////////////////////
void fillShowRecursiveIVec()
{
assert(m_sortedIVec.size() > 0);
int max = static_cast<int>(m_sortedIVec.size()) - 1;
// use OP's recursive insert
array2balancedR (m_sortedIVec, 0, max);
// NOTE - 'sequence' is inserted to 'm_recursiveIVec'
// instead of into tree the op did not share
showIVec(m_recursiveIVec, "\n m_recursiveIVec:");
}
// recursive extract from: m_sortedIVec to: m_recursiveIVec
// my adaptation of OP's recursive method
void array2balancedR(IVec_t& array, int lIndex, int rIndex)
{
//base case
if(lIndex > rIndex)
{
return;
}
else //recursive calls
{
int mid = (lIndex+rIndex)/2;
m_recursiveIVec.push_back(array[mid]); // does this
// tree.insert(array[mid]); // instead of this
array2balancedR(array, lIndex, mid-1); // recurse left
array2balancedR(array, mid+1, rIndex); // recurse right
}
}
Note: I left the "IVec_t& array" as a parameter to this function, because the OP's code has it. Within this 'class' wrapper, the function need not pass the array 'through the recursion', because each method has access to the instance data.
Next (in this MCVE) is a fill and show action using one possible iterative approach. I styled this iterative approach carefully to match the OP's recursive effort.
First, I added a 'tool' (IndxRng_t) to simplify the 'stack' capture of iterations for later processing. (i.e. "todo").
// //////////////////////////////////////////////////////////////
// iterative extract from m_sortedIVec to: m_iterativeIVec
class IndxRng_t // tool to simplify iteration
{
public:
IndxRng_t() = delete; // no default
IndxRng_t(int li, int ri)
: lIndx (li)
, rIndx (ri)
{}
~IndxRng_t() = default;
// get'er and set'er free. also glutton free. gmo free.
bool done() { return (lIndx > rIndx); } // range used up
int mid() { return ((lIndx + rIndx) / 2); } // compute
IndxRng_t left(int m) { return {lIndx, m-1}; } // ctor
IndxRng_t right(int m) { return {m+1, rIndx}; } // ctor
private:
int lIndx;
int rIndx;
};
void fillShowIterativeIVec()
{
assert(m_sortedIVec.size() > 0);
int max = static_cast<int>(m_sortedIVec.size()) - 1;
array2balancedI(m_sortedIVec, 0, max);
// 'sequence' inserted to 'm_iterativeIVec'
showIVec(m_iterativeIVec, "\n m_iterativeIVec:");
}
void array2balancedI(IVec_t& array, int lIndex, int rIndex)
{
std::vector<IndxRng_t> todo;
todo.push_back({lIndex, rIndex}); // load the first range
// iterative loop (No recursion)
do
{
if (0 == todo.size()) break; // exit constraint
// no more ranges to extract mid from
// fetch something to do
IndxRng_t todoRng = todo.back();
todo.pop_back(); // and remove from the todo list
if(todoRng.done()) continue; // lIndex > rIndex
int mid = todoRng.mid();
m_iterativeIVec.push_back(array[mid]); // do this
// tree.insert(array[mid]); // instead of this
todo.push_back(todoRng.right(mid) ); // iterate on right
todo.push_back(todoRng.left(mid) ); // iterate on left
}while(1);
}
And this mcve generates a result display:
void showResults()
{
assert(m_recursiveIVec.size() == m_sortedIVec.size());
assert(m_iterativeIVec.size() == m_sortedIVec.size());
std::cout << std::endl;
std::stringstream ss; // for btree use only
std::cout << "\n demo:\n create a BTree, "
<< std::flush;
std::cout << "\n Insert IVec_t " << std::endl;
BBT::BTree_t btree(ss);
std::cout << std::flush;
for (size_t i=0; i<m_iterativeIVec.size(); ++i)
btree.insertPL(m_iterativeIVec[i]);
std::cout << "\n iterative result:\n\n"
<< btree.showTallTreeView();
}
void showIVec(IVec_t& ivec, std::string lbl)
{
std::cout << lbl << std::endl;
for (auto it : ivec)
std::cout << std::setw(5) << it << std::flush;
std::cout << std::endl;
}
}; // class T607_t
int main(int argc, char* argv[])
{
T607_t t607;
return t607.exec(argc, argv);
}
My output (on Ubuntu 17.10, g++ 7.2.0),
m_sortedIVec :
0 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400
m_recursiveIVec:
700 300 100 0 200 500 400 600 1100 900 800 1000 1300 1200 1400
m_iterativeIVec:
700 300 100 0 200 500 400 600 1100 900 800 1000 1300 1200 1400
demo:
create a BTree,
Insert IVec_t
iterative result:
BTree_t::showTallTreeView(): (balance: 0 sz: 15)
0
100
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
-----------------
Iterative JavaScript implementation of converting sorted array to Binary Search Tree (BST):
function sortedArrayToBstIteratively(nums) {
// use stack to iteratively split nums into node tuples and reuse values
const stack = []
// add root node to tree
const tree = { first: 0, last: nums.length - 1 }
stack.push(tree)
// split array in the middle and continue with the two halfs
while (stack.length > 0) {
const node = stack.pop()
if (node.last >= node.first) {
if (node.last === node.first) {
// node reaches a single leaf value (last == first)
node.value = nums[node.first]
} else {
// node has still valid indices to further split the array (last > first)
const middle = Math.ceil((node.first + node.last) / 2)
node.value = nums[middle]
node.left = { first: node.first, last: middle - 1 }
node.right = { first: middle + 1, last: node.last }
stack.push(node.left)
stack.push(node.right)
}
} else {
// node has no more valid indices (last < first), create empty leaf
node.value = null
}
delete node.first
delete node.last
}
// console.log(JSON.stringify(tree))
return tree
}
I was assigned to create an array check (to see if the array is increasing, decreasing, or neither [then exiting if neither]) and a recursive binary search for one of my assignments. I was able to do these things after some help from my peers, but I need help in finding what seems to be causing the error
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Aborted
when running the code. I Googled this error and this error seems to be vague or I just am not understanding. It compiles without errors, but I need help in what finding what I did wrong. It is able to run without the binarySearchR function and its associating code, as the array check on its own was the previous assignment. Below is the code, and I thank you so much in advance!
#include <iosteam>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
int checkArraySort (string *fileLines, int numberOfLines);
int binarySearchR (string *fileLines, string searchKey, int iMin, int iMax);
int main ()
{
int numberOfLines = 0;
string searchKey = 0;
cout << "Input search key: ";
cin >> searchKey;
ifstream fileIn;
fileIn.open("words_in.txt");
string line;
if (fileIn.eof()) /* Checks file to see if it is blank before proceeding */
{
exit (EXIT_SUCCESS);
}
else
{
while(!(fileIn.eof()))
{
fileIn >> line;
numberOfLines++;
}
fileIn.close(); /* closes fileIn, need to reopen to reset the line location */
fileIn.open("words_in.txt");
string *fileInLines;
fileInLines = new string[numberOfLines];
for (int i = 0; i < numberOfLines; i++)
{
fileIn >> line;
fileInLines[i] = line;
}
fileIn.close(); /* closes fileIn */
int resultingCheck = checkArraySort(fileInLines, numberOfLines);
if (resultingCheck == -1)
{
cout << "The array is sorted in descending order." << endl;
}
else if (resultingCheck == 1)
{
cout << "The array is sorted in ascending order." << endl;
}
else
{
cerr << "ERROR: Array not sorted!" << endl;
exit (EXIT_FAILURE);
}
int searchResult = binarySearchR (fileInLines, searchKey, 0, numberOfLines);
if (!searchResult == -1)
{
cout << "Key found at index " << searchResult << "." << endl;
}
else
{
cout << "Key not found at any index." << endl;
}
exit (EXIT_SUCCESS);
}
}
int checkArraySort (string *fileLines, int numberOfLines)
{
int result = 1; /* Ascending by default */
for (int i = 1; i < numberOfLines; i++) /* Checks if decending */
{
if (fileLines[i] < fileLines[i-1])
{
result = -1;
}
}
if (result == -1) /* Makes sure it is descending (or if it is neither) */
{
for (int i = 1; i < numberOfLines; i++)
{
if (fileLines[i] > fileLines[i-1])
{
result = 0;
}
}
}
return result;
}
int binarySearchR (string *fileLines, string searchKey, int iMin, int iMax)
{
// so, its gotta look at the center value and each times, it discards half of the remaining list.
if (iMax < iMin) /* If the minimum is greater than the maximum */
{
return -1;
}
else
{
int iMid = (iMin + iMax) / 2;
if (fileLines[iMid] > searchKey) /* If the key is in the lower subset */
{
return binarySearchR (fileLines, searchKey, iMin, iMid - 1);
}
else if (fileLines[iMid] < searchKey) /*If the key is in the upper subset */
{
return binarySearchR (fileLines, searchKey, iMin, iMid + 1);
}
else /*If anything else besides the two */
{
return iMid;
}
}
}
The easy way: add a bunch of cout s to see where you program goes and what the values are.
Pros
Easy to do
Cons
Requires a recompile each time you want to add more info
The hard way: Learn to use a debugger
Pros
Can inspect "on the fly"
Don't need to rebuild
Can use what you learn in every other C++ program
Cons
Requires a bit of research to learn how to do it.
This question already has an answer here:
Number Gusser in c++ using function and midpoint
(1 answer)
Closed 8 years ago.
I am writing a program for number guesser using function and midpoint to find out the number that been chosen. I have a problem compiling and I can't figure out the problem ????
The description of my problem:
The playOneGame function should have a return type of void. It should
implement a complete guessing game on the range of 1 to 100.
The shouldPlayAgain function should have a boolean return type. It
should prompt the user to determine if the user wants to play again,
read in a character, then return true if the character is a ‘y’, and
otherwise return false.
In addition, you should implement the helper functions
getUserResponseToGuess, and getMidpoint. They should be invoked inside
your playOneGame function.
getUserResponseToGuess. This function should prompt the user with the
phrase “is it ? (h/l/c): “ with the value replacing the token
. It should return a char. The char should be one of three
possible values: ‘h’, ‘l’, or ‘c’. It should have the following
signature: char getUserResponseToGuess(int guess)
getMidpoint. This function should accept two integers, and it should
return the midpoint of the two integers. If there are two values in
the middle of the range then you should consistently chose the smaller
of the two. It should have the following signature: int getMidpoint(int low, int high)
My code:
#include<iostream>
using namespace std;
void playOneGame;
char getUserResponseToGuess(int guess);
int getMidpoint ( int low, int high);
int main() {
do
{
playOneGame();
} while (shouldPlayAgain());
return 0;
}
void playOneGame
{
int a = 100;
cout << "\nGuess a number between 1 and 100. " <<endl;
getUserResponseToGuess ( a);
}
char getUserResponseToGuess(int guess)
{
while (true)
{
int guess = getMidpoint(minimum, maximum);
std::cout << "\nIs it [h]igher/[l]ower/[e]qual to " << guess << "? ";
char answer;
if (!(std::cin >> answer))
{
std::cerr << "error reading user input, program exiting\n";
exit(1);
}
if (answer == 'h')
minimum = guess + 1;
else if (answer == 'l')
maximum = guess - 1;
else if (answer == 'e')
{
std::cout << "Well, isn't that nice.\n";
return;
}
if (minimum > maximum)
{
std::cerr << "hey, you lied to me!\n";
exit(1);
}
}
}
int getMidpoint ( int low, int high)
{
int mid;
mid = (low + high) / 2;
return mid;
}
void playOneGame; is not a function forward declaration. void playOneGame(); is. Also the same applies for the function definition.
Also, you should define shouldPlayAgain() and include <stdlib.h> for exit() to work.
And getUserResponseToGuess() has just a return instead of returning something useful and it does not return anything on the default branch.
so i have been working on a code for over two weeks and its not going too well. here are the instructions and the code is below it, as well as errors:
Task 1: Create one instance of this class. (the sorted list; he also had other instructions on HOW to start the code, but its already been done by me below in the code such as typedef...) You also need to read in data from one data file: float.dat, which contains the following numbers:
5.5
6.2
7.1
8.0
9.0
10.0
1.0
2.0
3.3
4.4
Data in float.dat contains floating numbers, which should be inserted into the object of SortedList. Note that you do not have any prior knowledge about data values in float.dat, but we assume that there are 10 elements in the data file.
Task 2: Use GetNextItem( ) to print out all the elements in the list in sorted sequence on computer screen.
Task 3: Use GetNextItem( ) to output all the elements in the list in sorted sequence onto a data file, output.dat.
Task 4: Design your test cases to demonstrate InsertItem( ), DeleteItem( ) and RetrieveItem( ) are working as expected.
here is the code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#define MAX_ITEMS 10
typedef float ItemType;
class SortedList
{
private:
int length;
ItemType values[MAX_ITEMS];
int currentPos;
enum RelationType { LESS, GREATER, EQUAL };
public:
SortedList() {length = 0; currentPos = -1;}
int getLength() {return length;}
RelationType ComparedTo(ItemType x)
{
if (length > x.getLength())
return LESS;
else if (length == x.getLength())
return GREATER;
else
return EQUAL;
}
void MakeEmpty() {length = 0;}
void InsertItem(ItemType x)
{
int first = 0, last = length --;
bool moreToSearch = (first <= last);
int location = 0;
int midpoint= (first + last) / 2;
while (moreToSearch)
{
switch (x.ComparedTo(values[location]))
{
case LESS: //search in 1st half
moreToSearch = (first <= last);
break;
case GREATER:
location++;
moreToSearch = (location < length);
break;
}
}
for (int index = length; length > location; index--)
{
values[index] = values[index - 1];
}
values[location] = x;
length++;
}
void DeleteItem(ItemType x)
{
int location = 0;
while (x.ComparedTo(values[location]) != EQUAL)
location++;
for (int index = location ++; index < length; index++)
values[index --] = values[index];
length--;
}
void RetrieveItem(ItemType &x, bool & found)
{
int midpoint;
int first = 0, last = length - 1;
bool moreToSearch = (first <= last);
found = false;
int index = 0;
while (moreToSearch && !found)
{
midpoint = (first + last) / 2;
switch (x.ComparedTo(values[index++]))
{
case LESS: //search in 1st half
moreToSearch = (first <= last);
last = midpoint - 1;
break;
case GREATER: //Search in 2nd half
first = midpoint + 1;
moreToSearch = (first <= last);
break;
case EQUAL: //x has been found
found = true;
break;
}
}
}
int LengthIs() {return length;}
void ResetList() {currentPos = -1;}
bool IsFull()
{
if (length < 9)
return false;
else
return true;
}
void GetNextItem(ItemType &x)
{
currentPos++;
x = values[currentPos];
cout << x;
}
};
int main()
{
SortedList x;
ifstream inFile; ofstream output;
string line;
bool allAboutLists;
int i = 0;
int size = 0;
inFile.open("float.txt");
float values[10];
while (!inFile.eof()) // write or read data from inFile into values
{
inFile >> values[i];
i++;
size++; // this will count how many values there are in the array
x.InsertItem(values[i]);
++i;
}
x.ResetList();
cout << "The following is the list that's been made:" << endl << endl;
x.InsertItem(64);
//x.printlist();
cout << endl;
x.DeleteItem(64);
//x.printlist();
x.RetrieveItem(7.1, allAboutLists);
cout << endl;
cout << endl << "The length is: "; x.LengthIs(); cout << endl;
cout << "Is the list full?: " << boolalpha << x.IsFull() << endl;
cout << "The next item is: ";
for (int i = 0; i < 10; i++)
{
cout << x.GetNextItem << endl;
}
x.ResetList();
inFile.close();
output.open("output.txt");
for (int f = 0; f < 10; f++)
{
output << x.GetNextItem << endl;
}
system("pause");
return 0;
}
and the compiler keeps saying this:
(25) error C2228: left of '.getLength' must have class/struct/union [they mean the x. its red lined under, same for the rest of those left of etc..]
(27) error C2228: left of '.getLength' must have class/struct/union
(44) error C2228: left of '.ComparedTo' must have class/struct/union
(66): error C2228: left of '.ComparedTo' must have class/struct/union
-and also, 7.1 in main has something about refernce type mistake.
I am in extereme hurry as i have been working on it for 2 weeks now and its driving me crazy ! I have the code done as seen and more than wnough and just need to know what to change exactly because I am following everything I have been searching and researching yet its no good. so precise details or code specifically taken from mine and fixed would be appreciated.
Thanks!
You are passing x as ItemType which is a float.
float doesn't have those methods... looks like you wanted to pass it as a SortedList
The compare function needs two parameters in order to do a compare. Instead of ComparedTo, you may want to call it CompareToLocation.
RelationType CompareToLocation(ItemType x, size_t location){
if(x < values[location]) return LESS;
if(x == values[location]) return EQUAL;
return GREATER;}
An example usage would be:
result = CompareToLocation(x, location);
// ...
You defined ComparedTo as a method for SortedList, yet everytime you call that function, you call it on ItemType objects, which are actually floats.
As you can see in the definition of the method, you are trying to use, once again, SortedList methods on float Objects:
RelationType ComparedTo(ItemType x)
{
if (length > x.getLength())
return LESS;
else if (length == x.getLength())
return GREATER;
else
return EQUAL;
}
Your problem is not really a compiling one, but a conceptual one, since you don't seem to grasp what your are actually coding.
I'd recommend have your declarations and implementations separate, so you can see at a glance how does your class work.
Your class declaration should look something like this:
class SortedList
{
private:
int length;
ItemType values[MAX_ITEMS];
int currentPos;
enum RelationType { LESS, GREATER, EQUAL };
public:
SortedList();
int getLength();
RelationType ComparedTo(ItemType x) ;
void MakeEmpty();
void InsertItem(ItemType x) ;
void DeleteItem(ItemType x);
void RetrieveItem(ItemType &x, bool & found);
int LengthIs();
void ResetList();
bool IsFull();
void GetNextItem(ItemType &x);
};
You should focus on each method, making clear what each one of them is trying to achieve, and what does it need to achieve it (parameters).
For example:
RelationType ComparedTo(ItemType x) ;
Your SortedList class has this function, which receives an ItemType (float) as a parameter.
What is this trying to achieve? How do you compare a whole ordered list to a single element?
How can a single number be greater, less or EQUAL to a set of numbers?
Maybe what you really want to do is compate parameter X with an element inside the list?
If this is the case, how do you know which element in the list must be compared to parameter X? You should add another parameter telling you which element inside your ordered list to compare X to.
I quess this doesn't really solve your problem, but at least I hope this helps you understand better what your problem is.