I'm trying to write a program that creates and fills a vector with int values, then searches through it and returns the minimum value, recursively. I have the code written out and building, but it returns a weirdly large value for minimum every time- I have a feeling it's not properly assigning the smallest value to int minimum, but I'm not sure. Any thoughts?
#include <iostream>
#include <conio.h>
#include <vector>
using namespace std;
int vectorSize;
int minimum;
int result = -1;
int start;
int ending;
int answer;
int test;
int recursiveMinimum(vector<int>, int, int);
void main() {
cout << "How many values do you want your vector to be? ";
cin >> vectorSize;
cout << endl;
vector<int> searchVector(vectorSize);
start = 0;
ending = searchVector.size() - 1;
for (int i = 0; i < vectorSize; i++) {
cout << "Enter value for position " << i << " " << endl;
cin >> searchVector[i];
}
for (int x = 0; x < vectorSize; x++) {
cout << searchVector[x] << " ";
}
int answer = recursiveMinimum(searchVector, start, ending);
cout << "The smallest value in the vector is: " << answer;
_getch();
}
int recursiveMinimum(vector<int> searchVector, int start, int end) {
if (start < end) {
if (searchVector[start] < minimum) {
minimum = searchVector[start]; //this part seems to not work
}
start++;
recursiveMinimum(searchVector, start, end);
}
else {
return minimum;
}
}
`
Your minimum variable is not initialised, which leads to undefined behaviour. It should be set to the first value in the vector:
minimum = searchVector[0];
int answer = recursiveMinimum(searchVector, start, ending);
Additionally, ending is off by one, which makes it pick 6 as the smallest value out of [6, 9, 8, 4].
So, ultimately, your code should look like this:
minimum = searchVector[0];
int answer = recursiveMinimum(searchVector, start, ending + 1); // note the + 1
While irrelevant to the question, I advise you to use a tail call in recursiveMinimum, as explained here:
start++;
return recursiveMinimum(searchVector, start, end);
The main issue is that you do not initialise minimum. Hence, comparison searchVector[start] < minimum might never become true, and minimum remains uninitialized.
As a quick fix, write int minimum = MAX_INT; instead of int minimum;. MAX_INT is the maximum positive integer value (defined in limits.h). So the values in your array will never be greater that this value, and your minimum search loop will work (unless there are other issues; but for that, please consult the debugger :-) )
Related
i have to return the max len of consecutive seq present in an array.
consider the example:-
N = 7
a[] = {2,6,1,9,4,5,3}
my code should return 6 but its giving 1. don't know how?
int findLongestConseqSubseq(int arr[], int N)
{
//Your code here
unordered_map<int,int> mp;
int ans=0;
for(int i=0;i<N;i++){
if(mp.count(arr[i])>0){
continue;
}
int len1=mp[arr[i]-1];
int len2=mp[arr[i]+1];
int ns=len1+len2+1;
ans=max(ans,ns);
mp[arr[i]-len1]=ns;
mp[arr[i]+len2]=ns;
// ans=max(ans,ns);
}
return ans;
}
There are two problems with your implementation.
The first issue is the code:
if(mp.count(arr[i])>0){
continue;
}
this code is not sufficient to ensure that repeated numbers do not make it into the rest of your loop (to see why this is, consider what happens with neither len1 or len2 are zero).
You can replace it with something like:
if(!mp.insert(pair<int,int>(arr[i], 1)).second) {
continue;
}
This will skip the rest of the loop if an entry for arr[i] exists, but also ensures that an entry will exist after the if expression is evaluated.
The second issue is with the code:
int len1=mp[arr[i]-1];
int len2=mp[arr[i]+1];
the subscript operator for maps in C++ has a side-effect of creating an entry if one does not exist. This is problematic for your algorithm because you do not want this to happen. If it did it would cause the previous piece of code to skip numbers it shouldn't. The solution is to use find but since the code for this is a little ugly (IMHO) it's probably neater to write a helper function:
inline int findOrDefault(const unordered_map<int, int>& map, int key, int defaultValue) {
auto find = map.find(key);
return (find == map.end()) ? defaultValue : find->second;
}
and use this to update your code to:
int len1=findOrDefault(mp, arr[i]-1, 0);
int len2=findOrDefault(mp, arr[i]+1, 0);
Putting this all together you end up with:
inline int findOrDefault(const unordered_map<int, int>& map, int key, int defaultValue) {
auto find = map.find(key);
return (find == map.end()) ? defaultValue : find->second;
}
int findLongestConseqSubseq(int arr[], int N)
{
unordered_map<int,int> mp;
int ans=0;
for(int i=0;i<N;i++){
if(!mp.insert(pair<int,int>(arr[i], 1)).second) {
continue;
}
int len1=findOrDefault(mp, arr[i]-1, 0);
int len2=findOrDefault(mp, arr[i]+1, 0);
int ns=len1+len2+1;
ans=max(ans,ns);
mp[arr[i]-len1]=ns;
mp[arr[i]+len2]=ns;
}
return ans;
}
Ok had a moment to look at this again and I came up with this. First we sort the array to make things easier. Then we can go through the numbers with one pass, counting each time the next consecutive number is greater by one. If the next number is not one greater after sorting, then we reset and start counting again, storing the highest streak count in max.
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
cout << "Get Longest Consecutive Streak: " << endl;
int intArray[] = { 9, 1, 2, 3, 4, 6, 8, 11, 12, 13, 14, 15 ,16 };
int arrayLength = size(intArray);
sort(intArray, intArray + arrayLength); //Sort Array passing in array twice plus amount of indexes in array
cout << "Sorted Array looks like this:" << endl; //Outputting sorted array to check
for (int i = 0; i < arrayLength; i++) {
cout << intArray[i] << " ";
}
cout << endl;
int count = 1;
int max = 1;
/*
* Loop through array, if the next number is one greater than current then add to count
* If it is not, reset the count.
* Store highest count value found passing through.
* */
for (int i = 0; i < arrayLength -1; i++) {
if (intArray[i + 1] == intArray[i] + 1) { //checking next value - is it equal to this one + 1?
count++;
}
else { //else if it is not, store the value if it is higher that what is currently there, then reset
if (max < count) {
max = count;
}
count = 1;
}
}
//Edge case: check again one more time if the current count (when finishing) is greater than any previous
if (max < count) {
max = count;
}
cout << "Longest Consecutive Streak:" << endl;
cout << max << endl;
return 0;
}
I want to find the highest value from an array using two given pointer int *p,*max;, but the code doesn't work.
#include <iostream>
#include <string>
using namespace std;
int main() {
int a[10], i, index;
int *p, *max;
for (i = 0; i < 10; i++) cin >> a[i];
max = 0;
p = &a[10];
for (index = 0; index < 10; index++) {
if ((p[index]) > *max) {
*max = (p[index]);
}
}
cout << "Highest value=" << *max << endl << "is at index=" << index << endl;
return 0;
}
The code is buggy. First of all, you assign
p=&a[10];
This assigns p to a memory address past a. Furthermore, you then index as p[index], which essentially is the same as a[10 + index].
Also, max is a wild pointer. It does not point to anything. You are assigning values to an undefined memory location.
I would strongly suggest to read up on pointers and to properly understand them before using them. Also, in modern C++, it is not very often than you need pointers.
Also, in idiomatic C++, we would probably write
auto p = std::max_element(a, a + 10);
There are several problems.
First, p should point to the array's first element, so you should have p = &a[0].
You can also rely on implicit conversion and just write p = a;, which is exactly the same.
&a[10] is the pointer "one-past-the-end" of the array, and dereferencing it is undefined.
Next, you want max to point to the maximum element.
It should also start at the beginning of the array, like p.
Then, when you find a new maximum, you should make max point to that element, not change the value max points to.
Lastly, index will always be 10 after the search loop.
(Take a few moments to think about why.)
You don't need it – the index is the difference between the location of the maximum element and the beginning of the array.
int main()
{
int a[10];
for(int i = 0; i < 10; i++)
cin >> a[i];
int* max = &a[0];
int* p = &a[0];
for (int index = 0; index < 10; index++){
if (p[index] > *max){
max = &p[index];
}
}
cout << "Highest value= " << *max << endl << "is at index= "<< max - a << endl;
}
I'd remove p and use a range-based for-loop where possible and iterators when it'll improve performance.
Comments in the code:
#include <iostream>
#include <iterator>
// using namespace std; // don't do this
int main() {
using std::cin, std::cout;
int a[10];
// use a range-based for-loop:
for(int& aref : a) { // aref is a reference to the current element in a
// check that extraction from std::cin actually works
if(!(cin >> aref)) {
std::cerr << "error reading int\n";
return 1;
}
}
// initialize max to point at the first element
auto max = std::begin(a);
// Start at the second element since max is already set to point at the first element.
// Don't use magic numbers. Define a constant or use std::size(<array>)
// ...or use iterators like in this example:
for(auto curr = std::next(std::begin(a)); curr != std::end(a); ++curr) {
if(*curr > *max) {
max = curr;
}
}
// you can use std::distance ot calculate the index for max:
cout << "Highest value=" << *max << '\n'
<< "is at index=" << std::distance(std::begin(a), max) << '\n';
}
The solution to this problem is recognizing that max should always point to the maximum item seen in the array a so far so instead of initializing max to 0 you start by initializing it to point to the first item in a which is &a[0] or just a.
I tried to make the least amount of changes to the original code:
#include <iostream>
#include<string>
using namespace std;
int main()
{
int a[10],i,index;
int *p,*max;
for(i=0;i<10;i++)
cin>>a[i];
max=a; // Initialize max to point to the first item in a
p=a;
for(index=0;index<10;index++){
if((p[index])>*max){
max=(&p[index]); // Now make max point to the new maximum item
}
}
cout<<"Highest value="<<*max<<endl<<"is at index="<<max - p<<endl;
return 0;
}
Here is the code in ideone:
https://ideone.com/BwE45C
As mentioned in the comments below p probably is not being used as the question expects so I have rewritten the code to iterate using p
#include <iostream>
#include<string>
using namespace std;
int main()
{
int a[10],i,index;
int *max;
for(i=0;i<10;i++)
cin>>a[i];
max=a;
for(int* p=a;p<a+10;p++){ // p is now a pointer that is used to iterate through the array
if(*p>*max){
max=p; // max points to the new maximum
}
}
cout<<"Highest value="<<*max<<endl<<"is at index="<<max - a<<endl;
return 0;
}
The new ideone link for this is here: https://ideone.com/bk3zoS
There is a task. It is necessary in a one-dimensional array of N real numbers to calculate the number of the maximum modulo element among unpaired numbers.
I wrote the code, but it does not work. I can’t understand what’s wrong with him.
#include <iostream>
#include <math.h>
using namespace std;
int main() {
setlocale(0, "");
const int KolEl = 5;
int mas[KolEl];
int max = abs(mas[0]);
int result;
for (int i = 0; i < KolEl; i++)
{
cout << " Введите елемент[" << i << "] = ";
cin >> mas[i];
if (mas[i] % 2 == 1) {
if (abs(mas[i]) > max) {
result = i;
cout << result << endl;
}
}
}
system("pause");
}
You initialize max as:
int mas[KolEl];
int max = abs(mas[0]);
However, the values in mas[] are garbage values (read: undefined behavior). So now the value in max is also UB.
You then go on to use that value to compare to the input you take:
if (abs(mas[i]) > max) {
So the result of that comparison is undefined.
You probably meant to declare max as something like:
int max = INT_MIN;
So that the first comparison will always be true (every int except INT_MIN will be greater than it).
I am writing a simple code to calculate Fabonacci numbers as an exercise. The code works, but i don't get why. I have some special cases for n=1 and n=2 which is the place of the number in the sequence (the numbers are 0 and 1). However after those, the number is calculated in this loop.
while(n>LoopCount)
{
Fib_n=Fib_1+Fib_2;
Fib_2=Fib_1;
Fib_1=Fib_n;
LoopCount++;
}
Going in to the loop, Fib_1=0, Fib_2=0, and Fib_n=1. Why does not this loop just spit out 0 no matter what? The whole code is below.
#include <iostream>
using namespace std;
int main()
{
cout <<"Which number of the Fibonacci sequence do you want to calculate?" <<endl;
int n;
cin >>n;
cout <<endl;
int Fib_n;
int Fib_1;
int Fib_2;
int LoopCount=1;
if(n>1)
{
Fib_n=1;
LoopCount++;
while(n>LoopCount)
{
Fib_n=Fib_1+Fib_2;
Fib_2=Fib_1;
Fib_1=Fib_n;
LoopCount++;
}
}
cout <<Fib_n;
return 0;
}
int Fib_1;
int Fib_2;
were never initialized. Therefore, the first time you calculate Fib_n=Fib_1+Fib_2;, Fib_n will get the sum of two uninitialized variables.
I have modified your code so it would work.
#include <iostream>
using namespace std;
int main()
{
cout <<"Which number of the Fibonacci sequence do you want to calculate?" <<endl;
int n;
cin >> n;
cout << endl;
int Fib_1 = 1;
int Fib_2 = 1;
int count = 0;
while(n > count)
{
Fib_1 = Fib_1 + Fib_2;
Fib_2 = Fib_1 - Fib_2;
count++;
}
cout << Fib_1;
return 0;
}
Fib_1
You have that as an uninitalized variable, so you may get a garbage value for output.
Fib_2 = Fib_1
Next, you initialize Fib_2 with Fib_1, meaning they both share the same (random) value.
In debug mode, these are both initialized to 0, and adding them:
Fib_n=Fib_1+Fib_2;
makes the sum equal 0. In release mode, you can expect random values from the compiler. Here is more info on Uninitialized Variables.
So essentially the problem is that the findLowest function isn't doing what I had planned for it to do. I know it's a logic error but I can't seem to find out why the variables aren't updating. They always default to the values they are instantiated with.
#include <stdafx.h>
#include <string>
#include <iostream>
using namespace std;
//Function prototypes
void findLowest(int regAccidents[], int arraySize, string regNames[]);
int getNumAccidents(string);
const int NUM_REGIONS = 5;
int main(){
string regionNames[NUM_REGIONS] = { "North", "South", "East", "West", "Central" };
int regionAccidents[NUM_REGIONS];
for (int i = 0; i < NUM_REGIONS; i++){//Populates the accident array
regionAccidents[i] = getNumAccidents(regionNames[i]);
if (regionAccidents[i] < 0)//checks to see if there are any accidents counts lower than 0
regionAccidents[i] = 0;
}
findLowest(regionAccidents, NUM_REGIONS, regionNames);
}
int getNumAccidents(string region){//returns the accidents for a specific region to be assigned to the regionAccidents[] array in main()
int regionAccidents = 0;
cout << "How many accidents for " << region << "? ";
cin >> regionAccidents;
return regionAccidents;
}
void findLowest(int regAccidents[], int arraySize, string regNames[]){ //used to determine what the lowest number of accidents is
int lowest = regAccidents[0]; //once that is found, update the lowRegion string of the accident location
string lowRegion = regNames[0];
for (int i = 0; i < arraySize; i++){
if (regAccidents[i] < regAccidents[i++]){
lowest = regAccidents[i];
lowRegion = regNames[i];
}
}
cout << "The region with the lowest amount of accidents is: " << lowRegion << endl;
cout << "The lowest number of accidents is: " << lowest << endl;
}
if (regAccidents[i] < regAccidents[i++]) { ...
is dead wrong, you need to compare the current index to the lowest found so far:
if (regAccidents[i] < lowest) { ...
The expression regAccidents[i] < regAccidents[i++] will never be true because you're comparing the same items in the array. It will, however, increment i when you least expect it. Not that that actually matters here since it's a secondary problem totally hidden by your primary one :-)
Yes, you have logic errors in your code. The findLowest should look like the following:
int lowest = regAccidents[0];
string lowRegion = regNames[0];
for (int i = 1; i < arraySize; i++){
//^^you have initialized lowest as regAccidents[0], so search from 1
if (regAccidents[i] < lowest ){
//^^if current is smaller than lowest, update lowest and name
lowest = regAccidents[i];
lowRegion = regNames[i];
}
}
You did say anything about what your getting as an output now.
are you overrunning the array with this line's increment?
if (regAccidents[i] < regAccidents[i++])