Arranging elements from two vectors alphabetically into one vector - c++

The two vectors the user enters will always be in alphabetical order, and the function merge_items places those values in one vector seeing which one comes before the other by using the < operator, the code initially gave a segmentation fault and at certain times, it doesn't show the last element.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void merge_items(vector<string>& a1,vector<string>& b1,vector<string>& merged);
int main(){
vector<string> v1,v2;
string a,b;
int n1,n2;
cout << "How many values for v1? " << endl;
cin >> n1;
for(int i = 0;i < n1;i++){
cin >> a;
v1.push_back(a);
}
cout << "How many values for v2? " << endl;
cin >> n2;
for(int i = 0;i < n2;i++){
cin >> b;
v2.push_back(b);
}
vector<string> merge;
merge_items(v1, v2, merge);
for(int i = 0;i < merge.size();i++){
cout << merge[i] << endl;
}
return 0;
}
void merge_items(vector<string>& a1,vector<string>& b1,vector<string>& merged){ int i1 = 0,i2 = 0;
string temp;
while(i1+i2 < (a1.size()-1+b1.size()-1)){
if(a1[i1] < b1[i2]){
temp = a1[i1];
merged.push_back(temp);
i1++;
}else{
temp = b1[i2];
merged.push_back(temp);
i2++;
}
}
}

This is the appropriate way to merge:
std::merge(a1.begin(), a1.end(),
b1.begin(), b1.end(),
std::back_inserter(merged));
As far as what's wrong with your solution. A couple things.
First, once you reach the end of one of the two vectors, you need to stop comparing against that vector and just copy whatever elements are left from the other vector. So you need to compare i1 against a1.size(), separately from your comparison of i2 against b1.size(). With what you're doing now, when you reach the end of one vector, you continue comparing against out of bounds elements from that vector, which is undefined behavior, and likely the cause of your segmentation faults.
Second, you don't need to be subtracting 1 from the size of the vectors. The way you're doing it will leave you with a merged vector which has 2 fewer elements than the combined sizes of the source vectors.

Related

C++ pointer gets overwritten in for loops

Could someone explain why pointers gets overwritten when variables are declared inside a loop?
For example, given the following snippet, and the user inputs 1 and 2. I would expect that the pNums array contain 2 pointers to 2 integers holding the value 1 and 2 respectively.
But instead, the console prints out 2 and 2;
#include <iostream>
using namespace std;
//Input "1 2"
int main() {
int* pNums[2];
for(int i = 0; i < 2; i++){
int num;
cin >> num;
pNums[i] = (&num);
}
cout << (*pNums[0]) << endl;
cout << (*pNums[1]) << endl;
}
Why is this the case? And how do I get around it? What if, for example, we don't know how many numbers the user will put in, and instead of a for loop, we have a while loop? Until some conditions are met, we want to keep creating new pointers and store them into a pNums vector?
There is only one num, and you are overwriting that. (And then causing Undefined Behavior, but never mind that.)
There are two simple ways to avoid this mistake.
1) Store objects, not pointers:
int nums[2];
for(int i = 0; i < 2; i++){
cin >> nums[i];
}
2) Use dynamic allocation:
int* pNums[2];
for(int i = 0; i < 2; i++){
int *p=new int;
cin >> *p;
pNums[i] = p;
}
The pointers that you are storing in pNums are to two instances of the variable num in the for block. There is one instance of the variable in each for loop iteration and these variables live only until the end of their respective iteration of the for loop body is reached.
Therefore your pointers will be invalid when the for loop exits and so trying to dereference them with e.g. *pNums[0] causes undefined behavior.
Don't store pointer, store values:
#include <iostream>
using namespace std;
//Input "1 2"
int main() {
int pNums[2];
for(int i = 0; i < 2; i++){
int num;
cin >> num;
pNums[i] = num;
}
cout << pNums[0] << endl;
cout << pNums[1] << endl;
}
and if you need a variable number of entries in the array, use std::vector.
for(int i = 0; i < 2; i++){
int num; //< this is num. It lives here.
cin >> num;
pNums[i] = (&num); //< you have taken the address of num (twice!)
}
// here is when 'num' is destroyed (no longer in scope)
// so this is now pointing at something that doesn't exist.
cout << (*pNums[0]) << endl;

Multidimensional Vector?

So I recently started learning C++ and I'm trying to figure out how to access a multidimensional vector or a vector with vectors stored inside of it. I've looked all over and I can't find exactly what I'm looking for. I want to be able to test the contents of each vector inside of the multidimensional vector by printing them out. Also whenever I try to see the size of the vector after each iteration, I'm getting random constants for each iteration. They look like they may be memory locations but I'm not sure.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int numofArrays;
int numofQueries;
vector<vector<int>> arr(numofArrays);
cin >> numofArrays;
cin >> numofQueries;
int arrSize;
int number;
vector<int> indArr;
// Outer loop, appends vectors containing ints to a multidimensional vector
for (int i = 0; i < numofArrays; i++) {
cin >> arrSize; // Getting number of elements from user
// Inner loop, gets user inputted values then creates a vector which is added to the multidimensional vector
for (int x = 0; x < arrSize; x++) {
cin >> number;
indArr.push_back(number);
cout << "Last number added to vector: " << number << endl; // Checking to see if correct numbers are being added.
}
arr.push_back(indArr);
cout << "Multidimensional Vector size: " << arr.size() << endl; // Checking size of vector after each iteration
indArr.clear(); // Empties vector for next iteration
}
return 0;
}
As I am very new to C++, I welcome constructive criticism.
Newly Revised Code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int numofArrays;
int numofQueries;
cin >> numofArrays;
cin >> numofQueries;
vector<vector<int>> arr(numofArrays);
// Outer loop, appends vectors containing ints to a multidimensional vector
for (int i = 0; i < numofArrays; i++) {
int arrSize;
vector<int>indArr;
cin >> arrSize; // Getting number of elements from user
indArr.resize(arrSize); // Resizing array for next values
// Inner loop, gets user inputted values then creates a vector which is added to the multidimensional vector
for (int x = 0; x < arrSize; x++) {
int number;
cin >> number;
indArr.push_back(number);
cout << "Last number added to vector: " << number << endl; // Checking to see if correct numbers are being added.
}
arr.push_back(indArr);
cout << "Multidimensional Vector size: " << arr.size() << endl; // Checking size of vector after each iteration
}
int test = arr[0][0];
cout << test;
return 0;
}
Just some tips:
vector<vector<int>> arr(numofArrays); constructs a vector of vectors of size numofArrays. But numofArrays is not yet read from cin, so it is an undefined number. Care with the order of operations.
arr.push_back(indArr); adds a vector at the end of arr.
Hence, in your loop, even if you fix the order of reading numofArrays and declaring arr, you start with an array of size numofArrays, and each cycle you add an element. You will end up with arr holding 2 times numofArrays elements.
Also, indArr is a temporary variable, which you reset each cycle. Although there is nothing wrong about what you are doing, in general is better to keep each variable limited to its scope. If you define indArr inside the loop, it will be automatically cleared and re-created. May not be the most efficient way to do things in all cases, but I'd leave this details for later.
Something like this should work for you:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int numofArrays;
int numofQueries;
cin >> numofArrays;
cin >> numofQueries; // this is an unused variable
vector<vector<int> > arr;
// Outer loop, set vectors containing ints to a multidimensional vector
for (int i = 0; i < numofArrays; i++) {
int arrSize;
vector<int> indArr;
cin >> arrSize; // Getting number of elements from user
// Inner loop, gets user inputted values then creates a vector which is added to the multidimensional vector
for (int x = 0; x < arrSize; x++) {
int number;
cin >> number;
indArr.push_back(number);
cout << "Last number added to vector: " << number << endl; // Checking to see if correct numbers are being added.
}
arr.push_back(indArr);
cout << "Multidimensional Vector size: " << arr.size() << endl; // Checking size of vector after each iteration
}
return 0;
}
The way you're inspecting the size is correct. For example in your code you're printing the integer number of elements in the first dimension of the array arr.
The odd results you're getting is because of how you're initializing the vector. In the constructor for arr there you specify a size describing the number of default-constructed elements to fill the vector with. However you're providing numofArrays which is an undefined value. Hence you receive random looking vector sizes when you print this out.
The real size of the vector arr's first dimension will be whatever this undefined value is plus one, due to the push_back operation.

C++ How would I use sort to sort this two dimensional array?

My question is pretty specific, I think. My program is supposed to store 10 names, and their corresponding phone numbers into an array. I want to sort the names/numbers by phone numbers, ascending order, and then output the array in the sorted order. Thanks for the help! Any and all help is appreciated.
What I have so far:
using namespace std;
main()
{
string name[10][2];
int x;
cout << "Please input 10 names";
for(int i = 0; i < 10; i++){
cin >> name[i][x];
}
int i = 0;
cout << "Please input their corresponding numbers";
for(x = 0; x < 10; x++){
cin >> name[i][x];
}
}
EDIT: Would it be possible(not as hassling) to instead do this but with a parallel array storing a string(name) and an int(number) and sort it by the int?(Of course, while keeping the names by their corresponding number) If so, how could I change it from a two-dimensional to a parallel array?(Or just pointing me in the right direction would be greatly appreciated) :)
You will want to use a vector of pairs. This is in this case more convenient than a map because you want to sort by value rather than by key. There are also methods to sort a map by value (see question Sorting std::map using value), but for this purpose a vector of pairs seems appropriate.
If you want to have a constant memory array instead of a dynamic memory array (std::vector) then use std::array<std::pair<std::string,int>, N>, where N is the number of elements.
Needs C++14 because of the template lambda.
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
int main()
{
std::vector<std::pair<std::string,int>> phonebook;
phonebook.reserve(10);
std::cout << "Please input a name and a number\n";
for (int i = 0; i < 10; ++i) {
std::cout << "Name: ";
std::string name;
std::cin >> name;
std::cout << "Number: ";
int number;
std::cin >> number;
phonebook.push_back({name, number});
}
std::sort( std::begin(phonebook),
std::end(phonebook),
[] (auto a, auto b) { return a.second < b.second; });
for (auto const& entry : phonebook)
{
std::cout << entry.first << ' ' << entry.second << '\n';
}
}

Issue with user-defined array in C++

I am trying to create an array using cin to define the size. While that seems to be working (based on what I currently have), none of the other stuff I want to do seems to be working.
For instance, I want to use a for loop to find the smallest int in the array since I will then need to compare it with all the other ints in the array, but no matter where I have the statement to return the smallest int, it does not do it.
What am I doing wrong?
#include <iostream>
using namespace std;
int main(){
int userSize;
cout << "Please define size of array: ";
cin >> userSize;
int *duckArray = new int[userSize];
for (int i = 0; i < userSize; i++) {
cout << "Please enter a number into the array: ";
cin >> duckArray[i];
}
int smallest = duckArray[0];
for (int i = 0; i < userSize; i++){
if (duckArray[i] < smallest){
smallest = duckArray[i];
cout << smallest << endl;
}
}
//cout << smallest << endl;
return 0;
}
Your code is working if you change this:
for (int i = 0; i < userSize; i++){
if (duckArray[i] < smallest){
smallest = duckArray[i];
}
}
cout << smallest << endl;
This will find and print the smallest number entered.
Arrays in C++ must have their size declared to the compiler at runtime. Other people are going to explain how you can buffer memory to simulate a dynamically allocating arrays. You can also have your Array at a given size and as the user adds and removes, you can reject inputs over the current size.
I highly recommend you look into Vectors. Vectors are much like ArrayLists in Java. They are a form of higher level collections that resize themselves as you add more elements to them.

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.