Find overlapping numbers in C++ - c++

I have the code that does not exactly work and cannot find the edge case here:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int meetings;
cin >> meetings;
vector<int> start(meetings);
vector<int> end(meetings);
for (int i = 0; i < meetings; i++) {
cin >> start[i] >> end[i];
}
int overlap = meetings;
for (int i = 0; i < meetings; i++) {
for (int j = i+1; j < meetings; j++) {
if (start[i] < end[j] && start[j] < end[i]) {
overlap--;
}
}
}
cout << overlap << endl;
return 0;
}
Basically, I need to have the user input like this:
3 - number of cases
10 20 - case 1 - start and end
12 25 - case 2
20 30 - case 3
Output:
Number of non overlapping meetings: 2 (case 2 is overlapping with case 1; but case 1 and case 3 are fine).
What am I missing here?
Edit: sorted the pair vectors as suggested and then it was easy. Cheers

As others have noted int start[meetings] is not valid C++ (although many compilers have extentions that allow it), it should be replaced by either std::vector<int> start(meetings) (needs #include<vector>) but other solutions are also available.
Now to the logic of your program: it is possible that intervals can overlap with more of one other interval, but the break inside the if statement breaks the inner loop when the first one is encountered, missing the ones after.
Also, it seems you're assuming the intervals are sorted

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';
}
}

What does this variable do?

One day, Twilight Sparkle is interested in how to sort a sequence of
integers a1, a2, ..., an in non-decreasing order. Being a young
unicorn, the only operation she can perform is a unit shift. That is,
she can move the last element of the sequence to its beginning:
a1, a2, ..., an → an, a1, a2, ..., an - 1. Help Twilight Sparkle to
calculate: what is the minimum number of operations that she needs to
sort the sequence?
Input
The first line contains an integer n (2 ≤ n ≤ 105). The second
line contains n integer numbers a1, a2, ..., an (1 ≤ ai ≤ 105).
Output
If it's impossible to sort the sequence output -1. Otherwise
output the minimum number of operations Twilight Sparkle needs to sort
it.
Examples
input
2
2 1
output
1
input
3
1 3 2
output
-1
input
2
1 2
output
0
Above is the problem and now I am confused because the solution down there used a variable called "s" and played around it for some reason but I don't know why was that variable used, if someone can tell me I'll be thankful.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, s, v(0);
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n - 1; i++) if (a[i] > a[i + 1]) s = i, v++;
if (a[n - 1] > a[0]) s = n - 1, v++;
if (v == 0) cout << 0 << endl;
else if (v > 1) cout << -1 << endl;
else cout << n - 1 - s << endl;
return 0;
}
Now here is my own solution, it works and everything except on a 10^5(and around that) size array but the question time limit is only 1000 ms, and mine exceeds that limit due to the nested loops making it go over O(10^8) which is 1000 ms on their systems.
#include <bits/stdc++.h>
#define fl(i,n) for(int i = 0; i < n; i++)
#define ll long long
#define nl endl
#define pb push_back
#define mp make_pair
#define PII pair<int,int>
#define EPS 1e-9
#define INF 1e9
using namespace std;
bool check(int a[], int n){
for(int i = 0; i < n-1; i++){
if(a[i] <= a[i+1]) continue;
return false;
}
return true;
}
int main()
{
int n;
cin >> n;
int a[n]; //is out of standard i know but it's accepted in the contest's compiler so we just use it
for(int i = 0; i < n; i++){
cin >> a[i];
}
if(check(a,n)){
cout << 0;
return 0;
}
int ret = 0;
for(int i = 0; i < n-1; i++){
ret++;
for(int j = n-1; j > 0; j--)
a[j] ^= a[j-1] ^= a[j] ^= a[j-1]; //is xor swap
if(check(a,n)){
cout << ret;
return 0;
}
}
cout << -1;
return 0;
}
PS: I TRACED the solution's code and even if I get the correct answers I simply don't know what it refers to.
The other person's implementation relies on an algorithmic insight. The only way a sequence can be sorted by moving back to front is if the sequence is made of two already-sorted sections. Then, the goal is to check how many unsorted discontinuities exist, and where they are. That's what s appears to be used for: the index of the (last) discontinuity of the sequence. v is the count of discontinuities.
If there are 0, it's already sorted. If more than 1, it's unsortable. If it's exactly one, then you can easily figure out how many shifts you need to perform to pull the discontinuity back to the front, using it's location (s) in the original sequence.
The only extra line of code is the special case of checking for the discontinuity around end of the sequence.
My recommendation: Generate a larger set of test sequences, and print v and s for each one.

Sieve of Eratosthenes C++ Infinite Loop

So, I've been working through a problem in Bjarne Stroustrup's Programming: Principles and Practices Using C++ for my own benefit, and this problem has stumped me for a couple of days now.
I'm supposed to implement the classic Sieve of Eratosthenes algorithm with the tools learned by chapter 4 (that's not a lot) and this is what I have so far:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
int p = 2;
int n = 0;
vector<int> nums{ 1, 1 };
cout << "Enter an integer greater than 1:\n";
cin >> n;
for (int i = 2; i <= n; ++i)
nums.push_back(0);
while (p < sqrt(n))
{
for (int i = 2; (i*p) <= n; ++i)
{
nums[i*p] = 1;
}
for (int i = (p+1); i <= n; ++i)
{
if (nums[i] == 0)
{
p = i;
break;
}
}
}
for (int i = 0; i <= n; ++i)
{
if (nums[i] == 0)
cout << i << '\n';
}
return 0;
}
This code is SOOO close to working but no cigar. It only prints the prime numbers after and including 5, it does not print 2 or 3. I know that the problem is due to the fact that my marking loop is marking nums[2] and nums[3], so I tried to add the following line of code to insure that 2 and 3 were unmarked, because they were used as the p starting values:
nums[p] = 0;
I put that line in-between the two for-loops nested within the while-loop. I have no idea how, but that somehow causes an infinite loop that I've tried for hours to fix. I'm really at my wit's end here.
NOTE: I've been testing this with n = 23.
So, after fixing your first loop starting point, the issue is the next loop.
Because the next loop always starts at 0 and looks for the next prime number, it is going to always find 2, and that will cause an infinite loop.
To solve this issue, start your search for the next prime, from the previous value:
for(int i = p + 1; i <= n; ++i)

Prime number finder cannot find prime, stops after 7

So I made a simple prime number finder for the numbers between 3 and 200. It has to use a boolean variable, just fyi. No errors occur. output is:
The prime numbers between 3 and 200 are:
3
5
7
Why does it not keep going? I have drawn it out on paper time and again and cannot find my logic error.
In addition; I wrote this out by hand because I do not know how to get the contents of my file. It exists on a remote host which I do not have root access to. Is there a better way to copy the file?
#include <iostream>
using namespace std;
int main()
{
int count=0;
cout<<"The prime numbers between 3 and 200 are: "<<endl;
for (int i=3;i<=200;i++)
{
for (int j=2;j<i;j++)
{
bool ptest=i%j;
if (!ptest)
{
break;
}
else if (ptest)
{
count=count+1;
if (count==(i-2))
cout<<i<<endl;
}
}
}
}
You forgot to set count back to 0 after using it in the j loop. Move the line:
int count = 0;
to be inside the first for loop. Then your program works correctly (although as msw indicated, it is not the most efficient technique!)
Some things to consider:
You don't need to consider any even numbers in your code.
You have some logic errors in your code. The value of count needs to be checked after the second for loop. count needs to be reset before the second for loop begins.
You can stop immediately after you find the number is not prime in the inner loop instead of continuing on. You can just use a flag isPrime instead of counting.
Here's a version of the code that works for me:
#include <iostream>
using namespace std;
int main()
{
cout << "The prime numbers between 3 and 200 are: " <<endl;
for (int i=3; i <= 200; i += 2) {
bool isPrime = true;
for (int j=3; j < i; j += 2) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime)
{
cout << i << endl;
}
}
}
You don't have to loop till j reach i, instead you can check if j < sqrt(i) ,i.e. write in the second for loop: for (int j=3; j*j<=i; j+=2)

Need help optimizing a program that finds all possible substrings

I have to find all possible, unique substrings from a bunch of user-input strings. This group of substrings has to be alphabetically sorted without any duplicate elements, and the group must be queryable by number. Here's some example input and output:
Input:
3 // This is the user's desired number of strings
abc // So the user inputs 3 strings
abd
def
2 // This is the user's desired number of queries
7 // So the user inputs 2 queries
2
Output:
// From the alphabetically sorted group of unique substrings,
bd // This is the 7th substring
ab // And this is the 2nd substring
Here's my implementation:
#include <map>
#include <iostream>
using namespace std;
int main() {
int number_of_strings;
int number_of_queries;
int counter;
string current_string;
string current_substr;
map<string, string> substrings;
map<int, string> numbered_substrings;
int i;
int j;
int k;
// input step
cin >> number_of_strings;
string strings[number_of_strings];
for (i = 0; i < number_of_strings; ++i)
cin >> strings[i];
cin >> number_of_queries;
int queries[number_of_queries];
for (i = 0; i < number_of_queries; ++i)
cin >> queries[i];
// for each string in 'strings', I want to insert every possible
// substring from that string into my 'substrings' map.
for (i = 0; i < number_of_strings; ++i) {
current_string = strings[i];
for (j = 1; j <= current_string.length(); ++j) {
for (k = 0; k <= current_string.length()-j; ++k) {
current_substr = current_string.substr(k, j);
substrings[current_substr] = current_substr;
}
}
}
// my 'substrings' container is now sorted alphabetically and does
// not contain duplicate elements, because the container is a map.
// but I want to make the map queryable by number, so I'm iterating
// through 'substrings' and assigning each value to an int key.
counter = 1;
for (map<string,string>::iterator it = substrings.begin();
it != substrings.end(); ++it) {
numbered_substrings[counter] = it->second;
++counter;
}
// output step
for (i = 0; i < number_of_queries; ++i) {
if (queries[i] > 0 && queries[i] <= numbered_substrings.size()) {
cout << numbered_substrings[queries[i]] << endl;
} else {
cout << "INVALID" << endl;
}
}
return 0;
}
I need to optimize my algorithm, but I'm not sure how to do it. Maybe it's the fact that I have a second for loop for assigning new int keys to each substring. Help?
Check out Suffix tree. It usually runs in O(n) time:
This article was helpful for me:
http://allisons.org/ll/AlgDS/Tree/Suffix/
Minor notes:
1. include <string>
2. careful with those } else {; one day you'll have a lot of else if branches
and a lot of lines and you'll wonder where an if starts and where it ends
3. careful with unsigned versus signed mismatching... again, one day it will
come back and bite (also, it's nice to compile without errors or warnings)
4. don't try to define static arrays with a variable size
5. nice with ++ i. not many know it has a slight performance boost
(maybe not noticeable with today's processors but still)
While I do agree that using proper algorithms when needed (say bubble sort, heap sort etc. for sorting, binary search, binary trees etc. for searching), sometimes I find it nice to do an optimization on current code. Imagine having a big project and implementing something requires rewrites... not many are willing to wait for you (not to mention the required unit testing, fat testing and maybe fit testing). At least my opinion. [and yes, I know some are gonna say that if it is so complicated then it was written badly from the start - but hey, you can't argue with programmers that left before you joined the team :P]
But I do agree, using existing stuff is a good alternative when called for. But back to the point. I tested it with
3, abc, def, ghi
4, 1, 3, 7, 12
I can't say whether yours is any slower than mine or vice-versa; perhaps a random string generator that adds maybe 500 inputs (then calculates all subs) might be a better test, but I am too lazy at 2 in the morning. At most, my way of writing it might help you (at least to me it seems simpler and uses less loops and assignments). Not a fan of vectors, cos of the slight overhead, but I used it to keep up with your requirement of dynamic querying... a static array of a const would be faster, obviously.
Also, while not my style of naming conventions, I decided to use your names so you can follow the code easier.
Anyway, take a look and tell me what you think:
#include <map>
#include <iostream>
#include <string> // you forgot to add this... trust me, it's important :)
#include <vector> // not a fan, but it's not that bad IF you want dynamic buffers
#include <strstream>
using namespace std;
int main ()
{
unsigned int number_of_strings = 0;
// string strings[number_of_strings]; // don't do this... you can't assign static arrays of a variable size
// this just defaults to 0; you're telling the compiler
cin >> number_of_strings;
map <string, string> substrings;
string current_string, current_substr;
unsigned int i, j, k;
for (i = 0; i < number_of_strings; ++ i)
{
cin >> current_string;
substrings[current_string] = current_string;
for (j = 1; j <= current_string.length(); ++ j)
{
for (k = 0; k <= current_string.length() - j; ++ k)
{
current_substr = current_string.substr(k, j);
substrings[current_substr] = current_substr;
}
}
}
vector <string> numbered_substrings;
for (map <string, string>::iterator it = substrings.begin(); it != substrings.end(); ++ it)
numbered_substrings.push_back(it->second);
unsigned int number_of_queries = 0;
unsigned int query = 0;
cin >> number_of_queries;
current_string.clear();
for (i = 0; i < number_of_queries; ++ i)
{
cin >> query;
-- query;
if ((query >= 0) && (query < numbered_substrings.size()))
current_string = current_string + numbered_substrings[query] + '\n';
else
cout << "INVALID: " << query << '\n' << endl;
}
cout << current_string;
return 0;
}