How can I get rid of fixed sentinel value (-32767)? - c++

Below is the program I wrote to find sum of a subarray from given array, however somehow I am not getting how can I get rid of the sentinel value (-32767 in this case)? and how can I optimise it?
and how can I keep track of range of max subarray?
#define EVALUE -32767
using namespace std;
int findMaxSubArray(vector<int>,int low,int high);
int findMaxSubArray_Mid(vector<int>,int low,int high);
int main()
{
vector<int> v;
int j=0;
cout << "Enter array values(-32767 to end): ";
while(1)
{
cin >> j;
if (EVALUE==j)
break;
v.push_back(j);
}
if(v.size()!=0)
cout << "Max sum is: " << findMaxSubArray(v,0,v.size()-1) << "\n";
else
cout << "No array elements entered, exiting...\n";
system("pause");
return 0;
}
int findMaxSubArray(vector<int> v, int low, int high)
{
if(low==high) return v[low];
int max_mid_sum=findMaxSubArray_Mid(v,low,high);
int max_left_sum=findMaxSubArray(v,low,(low+high)/2);
int max_right_sum=findMaxSubArray(v,(low+high)/2+1,high);
if (max_mid_sum>max_left_sum) return (max_mid_sum>max_right_sum?max_mid_sum:max_right_sum);
else return(max_left_sum>max_right_sum?max_left_sum:max_right_sum);
}
int findMaxSubArray_Mid(vector<int> v,int low,int high)
{
int mid=high/2;
int max_left_sum=0;
int max_right_sum=0;
int sum=0;
for(int i=mid;i>=low;--i)
{
sum+=v[i];
if(sum>max_left_sum)
{
max_left_sum=sum;
}
}
sum=0;
for(int i=mid+1;i<=high;++i)
{
sum+=v[i];
if(sum>max_right_sum)
{
max_right_sum=sum;
}
}
return (max_right_sum+max_left_sum);
}

When reading from a textfile, the last character that cin will get is the "EOF" character, or end of file character. You can send this character to your program in the command line with control+d. You're going to want to check for this rather than -32767.
This is a basic program that should identify a simple fix for your problem:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v;
int j;
cout << "Enter array values (Control+D (EOF) to end): ";
cin >> j;
while(cin.good())
{
v.push_back(j);
cin >> j;
}
return 0;
}
If you want to get really smart you can use the below and it will directly insert the contents of the memory at cin (from the beginning until EOF) into your vector. As far as running time goes, this will probably be faster than your solution and the above solution.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
vector<int> v;
cout << "Enter array values (Control+D (EOF) to end): ";
istream_iterator<int> in(cin);
istream_iterator<int> eof;
copy(in, eof, back_inserter(v));
ostream_iterator<int> out(cout, "\n");
copy(v.begin(), v.end(), out);
return 0;
}

About the sentinel, IIRC with Control+D you close standard input(may depend of OS). That will cause the << to fail (I am not sure how, probably you'll have to catch an exception).
Anyway, the rest of the code is just a recursive (binomial) adding of the vector. You can sustitute all of it with a simple for
for(int i = 0; i < v.size(); i++) {
total += v[i]
}
The question about range of max subarray is already managed by the class Vector

Related

What should i do to get the smallest of the sequence entered by the user?

I am making a program that should reader the user's input until something non-numeric is enetered by the user. I have to do this with vector. So the user has to define the the values of the elements and the size of the vector. The numVals should be intizialed as the amount of elements the user enters. The program should find the second smallest number of the sequence. So i tried to get first the smallest number, because that is easier. But give as input always zero instead of the minimum. Can anyone tell me what is wrong?
#include<iostream>
#include<vector>
#include<limits>
#include<stdexcept>
using namespace std;
int main(){
unsigned int i;
int numVals;
int min;
vector<int>sequence(numVals);
cout << "sequence: ";
while (cin.good()){
for (i=0; i<sequence.size(); ++i){
cin >> sequence.at(i);
}
}
min =sequence.at(0);
for (i=0; i<sequence.size();++i){
if (sequence.at(i)< min){
min=sequence.at(i);
}
}
cout << min << endl;
return 0;
}
There are quite a few issues with your code. The following code should do what you had in mind.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int num;
vector<int>sequence;
cout << "sequence: ";
while(cin >> num)
sequence.push_back(num);
int min = sequence.at(0);
for (int n: sequence)
{
if (n < min)
min = n;
}
cout << min << endl;
}
First of all, you have initialized the vector with an undefined size by not initializing numVals.
Secondly, cin.good() is used incorrectly.cin.good() gives the status of the last input. So in the case where it returns false, a zero input would have entered your sequence, which means the zero entry will always be the smallest!
EDIT: Refactored the implementation thanks to comments from #n.m.

Can't stop reading lines in c++

The following code is for a homework assignment due on 17 October. The problem states to "write a program with a loop that lets the user enter a series of numbers. After all the numbers have been entered, the program should display the largest and smallest numbers entered."
#include "stdafx.h"
#include <algorithm>
#include <array>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
bool isNumeric(string aString)
{
double n;
istringstream is;
cin >> aString;
is.str(aString);
is >> n;
if (is.fail())
{
return false;
}
return true;
}
vector<double> limits(vector<double> a)
{
// Returns [min, max] of an array of numbers; has
// to be done using std::vectors since functions
// cannot return arrays.
vector<double> res;
double mn = a[0];
double mx = a[0];
for (unsigned int i = 0; i < a.size(); ++i)
{
if (mn > a[i])
{
mn = a[i];
}
if (mx < a[i])
{
mx = a[i];
}
}
res.push_back(mn);
res.push_back(mx);
return res;
}
int main()
{
string line = " ";
vector<string> lines;
vector<double> arr;
cout << "Enter your numbers: " << endl;
while (!line.empty() && isNumeric(line))
{
getline(cin >> ws, line);
if (line.empty() || !isNumeric(line))
{
break;
}
lines.push_back(line);
transform(line.begin(), line.end(), line.begin(), [](char32_t ch) {
return (ch == ' ' ? '\000' : ch);
}); // Remove all spaces
arr.push_back(atof(line.c_str()));
}
vector<double> l = limits(arr);
cout << "\nMinimum: " << l[0] << "\nMaximum: " << l[1] << endl;
return 0;
}
The above code is what I have. However, it's not always outputting the correct maximum value and only outputs "0" for the minimum value. I can't seem to find what's wrong with this so if anyone could help that would be great.
For the minimum, your problem appears to be with the fact that in your limits() function, you initialize the value of min to 0. So if you have an array of [1, 2, 3, 4], it will check each element and, seeing that none of them is less than 0, leave 0 as the minimum. To fix this, you can set the initial value of mn to the first element of the array. Note that you will have to check to make sure the array has at least one element to avoid a possible overflow error.
For the maximum, I'm not sure what kind of inconsistencies you're having, but if your array only contained negative values, you would have the same problem as with minimum, where the initial value is higher than any of the actual values.

C++ Calling - search function

I was wondering how I could finish up this program. It's to perform a linear search on a list "ll" (which length is 31) for the user inputted item it, returning the user inputted numbers and their locations if they're found.
Problem: I'm not sure how to call the functions in this specific scenario, I don't really need to use pointers or pass a value, so the lack of these actually makes it more confusing for me, as those are fairly common scenarios.
#include <iostream> //enables usage of cin and cout
#include <cstring>
using namespace std;
int search (int i, int it, int ll, int z);
int printit (int i, int it, int ll, int z);
int main ()
{
int i,it,z;
int ll[] = {2,3,4,5,6,2,3,44,5,3,5,3,4,7,8,99,6,5,7,56,5,66,44,34,23,11,32,54,664,432,111}; //array hardwired with numbers
//call to search
return 0;
}
int search (int i, int it, int ll, int z)
{
cout << "Enter the item you want to find: "; //user query
cin >> it; //"scan"
for(i=0;i<31;i++) //search
{
if(it==ll[i])
{
//call to printit
}
}
return 0;
}
int printit (int i, int it, int ll, int z)
{
cout << "Item is found at location " << i+1 << endl;
return 0;
}
There is a problem with each of the parameters to search:
i's passed value gets overwritten before it gets used, and thus should be a local variable
Same thing for it
ll should be an array of ints
z isn't used at all
Things are even worse for printit: 3 of the 4 parameters are ignored.
Search and print don't need to return int, if you have already print out the results. Also some declared variables are useless. The following code would work:
#include <iostream> //enables usage of cin and cout
#include <cstring>
using namespace std;
void search (int ll[]);
void printit (int n);
int main ()
{
// int i,it,z;
int ll[] = {2,3,4,5,6,2,3,44,5,3,5,3,4,7,8,99,6,5,7,56,5,66,44,34,23,11,32,54,664,432,111}; //array hardwired with numbers
//call to search
search(ll);
return 0;
}
void search (int ll[])
{
cout << "Enter the item you want to find: "; //user query
cin >> it; //"scan"
for(i=0;i<31;i++) //search
{
if(it==ll[i])
{
//call to printit
printit(i);
}
}
// return 0;
}
void printit (int n)
{
cout << "Item is found at location " << n+1 << endl;
// return 0;
}

Enter standard input for values of map

I'm trying to write a map that takes in an integer as the key and then an x amount of int values that are given to it via standard input. This is my first time working with maps so I'm running into several issues and was wondering if someone could help understand better what I am doing incorrectly. Normally with a vector/array the following would work fine:
int standardInput;
for (int i = 1; i<=n; i++){
cin standardInput;
array[i] = standardInput;
}
I can't get that to work similarly when using a map:
int numberToCompare = 4;
map<int numberToCompare, int>myMap;
int standardInput;
cout << "Enter numbers: " << endl;
for (int i = 1; i <= n; i++){
cin standardInput;
myMap.insert(standardInput);
}
I'm still trying to understand about the key and values. The way I understood when reading about maps was that with a map the key is unique unlike multi maps. What I don't know how to do is allow user input to fill the rest of the map. I saw lots of examples online where inside the code people manually entered all of the input doing the following (this goes against what I want to accomplish).
portMap_.insert(pair<string,int>("fourth", 4444));
portMap_.insert(pair<string,int>("fifth", 5555));
EDIT: To clarify in case I caused some confusion, I'm trying to fill a map with numbers that are given via standard input.
I would recommend you browse the documentation for std::map found here. Then take a look at the examples provided in the insert() method documentation here.
The declare a map object, you need to specify the type for the key and the type for the value by providing the type name as template parameters:
#include <map>
using namespace std;
map<int,int> myMap;
If you then want to insert a key/value pair:
int myKey = 10;
int myVal = 100;
myMap.insert(pair<int,int>(myKey, myVal));
The above can be made a bit more terse with some typedefs:
typedef map<int,int> IntMap;
typedef pair<int,int> IntPair;
IntMap myMap;
myMap.insert(IntPair(10, 100));
If you want the key/value pairs to be provided by user input, just write a simple loop that accepts the values from standard input and insert the values into your map.
There are plenty of resources here for reading values from standard input. Something like the below would do the trick:
// pseudo-code
while (did the user quit?)
{
int key = 0;
int value = 0;
cin >> key >> value;
// maybe if the user enters -1, then you quit, otherwise:
myMap.insert(pair<int,int>(key, value));
}
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d", &n);
map<int, string> m;
for(int i = 1; i <= n; i++) {
string s = "abracadabra";
m.insert(pair<int, string>(i, s));
}
for(auto it = m.begin(); it != m.end(); it++) {
cout << it->first << " " << it->second <<"\n";
}
}
This works fine.
Problem:write a map that takes in an integer as the key and then an x amount of int values that are given to it via standard input
Solution Here i provided the code which will take the std input and store it to the MAP,
enter code here
`#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
int main()
{
int n;
int key;
long x;
cin >> n;//std input for number of entries in to MAP
map <int, long> map_book;
for (int i = 0; i < n; i++) {
cin >> x;//std input for VALUE
cin >> key;//std input for KEY
map_book[key] = x;
}
//here am searching the x and pinting if it is there in MAP or Else priniting it is not found
while(cin >> x) {
if (map_book.find(x) != map_book.end()) {
cout << x << "=" << map_book.find(x)->second << endl;
} else {
cout << "Not found" << endl;
}
}
return 0;
}`
This can be helpful.
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<char,int>mp;
char a;
int b,n;
cin>>n;
for(int i = 0; i<n; i++){
cin>>a>>b;
mp.insert(pair<char,int>(a,b));
}
cout<<endl;
for(auto&x:mp)
{
cout<<x.first<<" "<<x.second<<endl;
}
return 0;
}
output:
3
a 1
b 2
c 3
a 1
b 2
c 3
#include <iostream>
#include <map>
int main ()
{
std::map<char,int> first;
first['x']=8;
first['y']=16;
first['z']=32;
for(map<char,int>::iterator it = first.begin(); it != first.end(); ++it) {
cout << it->first <<" "<< it->second<<endl;
}
return 0;
}

C++ Two n sized integer lists

I'm new to C++ and I need some help creating this program:
I need to ask for the size of the list, then take the list containing integers and then ask the size of the second list and take those integers.
So far I have this:
#include <iostream>
using namespace std;
int main()
{
long int ARR[10];
int i,n;
printf("List 1 size: ");
scanf("%d",&n);
printf("List 1 data: ");
for(i=0;i<n;i++)
{
scanf("%ld",&ARR[i]);
}
So that will take the input for the first list. Now I will repeat this for the second list.
But the key point is I now need to compare the two lists. If list1 is in list2 then I say yay, or if not then nay.
How do I go about comparing these two lists? And I am I on the right track with the input?
Thanks,
EmptyPeace
I think that's what you expected.
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
bool mypredicate (int i, int j) {
return (i==j);
}
int main(){
int size_list = 0;
vector<int> list1, list2;
cin >> size_list;
list1.resize(size_list);
list2.resize(size_list);
cout << list1.size() << endl;
for (int i = 0; i < size_list; i++)
cin >> list1[i];
for (int i = 0; i < size_list; i++)
cin >> list2[i];
pair<vector<int>::iterator,vector<int>::iterator> mypair;
mypair = mismatch (list1.begin(), list1.end(), list2.begin(), mypredicate);
if( mypair.first == list1.end() && mypair.second == list2.end() )
cout << "are equals" << endl;
else{
cout << "aren't " << endl;
cout << *mypair.first << ", " << *mypair.second << endl;
}
system("pause");
return 0;
}
I think you should use either dynamic array or stl's vector to store data.
for example, dyn. array:
int size;
scanf("%d", size);
int *tab = new int[size];
...
delete[] tab;
or vector way:
#include <vector>
...
int size;
scanf("%d", size);
vector <int> tab(size);
// to insert an element, use tab.push_back( number );
// and getting an element goes array-way, for example tab[0];
And some words from me- if you are writing in c++, use cin and cout for input/output, unless you need extra speed or specific format. And remember, that list is something different than array/vector.