vector variable inside for loop - c++

I have defined an empty vector variable inside the loop for the test case, after execution of each test case I expect the vector will go empty, but it is storing the previous result of the earlier test cases as well please help thanks a lot.
My problem statement is this. which takes input as:
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
N lines follow. For each valid i, the i-th of these lines contains a string S3,i followed by a space and an integer
C3,i — the problem code and the number of correct solutions
on the i-th problem in the third division.
N more lines follow. For each valid i, the i-th of these lines contains a string S2,I followed by a space and an integer
C2,i — the problem code and the number of correct solutions
on the i-th problem in the second division.
Finally, N more lines follow. For each valid i, the i-th of these lines contains a string S1,i followed by a space and an
integer C1,i — the problem code and the number of correct
solutions on the i-th problem in the first division.
GOAL:
Codechef challenges have three divisions. In one challenge, there are N problems in each division, but some problems may be shared among multiple divisions. Each problem is uniquely identified by a code — a string containing only uppercase English letters. Each participant can only submit in one of the divisions.
Chef wants to find the number of correct solutions, in total among all 3 divisions, for each problem. Given a list of N problem codes with the numbers of correct solutions for each problem in each division, find the total number of correct solutions for each problem and sort them in non-decreasing order.
My code takes input as:
3
1
A 1
B 2
C 3
2
AA 1
AB 1
AB 1
AC 1
AC 1
AD 1
1
Z 100
Z 100
Z 100
The expected output is:
1 2 3
1 1 2 2
300
But my output has errors:
1 2 3
1 1 1 2 2 2 3
1 1 1 2 2 2 3 300
My code for above problem is:
#include <iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
int main() {
map<string,int>m;
int t,n,c_1;
string s_1;
cin>>t;
for(int i=0;i<t;i++){
cin>>n;
for(int k=0;k<3;k++){
for(int j=0;j<n;j++){
cin>>s_1;
cin>>c_1;
m[s_1]+=c_1;
}
}
vector<int>v;
for(auto x :m){
v.push_back(x.second);
}
sort(v.begin(),v.end());
for(auto y: v){
cout<<y<<" ";
}
cout<<"\n" ;
}
return 0;
}

Your vector (v) is being reset (to empty) on each run of the outer for loop but your map (m) isn't. That is keeping its content each time, and your new inputs are being appended to it. Thus, your for (auto x : m) { appends the data from each previous loop to your (initially empty) vector.
Move the declaration of map<string, int>m; to inside that outer loop to fix your problem:
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using std::cin, std::cout;
using std::string;
using std::map;
using std::vector;
using std::sort;
int main()
{
int t, n, c_1;
string s_1;
cin >> t;
for (int i = 0; i < t; i++) {
map<string, int>m; // Move the map to here, so it's created afresh for each loop.
cin >> n;
for (int k = 0; k < 3; k++) {
for (int j = 0; j < n; j++) {
cin >> s_1;
cin >> c_1;
m[s_1] += c_1;
}
}
vector<int>v;
for (auto x : m) {
v.push_back(x.second);
}
sort(v.begin(), v.end());
for (auto y : v) {
cout << y << " ";
}
cout << "\n";
}
return 0;
}
Alternatively, you can use the same map each time and just reset (clear) it on each run of the outer loop, by adding a m.clear(); as the first line inside that loop.

Related

Minimum number of steps to equalize distinct character of the string [duplicate]

This question already has answers here:
How to find the minimum number of operation(s) to make the string balanced?
(5 answers)
Closed 1 year ago.
I'm trying to write this program that asks for user input of string, my job is to print out the minimum number of steps required to equalize the frequency of distinct characters of the string.
Example
Input
6
aba
abba
abbc
abbbc
codedigger
codealittle
Output
1
0
1
2
2
3
Here is my program:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map<char, int >m;
vector<int> vec1, vec2;
string s;
int n;
cin >> n;
cin.ignore();
for (int i = 0; i < n; ++i)
{
m.clear();
vec1.clear();
getline(cin, s);
for (int i = 0; i < s.size(); i++)
m[s[i]]++;
for (auto itr : m)
vec1.push_back(itr.second);
sort(vec1.begin(), vec1.end());
int mid = vec1[vec1.size() / 2];
int ans = 0;
for (auto itr : vec1)
ans += abs(mid - itr);
vec2.push_back(ans);
}
for (int i = 0; i < vec2.size(); ++i)
cout << vec2[i] << endl;
}
What I tried to do is for each test case:
Using an unordered_map to count the frequency of the characters of the string.
Push the key values of the map to a vector.
Sort the vector in ascending order.
Calculate the middle element of the vector to equalize the distinct characters with as least steps as possible.
The result will add the difference between the middle element with the current element.
Push the result to another vector and print it.
But my result is wrong at test case number 5:
1
0
1
2
3 // The actual result is 2
3
I don't understand why I get the wrong result, can anyone help me with this? Thanks for your help!
The issue is that your algorithm is not finding the optimal number of steps.
Consider the string you obtained an incorrect answer for: codedigger. It has 4 letters of frequency 1 (coir) and 3 letters of frequency 2 (ddeegg).
The optimal way is not to convert half the letters of frequency 2 into some new character (not present in the string) to make all frequency 1. From my understanding, your implementation is counting the number of steps that this would require.
Instead, consider this:
c[o]dedigge[r]
If I replace o with c and r with i, I obtain:
ccdediggei
which already has equalized character frequencies. You will note that I only performed 2 edits.
So without giving you a solution, I believe this might still answer your question? Perhaps with this in mind, you can come up with a different algorithm that is able to find the optimal number of edits.
Your code correctly measures the frequencies of each letter, as the important information.
But then, there were mainly two issues:
The main target value (final equalized frequency) is not necessarily equal to the median value. In particular, this value must divide the total number of letters
For a given targeted height value, your calculation of the number of steps is not correct. You must pay attention not to count twice the same mutation. Moreover, the general formula is different, depending the final number of different letters is equal, less or higher than the original number of letters.
The following code focuses on correctness, not on efficiency too much. It considers all the possible values of the targeted height (frequency), i.e. all the divisors of the total number of letters.
If efficiency is really a concern (not mentioned in the post), then for example one could consider that the best value is unlikely to be very far from the initial average frequency value.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <unordered_map>
// calculates the number of steps for a given target
// This code assumes that the frequencies are sorted in descending order.
int n_steps (std::vector<int>& freq, int target, int nchar) {
int sum = 0;
int n = freq.size();
int m = nchar/target; // new number of characters
int imax = std::min (n, m);
for (int i = 0; i < imax; ++i) {
sum += std::abs (freq[i] - target);
}
for (int i = imax; i < n; ++i) {
sum += freq[i];
}
if (m > n) sum += m-n;
sum /= 2;
return sum;
}
int main() {
std::unordered_map<char, int >m;
std::vector<int> vec1, vec2;
std::string s;
int n;
std::cin >> n;
std::cin.ignore();
for (int i = 0; i < n; ++i)
{
m.clear();
vec1.clear();
//getline(cin, s);
std::cin >> s;
for (int i = 0; i < s.size(); i++)
m[s[i]]++;
for (auto itr : m)
vec1.push_back(itr.second);
sort(vec1.begin(), vec1.end(), std::greater<int>());
int nchar = s.size();
int n_min_oper = nchar+1;
for (int target = 1; target <= nchar; ++target) {
if (nchar % target) continue;
int n_oper = n_steps (vec1, target, nchar);
if (n_oper < n_min_oper) n_min_oper = n_oper;
}
vec2.push_back(n_min_oper);
}
for (int i = 0; i < vec2.size(); ++i)
std::cout << vec2[i] << std::endl;
}

Find 4 if a given array has 4 consecutive values using functions (C++)

A quick disclaimer before you read ahead, this is a question regarding my homework and some of these requirements will be oddly specific
I am writing a code that takes the number of values from the user and this will be the array length. Then it will ask the user to input their numbers into the array. Then it uses a function to determine if the given array contains 4 of the same values consecutively.
This is an example output
//example 1
Enter the number of values: 8
Enter the values: 3 4 5 5 5 5 4 5
The list has consecutive fours
//example 2
Enter the number of values: 9
Enter the values: 3 4 5 8 5 5 4 4 5
The list has no consecutive fours
The problem with my code is that I need to make a function bool isConsecutiveFour(int values[][4])for the question to be completed. I have tried that and since the array that I am originally using for the user input is a 1-dimensional array, I don't think I can do it 2 dimensional. When I copy and paste the code all into the main function the code works but once I implement it into a function with the requirements, the code starts to not work as intended. In the place where the function is called, I am aware that there is a expected expression, the thing is that I am unsure on what to put there as the original array is 1D while the one in the given function is 2D.
#include <iostream>
using namespace std;
bool isConsecultiveFour(int values[][4]);
int main(){
int x, input;
cout<<"Enter the number of values: "<< endl;
cin >> x;
int arr[x];
cout<<"Enter the values: "<< endl;
for(int i = 0; i < x; i++){
cin>>input;
arr[i] = input;
}
cout<<" "<< endl;
//error on the second bracket states that it is expecting an expression
isConsecultiveFour(arr[x][]);
return 0;
}
bool isConsecultiveFour(int values[][4]){
int count = 1;
for(int i = 0; i < sizeof(values)/sizeof(values[0]); i++){
if(values[i] == values[i + 1]){
count++;
}
}
if(count == 4 ){
cout<<"The list has consecutive fours"<< endl;
}
else{
cout<<"The list has no consecitive fours"<< endl;
}
return count;
}
You have multiple problems in your code.
The main problem regarding variable-length arrays and size of an array in a function can be solved using std::vector.
The function should return a boolean.
You can leave the loop after the fourth consecutive value
You have to reset the counter if two consecutive values are different.
You don't need to flush the buffer with endl.
You should avoid using namespace std;.
The type of a size of a STL container or array is std::size_t.
The end of the loop was off by one.
#include <iostream>
#include <vector>
bool isConsecutiveFour(std::vector<int> values);
int main(){
std::size_t x;
std::cout<<"Enter the number of values: \n";
std::cin >> x;
std::vector<int> arr(x);
std::cout<<"Enter the values: \n";
for(auto &el : arr){
std::cin>>el;
}
std::cout<<" \n";
isConsecutiveFour(arr);
return 0;
}
bool isConsecutiveFour(std::vector<int> values){
int count = 1;
for(std::size_t i = 0; i + 1 < values.size(); i++){
if(values[i] == values[i + 1]){
count++;
} else {
count = 1;
}
if(count == 4 ){
std::cout<<"The list has consecutive fours\n";
return true;
}
}
std::cout<<"The list has no consecitive fours\n";
return false;
}

Finding 3 or more duplicates in array

I need write a program which checks if there are 3 or more matching numbers in an array. My code works fine until there is an array like "2 2 3 3 5 5 4 4 1 1", then it approves that there are 3 or more duplicates in the array which is not true. Maybe someone knows a simple solution which would help me? Or do I need to overwrite my code?
Here is my code:
#include <iostream>
using namespace std;
void funk(int n, int a[], int &kiek);
int main()
{
int n, a[101],kiek=0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
funk(n, a, kiek);
if (kiek > 2) {
cout << "TAIP";
}
else
cout << "NE";
}
void funk(int n, int a[], int &kiek)//funkcijos kūnas
{
int j;
for (int i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (a[i] == a[j])
kiek++;
cout << kiek;
}
}
}
This is the input:
10
2 2 3 3 5 5 4 4 1 1
This is the output I need to get:
NE
The problem that your code has is:
You are comparing any 2 numbers and never reset the counter. So if there is an 1 1, you are increasing the counter. If there is then an 2 2 you are also increasing the counter. And for the final 3 3 you also increase the same counter. Then it is 3. Although there are only 2 same values. This can never work. What you could do is
Read all values
Count the frequency of EACH different value
Check if the frequency of the values
If any of the counts is greater than 2, then show corresponding message
Show count of each value
I will show you the "more-modern" C++ approach and will use C++ algorithms for the below example solution.
First we will get the number of values to work with from the user. We will store the values in a std::vector. And, we use std::copy_n to copy the values from std::cin to our std::vector. For that we will use the std::istream_iterator that will iterate over the elements given by the user. So, we use a simple one-liner to read all values from the user.
Next is the frequency counting. For this we have a standard solution in C++. You will find it in dozens of places in the net. We will use a std::map. The key is the integer that we read into the vector and the value is the counter. With the std::map's index operator [] we add a value to the map, if it is not yet existing. With the ++ we simply do the counting, whether the value was already in the std::map or has just been added. Also this is a very simple one-liner.
Then, we check, if any of the counts is greater than 2. For this we will use the STL algorithm std::any:of with a very simple lambda. With that, we can create your desired result.
Last, but not least, we show all values and their count, if the count is greater than 2. This we do with an ultra simple range based for loop. We extract the values out of the counter-std::map using structered bindings.
Please see:
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
// Give instructions
std::cout << "How many values do you want do read? Please specify: ";
// Read the number of values to enter
size_t numberOfValues{ 0U }; std::cin >> numberOfValues;
// Read the given number of values from std::cin
std::vector <int> values(numberOfValues);
std::copy_n(std::istream_iterator<int>(std::cin), numberOfValues, values.begin());
// Count each value
std::map<int, size_t> counter{};
std::for_each(values.begin(), values.end(), [&counter](const int& i) { counter[i]++; });
// Check, if any count is bigger than 2
if (std::any_of(counter.begin(), counter.end(), [](const std::pair<int, size_t> & c) { return c.second > 2; }))
std::cout << "TAIP\n";
else
std::cout << "NE\n";
// Look, if there is any number with a count bigger than 2 and show the result
for (const auto& [value, count] : counter)
if (count > 2) std::cout << value << " --> " << count << "\n";
return 0;
}
I hope this gives you an idea on how this could be done . . .

Why am I getting a 'Runtime Error - SIGSEGV' in my code?

I have got some impossible queries for you! (or are they? ;) )
You have n binary numbers of length m. The ith binary number is Bi. Also, you have to perform q queries on them. The indexing is zero-based and the indexing of bits starts from left.
The queries are of type : a, i, j.
If a is:
0 : perform Logical AND operation between Bi and Bj and output the number of 1s in the result.
1 : perform Logical OR operation between Bi and Bj and output the number of 1s in the result.
2 : perform Logical XOR operation between Bi and Bj and output the number of 1s in the result.
3 : flip the value of the jth bit of Bi (i.e. set the bit to 0 if it equals 1 and vice-versa).
Note: For queries of type 0, 1, and 2, the binary numbers remain unchanged.
It is also recommended to use Fast I/O for C++ and JAVA programmers.
Input Format:
First line contains Integers n and m.
The next n lines contain binary numbers of length m.
The ith line contains binary number Bi.
The next line contains an integer q
The next q lines contain queries of type : a, i, j.
Output Format:
Output number of 1s in the result of type 0, 1 and 2 queries.
Constraints:
1<=n, m<=2500
1<=q<=10^6
I have tried changing the array size, but still the error remains the same!
#include <iostream>
#include <math.h>
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n,m;
cin>>n>>m;
char arr[3000][3000];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>arr[i][j];
}
long int q;
cin>>q;
char query[3000][3000];
for(long int k=0;k<q;k++)
for(long int l=0;l<3;l++)
{
cin>>query[k][l];
}
for(long int i=0;i<q;i++)
{
if(int(query[i][0]-48)==3)
{
if(arr[int(query[i][1])-48][int(query[i][2])-48]=='1')
{
arr[int(query[i][1])-48][int(query[i][2])-48]='0';
}
else
{
arr[int(query[i][1])-48][int(query[i][2])-48]='1';
}
}
else if(int(query[i][0]-48)==2)
{
int cntr=0;
int bi=int(query[i][1])-48;
int bj=int(query[i][2])-48;
for(int i=0;i<m;i++)
{
int xorres=arr[bi][i]^arr[bj][i];
if(xorres==1)
cntr++;
}
cout<<cntr<<endl;
}
else if(int(query[i][0]-48)==1)
{
int cntr=0;
int bi=int(query[i][1])-48;
int bj=int(query[i][2])-48;
for(int i=0;i<m;i++)
{
int andres=arr[bi][i]|arr[bj][i];
if(andres-48==1)
cntr++;
}
cout<<cntr<<endl;
}
else if(int(query[i][0]-48)==0)
{
int cntr=0;
int bi=int(query[i][1])-48;
int bj=int(query[i][2])-48;
for(int i=0;i<m;i++)
{
int andres=arr[bi][i]&arr[bj][i];
if(andres-48==1)
cntr++;
}
cout<<cntr<<endl;
}
}
return 0;
}
The two char[3000][3000]'s that you allocate on the stack is the reason for the crash.
Since there's no upper constraint on n you'd better to try to allocate it on the heap and catch the exception if it fails. This can be done by using std::vector<std::vector<char>> instead.
Replace:
int n,m;
cin >> n >> m;
char arr[3000][3000];
With something like this:
#include <vector>
size_t n, m;
std::vector<std::vector<char>> arr;
while(std::cin >> n >> m) {
try {
arr.resize(n, std::vector<char>(m));
break; // success, break out of the while-loop
} catch(const std::exception& ex) {
// exception caught, most probably a bad_alloc
std::cerr << ex.what() << " ... try again\n";
}
}
As proposed in the comments, you probably don't need to store all the queries. Just deal with one query at a time.
Also, never #include <bits/stdc++.h> yourself. It's a non-standard/non-portable header file that includes a lot more than you need, and often not all you need. Instead, only include the headers you actually need.
Similarly, using namespace std; is considered bad practice.
OK, so I think you have complicated some things here.
The size of the queries is 10^6 and you are declaring the array as query[3000][3000].
Now, I don't think you need to store the queries. Consider this-
cin>>q;
while(q--)
{
cin>>a>>i>>j;
/*Your code here*/
}
The question states that the queries are in the form : a i j
So for example if you want to perform operation 0 on first 2 strings, the query will be:
0 1 2
But you are storing the binary numbers from index 0!
So, your code will perform the operation on second and third query. So, what you need to do is just take subtract 1 from values of i and j.

how can we do n nested for loops where n is dynamic [duplicate]

This question already has answers here:
c++ : dynamic number of nested for loops (without recursion)
(3 answers)
Closed 6 years ago.
I have read the following questions but have not found a solution to my problem:
c++ : dynamic number of nested for loops (without recursion)
variable nested for loops
actual problem statement is :-
Job and Jimmy both are playing with numbers. Job gives Jimmy an array of numbers and asks him to tell the minimum possible last number of a non decreasing sequence of length L.
Input Format
First input line consists of a number which is size of array N.
Next line contains N space separated elements of array.
Next line contains length of the non decreasing sequence i.e. L.
Output Format
You have to print the minimum possible last number of a sequence and if their is no non-decreasing sequence of length L, then print -1
Sample Input
7
9 7 2 5 4 11 12
3
Sample Output
11
Explanation
In sample input, possible non-decreasing sequences of length L=3 are (9,11,12) , (7,11,12) , (2,5,11) , (2,4,11) , (2,5,12) , (2,4,12) , (2,11,12) , (5,11,12) , (4,11,12) and the minimum last number is 11 for the sequences (2,5,11) and (2,4,11). Hence, the answer is 11."
my code...
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int fact(int y,int x)
{
static int temp=0;
if(temp==x)
{
temp=0;
return 1;
}
else
{
++temp;
return y*fact((y-1),x);
}
}
int main() {
int num,randmax,n,s,q,w last=-1, minlast=-1;
cin>>n;
vector<int> a(n);
for(int i=0;i<n; i++)
{
cin>>a[i];
}
cin>>s;
vector<vector<int>> c;
q=fact(s);
c.resize(q);
for(int i = 0 ; i < q ; ++i)
{
//Grow Columns by n
a[i].resize(s);
}
w=q;
randmax=n-1;
int k=0;
while(w)
{
for(int i=0 ; i<n ; i++){
}
num=rand()%randmax; // this works perfect as expected
c[][i]=a[num];
}
w--;
}
/*for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
for(int k=j+1;k<n; k++)
{
if((a[i]<=a[j])&&(a[j]<=a[k]))
{
last=a[k];
if(minlast=-1)
{
minlast=a[k];
}
if(last<minlast){
minlast=last;
}
}
}
}
}
*/
cout<<last;
return 0;
}
`
I would tell you what I tried to do... I thought of mapping the data by having them randomly assigned in one of my array and then computing them..
I got lost somewhere in my code...plz gimme an solution to it...and more imp. a good explanation of the same as I got stuck at times when I need a dynamic nested n loop type of thing...
also it would be more helpful if you edit in my code or algo so that I could learn where my mistakes are there...
Thanks in advance for you time...
As the answers your links have pointed out, you can imitate a dynamic amount of for loops by using an array David gives a fine implementation here.
For the actual problem you gave though, I see no need for a dynamic amount of for loops at all. The problem is a standard non-decreasing subsequence problem with a slight variation.
#include <iostream>
#include <fstream>
int N, L;
int arr[100], seq[100];
int bst;
int main() {
std::ifstream file ("c.txt");
file >> N;
for(int n = 0; n < N; ++n)
file >> arr[n];
file >> L;
file.close();
bst = 1e9;
for(int i = 0; i <= N; ++i) seq[i] = 1e9;
for(int i = 0; i < N; ++i)
{
int x = 0;
while(seq[x] < arr[i]) ++x;
seq[x] = arr[i];
if(x + 1 >= L)
bst = std::min(bst, arr[i]);
}
std::cout << bst << std::endl;
return 0;
}
This code should solve your problem. The first part does standard parsing and initialization. The rest is a variation on the LIS problem, which has several standard algorithms that solve it. Here, we just check that whenever we extend an array of length L or longer, we see if the element is smaller than our current.