Why is binary_search not working as expected? [duplicate] - c++

This question already has answers here:
Can we use binary search with an unsorted array? [duplicate]
(3 answers)
What happens if a binary search on a non-sorted data set is attempted? [closed]
(4 answers)
Closed last year.
The question is to find the index of first element in the array that repeats itself atleast once in the array.
Input:
7
1 3 4 5 3 7 2
#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
int a[n], curr = -1;
int num = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
{
int x = a[i];
a[i] = -1;
if (binary_search(a, a + num, x))
{
curr = i;
cout << curr << endl;
break;
}
}
cout << curr + 1;
return 0;
}
Expected Output:
2
(As 3 is the first element to appear twice in the array)
Output received:
0

cin >> n;
int a[n]
This isn't allowed in C++. The size of an array variable must be compile time constant. n is not compile time constant. To create an array of runtime length, you must allocate it dynamically. Simplest solution is to use std::vector,
int num = sizeof(a) / sizeof(a[0]);
Use std::size(a) to get the size of an array instead. However, in this case, just use n.
binary_search(a, a + num, x)
The input range must be partially sorted in order to use std::binary_search with respect of the searched number. Since you use potentially all elements as the searched number, this effectively means that the array must be fully sorted.
Input:
7
1 3 4 5 3 7 2
Your input array is not fully sorted. As result of violating the pre-condition, the behaviour of the program is undefined.

Related

Output numbers in reverse (C++) w/ vectors

I'm stuck for the first time on a lab for this class. Please help!
The prompt is:
Write a program that reads a list of integers, and outputs those integers in reverse. The input begins with an integer indicating the number of integers that follow. For coding simplicity, follow each output integer by a comma, including the last one.
Ex: If the input is:
5 2 4 6 8 10
the output is:
10,8,6,4,2,
2 questions: (1) Why does the vector not take user input unless the const int is included? (2) Why does the code not work in general? It seems to properly output, but with an error, and does not include the end line?
#include <iostream>
#include <vector>
using namespace std;
int main() {
const int MAX_ELEMENTS = 20;
vector<int> userInts(MAX_ELEMENTS);
unsigned int i;
int numInts;
cin >> numInts;
for (i = 0; i < numInts; ++i) {
cin >> userInts.at(i);
}
for (i = (numInts - 1); i >= 0; --i) {
cout << userInts.at(i) << ",";
}
cout << endl;
return 0;
}
Firstly, you need to specify the size because you are not using the vector's push_back functionality. Since you are only using at, you must specify the size ahead of time. Now, there's a few ways to do this.
Example 1:
cin >> numInts;
vector<int> userInts(numInts); // set the size AFTER the user specifies it
for (i = 0; i < numInts; ++i) {
cin >> userInts.at(i);
}
Alternatively, using push_back you can do:
vector<int> userInts; // set the size AFTER the user specifies it
for (i = 0; i < numInts; ++i) {
int t;
cin >> t;
userInts.push_back(t);
}
As for looping backwards, i >= 0 will always be true for unsigned numbers. Instead, you can use iterators.
for ( auto itr = userInts.rbegin(); itr != userInts.rend(); ++itr ) {
cout << *itr;
}
If you need to use indexes for the reverse loop, you can do:
for ( i = numInts - 1; i != ~0; --i ) { // ~0 means "not 0", and is the maximum value, I believe this requires c++17 or 20 though
cout << userInts.at(i);
}
with unsigned int i; the condition i >= 0 is always true. Eventually you will access an out-of-range element, which will throw std::out_of_range.
To answer your other question
std::vector userInts;
create a vector with no entries
userInts.at(i)
tries to access the (non existnat) ith entry.
You have 2 choices
create vector with a lot of empty etries
ask the vector to dynamically grow
The first one is what you did
const int MAX_ELEMENTS = 20;
vector<int> userInts(MAX_ELEMENTS);
Or you can do
userInts.push_back(x);
this will make sure there is enough space in the vector and add the new element to the end.

How to split a number into digits in C++ [duplicate]

This question already has answers here:
Converting integer into array of digits [closed]
(4 answers)
Closed 2 years ago.
I know there are similar questions on Stack overflow about this. I already checked them. Here are two points:
The number will be an input from the user, so I won't know how many digits the number may actually contain
I DON'T want to directly print the digits, I need to do some further process on every digit, so I need a way to save or assign every single digit.
So fore example, if the user enters 1027, I'll need 1, 0, 2, 7 returned, and not printed. That's where my problem starts.
Here's how I'd write it if it could be printed:
int x;
cin>>x;
while(x != 0)
{
cout<<x%10<<endl;
x/=10;
}
Any hints or help is in advance appreciated.
It depends what order you need it in. If you need least-significant digit (rightmost) to most-significant (leftmost), then your solution is almost there
int x = ...
while(x != 0)
{
int current = x % 10; // get rightmost digit
x /= 10;
// process 'current', or store in a container for later processing
}
If you need most-significant (leftmost) to least-significant (rightmost), then you can do this recursively:
void for_each_digit(int input)
{
// recursive base case
if (input == 0) { return; };
int current = input % 10
for_each_digit(input / 10); // recurse *first*, then process
// process 'current', add to container, etc
}
// ...
int x = ...
for_each_digit(x);
Edit: I apparently missed the part about returning a sequence of digits.
Either approach works. If you go right-to-left, you will need to reverse the container first. If you go recursive, you will need to append each value to the container.
Use a std::string:
std::string input;
std::cin >> input;
Now input[i] is the i-th digit. input.size() is the number of digits.
Well you can use vector. It can take variable length input. You need not declare the size beforehand. Learn more about vector here: vector
#include<iostream>
#include<vector>
#include <algorithm> // std::reverse
using namespace std;
int main(void)
{
vector<int>digits;
int x;
cin >> x;
while(x)
{
digits.push_back(x % 10);
x = x / 10;
}
// reversing the order of the elements inside vector "digits" as they are collected from last to first and we want them from first to last.
reverse(digits.begin(), digits.end());
// Now the vector "digits" contains the digits of the given number. You can access the elements of a vector using their indices in the same way you access the elements of an array.
for(int i = 0; i < digits.size(); i++) cout << digits[i] << " ";
return 0;
}
You may try std::vector<int> to store unknown number of integers as shown:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> digits;
std::string s;
std::cout << "Enter the number: ";
std::cin >> s;
size_t len = s.length();
for (size_t i = 0; i < len; i++) {
digits.push_back(s[i] - '0');
}
// Comment next 3 code to stop getting output
for (size_t i = 0; i < len; i++)
std::cout << digits[i] << ' ';
std::cout << std::endl;
return 0;
}
Note: This approach doesn't performs any mathematical operations (i.e. operation of division and getting remainders). It simply stores each integer in a vector using a for loop.

What are all of these numbers following the expected output?

I was trying to write a program to take an input and output the reverse of that input; here was my code:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int num[n];
for (int i=1; i<=n; i++)
{
cin >> num[i];
}
for (int i=n; i>=0; i--)
{
cout << num[i] << " ";
}
return 0;
}
I realized that in the second for loop, i can equal 0 and then i equals -1. However, the outputs don't really make sense. For example, an input of
6
8 1 2 6 3 9
results in
9 3 6 2 1 8 8 8
and a lot of the time it's just the array reversed but with an 8 added onto the end, but sometimes there are these types of numbers:
9
1 0 2 8 1 4 2 9 8
8 9 2 4 1 8 2 0 1 1703936
Where do these ending numbers come from? Because I don't understand what's going on, I can't generalize what the problem is, but if you have an easily-accessible IDE nearby and will copy and paste my code (assuming it's not a well-known problem and I'm making everyone laugh at my stupidity), could anyone tell me why there are these numbers added onto the end?
for (int i=1; i<=n; i++)
In C++, array indexes are 0-indexed. This means if your array is size n, the valid indexes are 0, 1, 2, ..., n-1.
Your loop will loop over 1, 2, 3, ..., n. Do you see the issue? You never write to the 0'th index, and you write one past the last index (which is not allowed).
Then when you go to print:
for (int i=n; i>=0; i--)
You print n, n-1, n-2, ..., 0. You're printing the n'th element, which is again, not allowed.
Instead, your loops should look like:
for (int i=0; i<n; i++)
{
cin >> num[i];
}
for (int i = 0; i < n; i++)
{
cout << num[n - i - 1] << " ";
}
Your second loop begins with i equal to n ... but that's not a valid array index, because an array containing n elements has indexes [0..n-1]! Therefore, you are seeing "memory garbage."
So, your second loop should be:
for (int i=n-1; i>=0; i--)
You seem to think that arrays are indexed from 1 which is your main issue.
for (int i=1; i<=n; i++)
The last element of an array if length-1, so if you had 3 elements the last index is 2, not 3; however, the loop above starts at 1 (the second element) and then accesses an index out of bounds, which is undefined behaviour.
But really you don't need to use indices at all, just for (auto& i : n) will iterate properly over your container. If you want to loop using indices, you need
for (int i = 0; i < n; i++) // forwards
for (int i = n-1; i >= 0; i--) //backwards
It's worth noting that variable length arrays (that is, arrays whose lengths are not known at compile time) are not standard C++, but are an extension of GCC. It would be worth ditching that behaviour now, and using vector instead:
int length = 0;
std::cin >> length;
std::vector<int> n(length);

I am unable to assign difference of two elements of 2 dimensional array to element of other array in C++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Below is the code, which is breaking my head since two days.
#include <iostream>
using namespace std;
int main()
{
int N;
int A[1][N-1];
int B[1][N-1];
std::cout << "ENTER NO OF ROUND" << '\n';
std::cin >> N;
for (int j=0; j<N; j++)
{
int i =0;
std::cout << "enter the scores" << '\n';
std::cin >> A[i][j]>>A[i+1][j];
if (A[i][j] > A[i+1][j])
{
B[i][j] = A[i][j] - A[i+1][j];
B[i+1][j] = 1;
}
if (A[i][j] < A[i+1][j])
{
B[i][j] = A[i+1][j] - A[i][j];
B[i+1][j] = 2;
}
}
std::cout << A[0][0]<<A[1][0] << '\n';
return 0;
}
Here in line 18 line 19 and line23 line24i should get difference of two elements of array A[1][N-1] Which is then assigned to a element in array B[1][N-1],but am unable get the correct result ,rather am getting a random number.
help me getting through this
You use uninitialized data, so anything can happen.
You declare the N variable:
int N;
And then, in the very next line, without assigning any value, you use it to create two arrays using N as a size:
int A[1][N-1];
int B[1][N-1];
This already is a starting point for disaster. Moreover, declaring an array with size [N - 1] is not technically correct - N is a variable, so cannot be used to declare array in this manner. It's a compiler extension (are you using Visual Studio?). If value of N is known, declare it as:
static constexpr size_t N = value;
If it is read at runtime, create your arrays with new or, much better, use std::vector to make your code robust and less error-prone.
The second thing is, that A array is declared as int A[1][N-1];, but you do the following:
int i = 0;
....
if (A[i][j] > A[i+1][j])
Which results in reading A[1][j], which does not exist - in C++ we start indexing from 0! You also modify those non-existing elements:
std::cin >> A[i][j] >> A[i+1][j];
which most likely will result in writing to memory that belongs to B array.
Small notes:
using namespace std seems redundant, as you write std:: everywhere
what is the point of two-dimensional array [M][N] if M = 1?
Use std::vectors if you need arrays with size determined at run-time. The C Variable-length arrays you use are not supported in C++.
std::cout << "ENTER NO OF ROUND" << '\n';
int N = 0;
std::cin >> N;
std::vector<std::vector<int>> A(2, std::vector<int>(N));
std::vector<std::vector<int>> B(2, std::vector<int>(N));
And note that you need 2 x N array because you read both A[i][j] and A[i+1][j] and your for loop is from [0 to N-1] -- N times.

Array overflow c++ (at arr[0])?

Ok so last night I taught my sister some basic code how to read input, put it in array and print it to the screen. Here is the code :
int main() {
int N; // size of array
cin >> N;
int arr[N];
for(int i = 1; i<= N; i++) {
cin >> arr[i];
}
for(int i = 0; i<N; i++) {
cout << arr[i] << endl;
}
return 0;
}
And here is the result :
input :
4
2 3 4 1
output :
8
2
3
4
I don't have any clues why this can happen, I tried to check the code but it seems simple and already correct for me.
First of all C++ does not support variable length arrays and if an array is declared as having N elements then the valid range of indices is [0, N-1].
You could either dynamically allocate an array of the required size yourself or use standard container std::vector<int>.
Using std::vector<int> you could for example write
#include <iostream>
#include <vector>
int main()
{
unsigned int n = 0;
std::cout << "Enter number of elements: ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
for ( int &x : v ) std::cin >> x;
std::cout << "\nThe array is ";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
The program output might look like
Enter number of elements: 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array is 0 1 2 3 4 5 6 7 8 9
The first thing you have to look after is that dasblinkenlight has already mentioned in his answer, variable-length arrays are a language extension.
Then you should think that arrays are zero index based. What does this means? Let's consider an array of size 4 that is denoted as arr. Then it's elements can be accessed as arr[0], arr[1], arr[2], and arr[3]. So what happens when you run your first loop?
for(int i = 1; i<= N; i++) {
cin >> arr[i];
}
You set the a value for arr[1], arr[2] to arr[N]. But the arr[N] points to a place in memory that is not associated with the array, since the array's size is N and all arrays are zero based. The last element of the array lives in here arr[n-1].
Unfortunately in C++ there isn't any check for the length of an array and you are allowed to do things like this. For instance, if you had tried this in C# or in Java then you would have got an Index Out Of Range Exception.
If you change your code to the following, then you will get the expected output:
for(int i = 0; i<N; i++) {
cin >> arr[i];
}
for(int i = 0; i<N; i++) {
cout << arr[i] << endl;
}
Your code is not valid C++, because variable-length arrays are a language extension.
With that part out of our way, consider what happens in your first loop's last step: you are accessing an element past the end of the array, which is undefined behavior.
Your second loop is correct, though, so all you need to do is correcting the header of the first loop to match the header of the second loop.
An array of N elements has indexes from 0 to N-1 (so: N-1 - 0 + 1 = N elements, some maths.)
So fix this: for(int i = 1; i<= N; i++) with this : for(int i = 1; i< N; i++)