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

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.

Related

Value of a variable is not updating, it is either 1 or 0

Hey there! In the following code, I am trying to count frequency of each non zero number
My intention of the code is to update freq after testing each case using nested loop but value of freq is not updating. freq value remains to be either 0 or 1. I tried to debug but still ending up with the same bug.
Code:
#include <bits/stdc++.h>
using namespace std;
int main() {
int size;
cin>>size;
int freq=0;
int d[size];
for(int i=0;i<size;i++){ //To create array and store values in it
cin>>d[i];
}
for(int i=0;i<size;i++){
if(d[i]==0 )continue;
for(int j=0;j<size;j++){
if(d[i]==d[j]){
freq=freq+1;
d[j]=0;
}
}
cout<<"Frequency of number "<<d[i]<<" is "<<freq<<endl;
d[i]=0;
freq=0;
}
}
Input:
5
1 1 2 2 5
Expected output:
Frequency of number 1 is 2
Frequency of number 2 is 2
Frequency of number 5 is 1
Actual output:
Frequency of number 0 is 1
Frequency of number 0 is 1
Frequency of number 0 is 1
Frequency of number 0 is 1
Frequency of number 0 is 1
Some one please debug the code and fix it. Open for suggestions.
#include <bits/stdc++.h>
This is not standard C++. Don't use this. Include individual standard headers as you need them.
using namespace std;
This is a bad habit. Don't use this. Either use individual using declarations for identifiers you need, such as using std::cout;, or just prefix everything standard in your code with std:: (this is what most people prefer).
int d[size];
This is not standard C++. Don't use this. Use std::vector instead.
for(int j=0;j<size;j++){
if(d[i]==d[j]){
Assume i == 0. The condition if(d[i]==d[j]) is true when i == j, that is, when j == 0. So the next thing that happens is you zero out d[0].
Now assume i == 1. The condition if(d[i]==d[j]) is true when i == j, that is, when j == 1. So the next thing that happens is you zero out d[1].
Now assume i == 2. The condition if(d[i]==d[j]) is true when i == j, that is, when j == 2. So the next thing that happens is you zero out d[2].
Now assume i == 3 ...
So you zero out every element of the array the first time you see it, and if(d[i]==d[j]) never becomes true when i != j.
This can be fixed by changing the inner loop to
for (int j = i + 1; j < size; j++) {
This will output freq which is off by one, because this loop doesn't count the first element. Change freq = 0 to freq = 1 to fix that. I recommend having one place where you have freq = 1. A good place to place this assignment is just before the inner loop.
Note, I'm using spaces around operators and you should too. Cramped code is hard to read.
Here is a live demo of your program with all the aforementioned problems fixed. No other changes are made.
To build an histogram, you actually need to collect history.
Example:
int main() {
int size;
cin >> size;
int d[size];
int hist[size + 1]{}; // all zeroes - this is for the histogram
for (int i = 0; i < size; i++) { // To create array and store values in it
cin >> d[i];
}
for (int i = 0; i < size; i++) {
++hist[d[i]];
}
for(int i = 0; i < size; ++i) {
cout << "Frequency of number " << i << " is " << hist[i] << endl;
}
}
Note: VLAs (Variable Length Arrays) are not a standard C++ feature. Use std::vector instead.
A slightly different approach would be to not be limited by the size parameter when taking the input values. std::map the value to a count instead:
#include <iostream>
#include <vector>
#include <map>
int main() {
int size;
if(not (std::cin >> size) or size < 1) return 1;
std::map<int, unsigned long long> hist; // number to count map
for(int value; size-- > 0 && std::cin >> value;) {
++hist[value];
}
for(auto[value, count] : hist) {
std::cout << "Frequency of number " << value << " is " << count << '\n';
}
}

C++ How to optimize this algorithm ? (std::map)

The problem is the following: We are given a number 's', s ∈ [0, 10^6], and a number 'n', n ∈ [0, 50000], then n numbers, and we have to find how many number pairs' sum is equal to the 's' number (and we must use either maps or sets to solve it)
Here is the example:
Input:
5 (this is s)
6 (this is n)
1
4
3
6
-1
5
Output:
2
explanation : these are the (1,4) and (6,−1) pairs. (1 +4 = 5 and 6 + (-1) = 5)
Here is my "solution" , I don't even know if it's correct, but it works for the example that we got.
#include <iostream>
#include <map>
#include <iterator>
using namespace std;
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
int s;
cin >> s;
int n;
cin >> n;
map<int, int> numbers;
int element;
int counter = 0;
for(int i=0; i<n;i++)
{
cin >> element;
numbers.insert(pair<int, int>(element, s-element));
}
for(map<int, int>::iterator it = numbers.begin(); it != numbers.end(); it++)
{
map<int, int>::iterator it2 = it;
while(it2 != numbers.end())
{
if(it->second == it2->first)
{
counter++;
break;
}
it2++;
}
}
cout << counter << "\n";
return 0;
}
Thanks for the answers in advance! I'm still a beginner and I'm learning, sorry.
element, s-element is a good idea but there is no reason to store all the pairs and only then check for duplicates. This removes the O(n^2) loop you have there at the end.
The standard way using hashing would be:
seen=unordered_map<number,count>()
for 1...n:
e = read_int()
if (s-e) in seen:
duplicates+=seen[s-e] # Found new seen[s-e] duplicates.
if e in seen:
seen[e]+=1
else:
seen.insert(e,1)
return duplicates
Here's a brute-force method, using a vector:
int target_s = 0;
int quantity_numbers = 0;
std::cin >> target_s >> quantity_numbers;
std::vector<int> data(quantity_numbers);
for (int i = 0; i < quantity_numbers; ++i)
{
cin >> data[i];
}
int count = 0;
for (int i = 0; i < quantity_numbers; ++i)
{
for (j = 0; j < quantity_numbers; ++j)
{
if (i == j) continue;
int pair_sum = data[i] + data[j];
if (pair_sum == target_s) ++count;
}
}
std::cout << count;
The above code includes the cases where pair <a,b> == s and pair <b,a> == s. Not sure if the requirement only wants pair <a,b> in this case.
As always with this kind of questions, the selection of the appropriate algorithm will improve your solution. Writing some "better" C++ code, will nearly never help. Also, brute forcing is nearly never a solution for such an algorithm.
With the following described approach (which was of course not invented by me), we need just one std::map (or even better, a std::unordered_map) and one for loop. We do not need to store the read values in an additional std::vector or such alike. So, we can come up with low memory condumption and fast computation.
Approach. Any time, after reading a value, we will calculate the delta from the desired sum.
If we look at the required condition that the current value and some previuosly read value, should add up to the desired sum, we can write the following mathematical equations:
currentValue + previouslyReadValue = desiredSum
or
desiredSum - currentValue = previouslyReadValue
or with
delta = desiredSum - currentValue
-->
delta == previouslyReadValue
So, we need to look at the already read values and if they are equal to the delta (Because then they would add up the the desired sum), add their count of occurence the the resulting count of valid pairs.
The already read values and their count of occurence will be stored in a std::unordered_map.
All this will result in a 10 line solution:
#include <iostream>
#include <unordered_map>
int main() {
// Initialize our working variables
int numberOfValues{}, desiredSum{}, currentValue{}, resultingCount{};
// Read basic parameters. Desired sum and overall number of input values.
std::cin >> desiredSum >> numberOfValues;
// Here, we will store all values and their count of occurence
std::unordered_map<int, int> valuesAndCount{};
// Read all values and operate on them
for (int i{}; i < numberOfValues; ++i) {
std::cin >> currentValue; // Read from cin
const int delta{ desiredSum - currentValue }; // Calculate the delta from the desired sum
// Look, if the calculated delta is already in the map. Becuase, if the delta and the
// current value sum up to our desired sum, then we found a valid pair.
if (valuesAndCount.find(delta) != valuesAndCount.end())
// Increase the resulting count, by the number of times that this delta value has already been there
resultingCount += valuesAndCount[delta];
// Nothing special, Just cound the occurence of this value.
valuesAndCount[currentValue]++;
}
return !!(std::cout << resultingCount);
}

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.

How to reduce the execution time further?

I'm trying a problem for a contest.The requirement is as below.
Problem:
Input_format:
Output_expected:
My C++ code is:-
#include <iostream>
using namespace std;
int main() {
long long n,i,j,k=0,p,q;
cin>>n;//takes size of string//
char s[n];
cin>>s;
cin>>p;//Number of test cases//
for(i=0;i<p;i++)
{
cin>>q;//takes index to check till//
for(j=0;j<q-1;j++)
{
if(s[j]==s[q-1])//checks if characters are equal//
{
k++;//if yes then counts it//
}
}
cout<<k<<endl;
k=0;//makes cout 0 for next iteration//
}
return 0;
}
So it seems the code works for most of the cases but there's this time constraint that seems exceeding for some cases.What more can be done to reduce the time.Thanks in advance for taking time to read this.
Let's say we have an array cnt which stores the number of occurrences of each letter in the before the ith character of the string, for some i. We can easily update this array to include the ith character by simply incrementing the relevant element. So we'll iterate through the string updating this array, and at the ith iteration the cnt array will contain counts of every letter before index i.
Now, at the ith iteration, the information in the cnt array which would be useful for answering queries is cnt[s[i]], since that contains the number of occurrences of the character at index i in the part of the string preceding index i. We'll store this information in a[i], where a is some other array. So now a[i] is the number of occurrences of the letter at index i in all positions before i, which is exactly what we want for a query at index i. Therefore, we can now answer queries using the array.
Possible implementation:
#include <iostream>
#include <string>
#include <vector>
int main()
{
//read input
int n;
std::string s;
std::cin >> n >> s;
//iterate through string maintaining cnt array and adding relevant values to array a
int cnt[26] = { 0 };
std::vector<int> a;
a.reserve(n);
for (int i = 0; i < n; i++)
{
int c = s[i] - 'a';
a.push_back(cnt[c]);
cnt[c]++;
}
//answer queries
int q;
std::cin >> q;
for (int i = 0; i < q; i++)
{
int p;
std::cin >> p;
p--;
std::cout << a[p] << '\n';
}
}
First, this declaration:
long long n
cin>>n;//takes size of string//
char s[n];
Is non-standard. g++ supports it, but I don't believe variable sized arrays have made it into the C++ standard as it has for C. And I doubt you need long long as your index type unless you are scaling beyond 2 billion items.
Better:
int n;
cin>>n; //takes size of string
vector<char> s(n);
s is effectively the same as an array as for as accessing it at index locations with the [] operation.
Back to the solution:
Use a hash table that maps between a character and the number of occurrences of that character as you scan the s array once. Then use another array to keep track of how many times the character at that index was seen up to that point.
std::vector<int> positionCount(n);
std::unordered_map<char, int> table;
Insert your characters from s into the table and positionCount table as follows
for (int i = 0; i < n; i++)
{
char c = s[i];
// table[c] is the number of occurrences that "c" was seen in the input array so far
table[c]++;
// since table[c] is getting updated as we iterate,
// Keep track of the count of the char at position i in a separate array
positionCount[i] = table[c];
};
Then for each test case:
for(i=0;i<p;i++)
{
cin>>q; //takes index to check till
q--; // off by 1 fix since the array is described as 1..N
long result = positionCount[q];
result--; // off by 1 fix again since the output is the preceeding count and doesn't include the character at position q.
cout << result << endl;
}
All of the above is intuitively faster since there's no inner for loop. Hash table insertion and lookup is O(1) as is each array lookup.
And if you are into the whole brevity thing, you can simplify the above into this:
for (int i = 0; i < n; i++)
{
positionTable[i] = table[s[i]]++;
}
for(i=0;i<p;i++)
{
cin >> q;
cout << positionTable[q-1] << endl;
}

How do online judges pass the input data?

I'm trying to solve this problem from an online judge (Codeforces):
One day Deivis came across two Vectors of integers A and B, and wondered, could it be possible to form the number X by adding an element of A to another element of B?
More formally, it is possible to choose two indexes i and j such that Ai + Bj = x?
Input
The first entry line is two integers n and x. The second line contains n numbers, the vector A. The third and last line contains n numbers, vector B.
Output
Print 1 if it is possible to form the number x from a sum of one element of each vector, and 0 otherwise."
My problem is that I can not fill in the second vector, when the program runs on the site it fills the vector with zeros. I am using C ++, here's my code:
#include <bits/stdc++.h>
using namespace std;
#define MAX 10
int main()
{
int n, x, i = 0, j = 0, resp = 0, sum;
vector<int> vetA(MAX), vetB(MAX);
cin >> n >> x;
while (scanf("%d", &vetA[i]) == 1)
i++;
while (scanf("%d", &vetB[j]) == 1)
j++;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
sum = vetA[i] + vetB[j];
if (sum == x)
{
resp = 1;
goto END;
}
}
}
END: printf("%d", resp);
return 0;
}
I try to use getchar() after each while loop, but seems that on the site it does not do data capture like on a keyboard, and so the second vector isn't receiving any data. I've also tried to capture data as a std::string but that doesn't work.
Can someone help me?
Here are some hints/examples to compare your program to:
#include <iostream> //Include each standard library seperately
#include <vector> //#include <bits/stdc++.h> is bad practice
// Only declare variables as they are used.
int n; // Better coding practice is one variable per line.
int x; // Competitions shouldn't care how many lines.
if (!(std::cin >> n >> x)) //This is basically the same as cin.fail()
{
std::cerr << "Error inputting data.\n";
return 1;
}
// Now create the vectors, after the size has read in.
std::vector<int> vetA(n);
std::vector<int> vetB(n);
// The number of elements is known, so use a "for" loop.
for (size_t i = 0; i < n; ++i)
{
std::cin >> vetA[i];
}
for (size_t i = 0; i < x; ++i)
{
std::cin >> vetB[i];
}
You should add in some error handling because your program will be given some invalid inputs.
The inputs and vector sizes are examples since you didn't specify the input format in your Post.