weird things using std::vector [duplicate] - c++

This question already has answers here:
binary_search in c++ unexpected behaviour
(4 answers)
Closed 9 years ago.
I wrote a simple code to insert 2,4,8,16,32,3,9,27,5,6,7 into a vector object.
After insert these numbers, I check with std::binary_search for 8, but weirdly it returns 0.
Here is the code. I do not know why. Could someone help me?
Thanks a lot!
#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std;
void printVector(vector<int>const & p) {
for (int i = 0; i < p.size(); i++)
cout << p[i] << ' ';
cout << endl;
}
int main() {
const int max = 100;
int num;
vector<int> base;
for (int i = 2; i <= 7; i++) {
int expo = log(max) / log(i);
num = 1;
for (int iexp = 1; iexp < expo; iexp++) {
num *= i;
if (!binary_search(base.begin(), base.end(), num)) { // If the number is not in the vector
base.push_back(num); // Insert the number
printVector(base); // Reprint the vector
cout << endl;
}
}
}
cout << binary_search(base.begin(), base.end(), 8) << endl;
printVector(base);
return 0;
}

The sequence must be sorted for std::binary_search. Behavior is undefined if the sequence is not sorted.
You can use std::sort to sort it first, or, depending on what kind of performance you need, you can use std::find to do a linear search.

Binary search requires the vector be sorted. If you insert values in random order the results of the binary search will be unpredictable.

std::binary_search only works on sorted sequence. You need to sort the vector first.

Related

std::copy doesn't copy vector in C++

To find all sequences of fixed length which contain only 0 and 1 I use this code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void print_array(vector<string> arr) {
cout << '[';
int n = arr.size();
for (size_t i = 0; i < n; i++) {
cout << arr[i];
if (i < (n - 1)) {
cout << ", ";
}
}
cout << ']' << endl;
}
vector<string> get_variants(int n) {
vector<string> result = {"0", "1"};
vector<string> temp;
temp.reserve(2);
result.reserve(2);
for (int i=0; i < (n - 1); ++i) {
copy(result.begin(), result.end(), temp.end()); // [1]
for (int j=0; j < result.size(); ++j) {
temp[j] += "0";
result[j] += "1";
}
copy(temp.begin(),temp.end(), result.end());
temp.clear();
}
return result;
}
int main(int argc, char const *argv[]) {
int n;
cin >> n;
vector<string> maybe = get_variants(n);
print_array(maybe);
return 0;
}
But vector temp is empty, before copying in line which I marked [1] and after. So, my program's output was [0111, 1111]. What I'm doing wrong?
A more straightforward way than using std::copy is the use of .insert():
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
You are writing to temp.end() and result.end(). These iterators represent "one past the end", and therefore writing to these iterators is Undefined Behavior.
You seem to be looking for std::back_inserter. This will create an iterator that will insert a new element to your container when it is written through.
std::copy(result.begin(), result.end(), std::back_inserter(temp));
While this answers the posted question, there remain other errors in your code leading to Undefined Behavior.
Trying to compile your program with a C++ compiler will not work, because you include #include <bits/stdc++.h>which is a non tC++ standard compliant header.
You should never include this file.
You are using typical competitive programming stuff, but including all C++ headers and not use them will eat up Compile time for no good reason.
Then, you typedef the typical competitive programming abbreviations. 2 of them, you do not use. Then there is no reason to define them.
I recommend to not do this any longer. And in C++, please use the using statement.
Then, although you want to be fast, you pass arr by value to your print function. This will copy the whole vector.
You assign/compare a lot of int with unsigned int values. This you should not do.
Additionally: Please use meaningful variable names and write comments. The more the better.
Regarding your specific bug. Both std::copy statements use end iterator as target. End is end. It is past the end of the vector. Please use std::back_inserter instead.
Regarding the algorithm. I took a while for me to realize that you basically want to create binary numbers. Nothing else. Unfortunately you translated that in a very complicated way.
Normally, you just would count from 0 to 2^n-1 and then show the data. Thats all. Becuase the numbers may be of arbitraty length, we will use manual addition of digits like in scholl on a peice of paper. Very simple.
Everthing then biols down to some lines of code.
Please see:
#include <iostream>
#include <vector>
int main() {
// Read length of binary number to create and validate input
if (int numberOfDigits{}; (std::cin >> numberOfDigits and numberOfDigits > 0)) {
// Here we will store the binary digits, so 0s or 1s
std::vector<int> digits(numberOfDigits,0);
// Som printing helper
std::cout << '[';
bool printComma{};
// We need to print 2^n possible combinations
for (int i = 0; i < (1 << numberOfDigits); ++i) {
// Print comma, if need
if (printComma) std::cout << ','; printComma = true;
// Print all digits of the binary number
for (const int d : digits) std::cout << d;
// Calculate next binary number
int carry = 0;
for (int index=numberOfDigits -1; index >=0; --index) {
const int sum = digits[index] + ((index == (numberOfDigits - 1)?1:0)) + carry;
carry = sum / 2;
digits[index] = sum % 2;
}
}
std::cout << ']';
}
}
If there should be questions, then I am happy to answer.

getting N number from user and find the biggest [duplicate]

This question already has answers here:
How to find Maximum value from 5 inputs by user? [closed]
(4 answers)
Closed 2 years ago.
I'm writing my first code in c++.
I want recieve in N number from user and find the biggest one.
I just have learnt itteration,if statement...(no list)
Please give me some guidance
If you like to learn C++, I suggest you directly start using the standard library (stl), its containers (such as std::vector) and its algorithm (in this case std::max_element).
A range based loop is not as good as a proper algorithm, but still better than a hand crafted index based loop.
Please refer to the Book "A tour of C++" by Stroustrup. He summarizes how C++ is meant to be used now.
Here is the code:
#include <vector>
#include <limits>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> arr;
const int N = 10;
for (int i = 0; i<N; i++) {
int value;
std::cin >> value;
arr.push_back(value);
}
const auto max_algorithm = std::max_element(arr.begin(), arr.end());
std::cout << "Largest is: " << *max_algorithm << std::endl;
auto max_range_based_loop = std::numeric_limits<int>::lowest();
for (const auto& item : arr) {
max_range_based_loop = std::max(item, max_range_based_loop );
}
std::cout << "Largest is: " << max_range_based_loop << std::endl;
return 0;
}
Initialize int max = INT_MIN.
While taking user input in an array, check if each input element is greater than max,
If greater, update max value.
when loop terminates return max.
Example:
int main()
{
int N = 10; // N is array size
int arr[N]; // Array declaration
int max = INT_MIN;
for(int i=0; i<N; i++)
{
cin>>arr[i]; // user input
if(arr[i]>max) //check each element if it's greater than max
{
max = arr[i];
}
}
cout<<"Largest is: "<<max<<endl; // print max Or return it in a method
return 0;
}

Finding minimum and maximum in a array c++

I have to find the minimum and maximum value of elements in a array using divide and conquer. I have written a code but it is not working for more then 6 elements in array. I don't know whats the problem
#include<iostream>
using namespace std;
int minimum=999,maximum,mi,ma;
void result(int mi,int ma)
{
if(maximum<ma)
{
maximum=ma;
}
if(minimum>mi)
{
minimum=mi;
}
}
void maxmin(int arr[],int i,int j)
{
cout<<" i ="<<i<<" j= "<<j<<endl;
if(i==j)
{
mi=ma=arr[i];
result(mi,ma);
}
else if(i==j-1)
{
if(arr[i]>arr[j])
{
ma=arr[i];
mi=arr[j];
}
else
{
mi=arr[i];
ma=arr[j];
}
result(mi,ma);
}
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
}
int main()
{
int arr[10],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
maxmin(arr,0,n-1);
cout<<" max "<<maximum<<" min "<<minimum<<endl;
return 0;
}
Your code has a few mistakes
Your code reads n from the user input, but you provided only 10 sized array, and user can try to input 10+ numbers, so we will have an undefined behavior in that case.
You write it very bad and unreadable. If you want somebody else to read your code, check in the your favourite book or in the internet information about how to write beautiful and readable code.
You implemented that algorithm yourself. It is a bad habit, use the standard library algorithms and you will not encounter such mistake.
.
#include <iostream> // std::cin, std::cout
#include <cstddef> // std::size_t
#include <algorithm> // std::min_element, std::max_element
int main ()
{
std::size_t array_size;
std::cin >> array_size;
int *some_array = new int[array_size]; // Allocate memory dynamically
for(std::size_t i = 0; i < array_size; ++i)
{
std::cin >> some_array[i];
}
/* Standard library operate on iterators, they are special classes
* that have interface that is similar in many cases to pointers (so we can use pointers as iterators).
* std::min/max_element needs one iterator for the sequence beginning
* and one iterator after the end. It returns iterator to a found element.
*/
int min = *std::min_element(some_array, some_array + array_size);
int max = *std::max_element(some_array, some_array + array_size);
delete[] some_array;
std::cout << "Min = " << min << std::endl << "Max = " << max;
std::cout << std::endl;
}
Code isn't well written and first dry run your code, you will find the problem easily.
Change
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
To
else
{
int mid=(i+j)/2; /*** Adding brackets ***/
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
And check the logic for calling the result function (because according to your logic the two subsets are individually calculating MIN and MAX in itself not in whole array)

How do you add all elements in a vector together? c++ [duplicate]

This question already has answers here:
How to sum up elements of a C++ vector?
(13 answers)
Closed 7 years ago.
I'm very new to coding and was just playing around with vectors however I cant seem to find out how to add all elements in a vector together when the amount of elements is user-defined.
#include <iostream>
#include <vector>
using namespace std;
int NoOfItems;
int i=1;
double Odds;
double Cost;
vector<double> CaseNumber;
int main()
{
cout << "How many items in the case: ";
cin >> NoOfItems;
while (true) {
if (NoOfItems == 0) {
break;
} else {
cout << "Odds for item " << i <<endl;
cin >> Odds;
CaseNumber.push_back(Odds);
NoOfItems = NoOfItems - 1;
i = i + 1;
}
}
}
You'll want to spend some time cleaning up your code. There's some very questionable code conventions being used.
Anyways, to sum all of the elements of your vector:
double sum = 0;
for(size_t index = 0; index < CaseNumber.size(); index++) {
sum += CaseNumber[index];
}
Or, in a way that's slightly more friendly to the semantics of C++:
double sum = 0;
for(double & d : CaseNumber) {
sum += d;
}
Either will result in the variable sum containing the sum total of all elements in CaseNumber

C++ Program Apparently Printing Memory Address instead of Array

#include <iostream>
using namespace std;
int main(){
int findMax(int *);
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
int mval = findMax(values);
cout << values << endl << mval;
return 0;
}
//Function to find the maximum value in the array
int findMax(int arr[]){
int localmax = 0;
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
if(arr[i] > localmax){
localmax = arr[i];
}
}
return localmax;
}
The purpose of this program is for the user to input a space-separated series of values ended by a 0. That array is then to be analyzed to find the max. I figured out how to convert what is originally a char[] into an int[] so that I can use the findMax() function on it without error but the sorting loop seems to have a problem of its own and when "cout << values << endl << mval;" is called, it returns only a memory address instead of what should be a non-spaced sequence of ints. Can anybody explain what I am doing wrong? It seems that I may have made some mistake using the pointers but I cannot figure out what.
Printing values won't print the contents of the array as you expect, it will print the memory location of the first element of the array.
Try something like this instead:
#include <iterator>
#include <algorithm>
// ...
copy(&values[0], &values[MAX], ostream_iterator(cout, " "));
Sorry I can't post actual working code, but your original post is a mess with many syntax and syntactic errors.
EDIT: In the interest of being more complete and more approachable & understandable to beginners, I've written a small program that illustrates 4 ways to accomplish this.
Method 1 uses copy with an ostream_iterator as I've done above.
Method 2 below is probably the most basic & easiest to understand.
Method 3 is a C++0x method. I know the question is tagged C++, but I thought it might be educational to add this.
Method 4 is a C++ approach using a vector and for_each. I've implemented a functor that does the dumping.
Share & Enjoy
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
struct dump_val : public unary_function<int,void>
{
void operator()(int val)
{
cout << val << " ";
}
};
int main(){
int vals[5] = {1,2,3,4,5};
// version 1, using std::copy and ostream_iterator
copy(&vals[0], &vals[5], ostream_iterator<int>(cout, " "));
cout << endl;
// version 2, using a simple hand-written loop
for( size_t i = 0; i < 5; ++i )
cout << vals[i] << " ";
cout << endl;
// version 3, using C++0x lambdas
for_each(&vals[0], &vals[5], [](int val)
{
cout << val << " ";
}
);
cout << endl;
// version 4, with elements in a vector and calling a functor from for_each
vector<int> vals_vec;
vals_vec.push_back(1);
vals_vec.push_back(2);
vals_vec.push_back(3);
vals_vec.push_back(4);
vals_vec.push_back(5);
for_each( vals_vec.begin(), vals_vec.end(), dump_val() );
cout << endl;
}
When you pass around an array of X it's really a pointer to an array of X that you're passing around. So when you pass values to cout it only has the pointer to print out.
You really should look into using some of the standard algorithms to make your life simpler.
For example to print all the elements in an array you can just write
std::copy(values, values+MAX, std::ostream_iterator<int>(std::cout, "\n"));
To find the max element you could just write
int mval = *std::max_element(values, values+MAX);
So your code becomes
#include <iostream>
using namespace std;
int main(){
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
copy(values, values+MAX, ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values, values+MAX);
return 0;
}
Doing this removes the need for your findMax method altogether.
I'd also re-write your code so that you use a vector instead of an array. This makes your code even shorter. And you can use stringstream to convert strings to numbers.
Something like this should work and is a lot less code than the original.
int main(){
vector<int> values;
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
int temp = 0;
stringstream ss(ivals);
//read the next int out of the stream and put it in temp
while(ss >> temp) {
//add temp to the vector of ints
values.push_back(temp);
}
copy(values.begin(), values.end(), ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values.begin(), values.end());
return 0;
}
Array of int is promoted to a pointer to int when passed to a function. There is no operator << taking ordinary array. If you want to use operator << this way, you need to use std::vector instead.
Note: it is possible technically to distinguish array when passed to a function using template, but this is not implemented for standard operator <<.
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
sizeof(arr) here is the size of the pointer to the array. C++ will not pass the actual array, that would be grossly inefficient. You'd typically only get one pass through the loop. Declare your function like this:
int findMax(int* arr, size_t elements) {
//...
}
But, really, use a vector.
Oh, hang on, the question. Loop through the array and print each individual element.