I'm a newbie and i'm currently making a program that asks the user a number and if the number is a prime it gets stored in a vector, if the vector isn't completed the code doesn't stop. The only problem is that it stores multiples of 5, like 15, 25, 35, etc in it. How can i make it stop storing these multiples of 5? Here is the code:
#include <stdio.h>
int main()
{
int primes[5], num, i, count = 0, x = 0;
do
{
printf ("Type a number: ");
scanf("%d", &num);
for (i = 1; i <= num; i++)
{
if (num % i == 0)
{
count++;
}
}
if (count = 2)
{
primes[x] = num;
x++;
}
}
while (x < 5);
for (x = 0; x < 5; x++)
{
printf("%d ", primes[x]);
}
}
= is the assignment operator, not the equality check operator. You should use == to check if the count is 2:
if (count = 2)
You write
for (i = 1; i<= num; i++)
a prime number is a number that is divisible only by one and itself, your primality test divides your number by all numbers (includind 1 and num itself) so every number (prime or not) will probe to be compound.
Your primality test must start at 2 and end at most at num - 1 to avoid dividing the number by one and by itself (all numbers are divisible by themselves and by one) as in
for (i = 2; i < num; i++)
this should solve your problem... but it will be very inefficient, as you are dividing by all the even numbers, and it is not necessary to divide it by all the even numbers (except for 2 itself) Also, you can stop at a number that is below or equal to sqrt(num), rounded down to the previous integer, because if the number has a factor above that number, for sure you have already found a factor below it (and both multiply pairwise to give you the number).
Also, there's a problem here:
if (count = 2)
This is a valid C statement, but it most probably don't do what you intend, as the = operator is the Assignment Operator, and not the logical equal operator (which is spelled ==) You need to change, because as shown, you are assigning count the value 2, and this is always true, by definition of the assignment operator, if you assign something different than zero, it will result in a true result, so your if will execute allways the body of its true part.
Anyway, many variables it's not clear what you are using them for, (count is one of these) as you assign, increment it, but you don't use its value anywhere (except the if statement above, and in a wrong way)
We were tasked to make a program that accepts ONLY ten inputs from the user and then sort it into an Even or Odd Array.
Accepts 10 inputs.
Segregates to an Even or Odd Array.
Print how many are in the Even/Odd Array.
Print the numbers in each Array.
This is the program I made:
#include<stdio.h>
int main(){
int even[10];
int odd[10];
int number;
int numOdd = 0;
int numEven = 0;
int sizeOdd = 0;
int sizeEven = 0;
int count;
printf("Input numbers:\n");
for(count = 0; count < 10; count++){
scanf("%d", &number);
if (number %2 == 0){
while (numEven < 10){
even[numEven++] = number;
sizeEven++;
}
}
else {
while (numOdd < 10){
odd[numOdd++] = number;
sizeOdd++;
}
}
}
printf("\n\nEven numbers(%d): ", sizeEven);
for(number = 0; number < numEven; number++){
printf("%d, ", even[number]);
}
printf("\n\nOdd numbers(%d): ", sizeOdd);
for(number = 0; number < numOdd; number++){
printf("%d, ", odd[number]);
}
system("pause");
return 0;
}
But my program just outputs the first numbers in the array and repeats it. Like, if I input 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, I get:
Even numbers (10): 2, 2, 2, 2, 2
Odd numbers (10): 1, 1, 1, 1, 1
Am I wrong with everything/my logic in the program? Am I on the right track and I just have to tweak it a bit? Hope for help!
This may help you:
Why do you add that while loop inside the if and else condition:
if (number %2 == 0){
even[numEven++] = number;
Also even[numEven++] itself increses the value of numEven variable no need to increment again in the next line.
You've used while twice, where you should have used if. As a result, your even array will be filled with the first even number entered, and your odd array will be filled with the first odd number.
Change each while to an if and you may be OK, though I haven't checked for other errors. For example...
if (number %2 == 0){
if (numEven < 10){
even[numEven++] = number;
sizeEven++;
}
}
The while keyword defines a complete loop of it's own - it's not a limit on some other kind of repetition such as (in this case) your addition of elements to each array.
BTW - you don't really need the if checks either. You only input 10 items, so at most you can add 10 items to the even array, or 10 items to the odd array. As the arrays are both large enough to take 10 items, you don't need bounds checks in this code.
The while keyword defines a complete loop of it's own - it's not a limit on some other kind of repetition such as (in this case) your addition of elements to each array.
BTW - you don't really need the if checks either. You only input 10 items, so at most you can add
I came across this question on a website. As mentioned there, it was asked in amazon interview. I couldn't figure out a proper solution in given constraint.
Given an array of n integers, find 3 elements such that a[i] < a[j] < a[k] and i < j < k in O(n) time.
So here is how you can solve the problem. You need to iterate over the array three times. On the first iteration mark all the values that have an element greater than them on the right and on the second iteration mark all the elements smaller than them on their left. Now your answer would be with an element that has both:
int greater_on_right[SIZE];
int smaller_on_left[SIZE];
memset(greater_on_rigth, -1, sizeof(greater_on_right));
memset(smaller_on_left, -1, sizeof(greater_on_right));
int n; // number of elements;
int a[n]; // actual elements;
int greatest_value_so_far = a[n- 1];
int greatest_index = n- 1;
for (int i = n -2; i >= 0; --i) {
if (greatest_value_so_far > a[i]) {
greater_on_right[i] = greatest_index;
} else {
greatest_value_so_far = a[i];
greatest_index = i;
}
}
// Do the same on the left with smaller values
for (int i =0;i<n;++i) {
if (greater_on_right[i] != -1 && smaller_on_left[i] != -1) {
cout << "Indices:" << smaller_on_left[i] << ", " << i << ", " << greater_on_right[i] << endl;
}
}
This solution iterates 3 times over the whole array and is therefore linear. I have not provided the whole solution so that you can train yourself on the left to see if you get my idea. I am sorry not to give just some tips but I couldn't figure out how to give a tip without showing the actual solution.
Hope this solves your problem.
One-pass linear time, with O(1) extra space (4 variables). Very efficient (only a couple comparisons/branches per iteration, and not much data shuffling).
This is NOT my original idea or algorithm, I just tidied up and commented the code in an ideone fork. You can add new test-cases to the code there and run it online. The original is by Kenneth, posted in comments on a thread on www.geeksforgeeks.org. Great algorithm, but the original implementation had some really silly code outside of the actual loop. (e.g., instead of local variables, lets use two member-variables in a class, and implement the function as a member-function of class Solution... And the variable-names sucked. I went for quite verbose ones.)
Kenneth, if you want to post your code as an answer, go ahead. I'm not trying to steal credit for the algo. (I did put some work into writing up this explanation, and thinking through why it works, though.)
The main article above the discussion thread has the same solution as Ivaylo Strandjev's answer. (The main-article's code is what Pramod posted as an answer to this question, months after Ivalyo's answer. That's how I found the interesting answers in comments there.)
Since you only need to find a solution, not all of them, there aren't as many corner cases as you'd expect. It turns out you don't need to keep track of every possible start and middle value you've seen, or even backtrack at all, if you choose the right things to keep as state.
The main tricks are:
The last value in a sequence of monotonically decreasing values is the only one you need to consider. This applies to both first(low) and second(mid) candidate elements.
Any time you see a smaller candidate for a middle element, you can start fresh from there, just looking for either a final element or an even better mid-candidate.
If you didn't already find a sequence of 3 increasing elements before an element smaller than your current mid-candidate, min-so-far and the new smaller middle-candidate are as good (as forgiving, as flexible) as you can do out of the numbers you've already checked. (See the comments in the code for a maybe-better way of phrasing this.)
Several other answers make the mistake of starting fresh every time they see a new smallest or largest element, rather than middle. You track the current min that you've seen, but you don't react or make use of it until you see a new middle.
To find new candidate middle elements, you check if they're smaller than the current middle-candidate, and != min element seen so far.
I'm not sure if this idea can be extended to 4 or more values in sequence. Finding a new candidate 3rd value might require tracking the min between the current candidate second and third separately from the overall min. This could get tricky, and require a lot more conditionals. But if it can be done correctly with constant-size state and one pass without backtracking, it would still be linear time.
// Original had this great algorithm, but a clumsy and weird implementation (esp. the code outside the loop itself)
#include <iostream>
#include <vector>
using namespace std;
//Find a sorted subsequence of size 3 in one pass, linear time
//returns an empty list on not-found
vector<int> find3IncreasingNumbers(int * arr, int n)
{
int min_so_far = arr[0];
int c_low, c_mid; // candidates
bool have_candidates = false;
for(int i = 1; i < n; ++i) {
if(arr[i] <= min_so_far) // less-or-equal prevents values == min from ending up as mid candidates, without a separate else if()continue;
min_so_far = arr[i];
else if(!have_candidates || arr[i] <= c_mid) {
// If any sequence exists with a middle-numbers we've already seen (and that we haven't already finished)
// then one exists involving these candidates
c_low = min_so_far;
c_mid = arr[i];
have_candidates = true;
} else {
// have candidates and arr[i] > c_mid
return vector<int> ( { c_low, c_mid, arr[i] } );
}
}
return vector<int>(); // not-found
}
int main()
{
int array_num = 1;
// The code in this macro was in the original I forked. I just put it in a macro. Starting from scratch, I might make it a function.
#define TRYFIND(...) do { \
int arr[] = __VA_ARGS__ ; \
vector<int> resultTriple = find3IncreasingNumbers(arr, sizeof(arr)/sizeof(arr[0])); \
if(resultTriple.size()) \
cout<<"Result of arr" << array_num << ": " <<resultTriple[0]<<" "<<resultTriple[1]<<" "<<resultTriple[2]<<endl; \
else \
cout << "Did not find increasing triple in arr" << array_num << "." <<endl; \
array_num++; \
}while(0)
TRYFIND( {12, 11, 10, 5, 6, 2, 30} );
TRYFIND( {1, 2, 3, 4} );
TRYFIND( {4, 3, 1, 2} );
TRYFIND( {12, 1, 11, 10, 5, 4, 3} );
TRYFIND( {12, 1, 11, 10, 5, 4, 7} );
TRYFIND( {12, 11, 10, 5, 2, 4, 1, 3} );
TRYFIND( {12, 11, 10, 5, 2, 4, 1, 6} );
TRYFIND( {5,13,6,10,3,7,2} );
TRYFIND( {1, 5, 1, 5, 2, 2, 5} );
TRYFIND( {1, 5, 1, 5, 2, 1, 5} );
TRYFIND( {2, 3, 1, 4} );
TRYFIND( {3, 1, 2, 4} );
TRYFIND( {2, 4} );
return 0;
}
Making a CPP macro which can take an initializer-list as a parameter is ugly:
Is it possible to pass a brace-enclosed initializer as a macro parameter?
It was very much worth it to be able to add new test-cases easily, though, without editing arr4 to arr5 in 4 places.
I posted another approach to resolve it here.
#include<stdio.h>
// A function to fund a sorted subsequence of size 3
void find3Numbers(int arr[], int n)
{
int max = n-1; //Index of maximum element from right side
int min = 0; //Index of minimum element from left side
int i;
// Create an array that will store index of a smaller
// element on left side. If there is no smaller element
// on left side, then smaller[i] will be -1.
int *smaller = new int[n];
smaller[0] = -1; // first entry will always be -1
for (i = 1; i < n; i++)
{
if (arr[i] < arr[min])
{
min = i;
smaller[i] = -1;
}
else
smaller[i] = min;
}
// Create another array that will store index of a
// greater element on right side. If there is no greater
// element on right side, then greater[i] will be -1.
int *greater = new int[n];
greater[n-1] = -1; // last entry will always be -1
for (i = n-2; i >= 0; i--)
{
if (arr[i] > arr[max])
{
max = i;
greater[i] = -1;
}
else
greater[i] = max;
}
// Now find a number which has both a greater number on
// right side and smaller number on left side
for (i = 0; i < n; i++)
{
if (smaller[i] != -1 && greater[i] != -1)
{
printf("%d %d %d", arr[smaller[i]],
arr[i], arr[greater[i]]);
return;
}
}
// If we reach number, then there are no such 3 numbers
printf("No such triplet found");
return;
}
// Driver program to test above function
int main()
{
int arr[] = {12, 11, 10, 5, 6, 2, 30};
int n = sizeof(arr)/sizeof(arr[0]);
find3Numbers(arr, n);
return 0;
}
Just for fun:
In JAVA:
List<Integer> OrderedNumbers(int[] nums){
List<Integer> res = new LinkedList<>();
int n = nums.length;
//if less then 3 elements, return the empty list
if(n<3) return res;
//run 1 forloop to determine local min and local max for each index
int[] lMin = new int[n], lMax = new int[n];
lMin[0] = nums[0]; lMax[n-1] = nums[n-1];
for(int i=1; i<n-1; i++){
lMin[i] = Math.min(lMin[i-1], nums[i]);
lMax[n-i-1] = Math.max(lMax[n-i],nums[n-i-1]);
}
//if a condition is met where min(which always comes before nums[i] and max) < nums[i] < max, add to result set and return;
for(int i=1; i<n-1; i++){
if(lMin[i]<nums[i] && nums[i]<lMax[i]){
res.add(lMin[i]);
res.add(nums[i]);
res.add(lMax[i]);
return res;
}
}
return res;
}
This problem is very similar to computing the longest increasing subsequence, with the constraint that size of this subsequence must necessarily be equal to three. The LIS problem (with O(nlog(n)) solution) can easily be modified for this specific problem. This solution has O(n) single pass complexity with O(1) space.
This solution requires that only unique elements occur in the list. We use an online solution. As we encounter any new element, it has potential to extend the present most optimum subsequence or start a new subsequence. In this case, as the maximum length of increasing subsequence is three, any new element currently being processed can either extend a sequence of size 2 to 3 and 1 to 2. So we maintain active lists containing the most optimum elements.
In this particular problem, the maximum number of active lists we have to maintain are 2 - one of size 2 and another of size 1. As soon as we hit a list with size 3, we have our answer. We make sure each active list terminates with minimum number. For more detailed explanation of this idea, refer this.
At any point of time in the online solution, these two active lists will store the most efficient values of the list - the end of the list will be smallest element that can be placed there. Suppose the two lists are:
Size 2 list => [a,b]
Size 1 list => [c]
The initial list can be easily written (refer to the code below). Suppose the next number to be entered is d. Then cases (cascading in execution) are as follows:
Case 1: d > b.
We have our answer in this case, as a < b < d.
Case 2: b > d > a. In this the list of size 2 can be optimally represented by having end as d instead of b, as every element occurring after d greater than b will also be greater than d. So we replace b by d.
Case 3: d < c. As Case 1 and 2 fails, it automatically implies that d < a. In such a case, it may start a new list with size one. The list with size one is compared to get the most efficient active list. If this case is true, we replace c by d.
Case 4: Otherwise. This case implies that d < b and c < d. In such a case, the list of size 2 is inefficient. So we replace [a, b] by [c, d].
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int two_size_first;
int two_size_mid;
int one_size;
int end_index;
vector<int> arr;
Solution(int size) {
end_index = two_size_mid = two_size_first = one_size = -1;
int temp;
for(int i=0; i<size; i++) {
cin >> temp;
arr.push_back(temp);
}
}
void solve() {
if (arr.size() < 3)
return;
one_size = two_size_first = arr[0];
two_size_mid = INT_MAX;
for(int i=1; i<arr.size(); i++) {
if(arr[i] > two_size_mid) {
end_index = i;
return;
}
else if (two_size_first < arr[i] && arr[i] < two_size_mid) {
two_size_mid = arr[i];
}
else if (one_size > arr[i]) {
one_size = arr[i];
}
else {
two_size_first = one_size;
two_size_mid = arr[i];
}
}
}
void result() {
if (end_index != -1) {
cout << two_size_first << " " << two_size_mid << " " << arr[end_index] << endl;
}
else {
cout << "No such sequence found" << endl;
}
}
};
int main(int argc, char const *argv[])
{
int size;
cout << "Enter size" << endl;
cin >> size;
cout << "Enter " << size << " array elements" << endl;
Solution solution(size);
solution.solve();
solution.result();
return 0;
}
My Approach - O(N) time two passes O(1) space with two variables used
for each element of the array we visit we maintain the minimum possible to its left to check for whether this element may be the middle element and also keep record of minimum middle element to its left to check for whether this element may be a candidate third element or it may form a middle element with lower value than found so far.Initailise min so far and middle so far to INT_MAX,
Fr each element thus we have to check :
If a particular array element is greater than the minimum of middle element so far than this array element is the answer with thi as the third element and the min middle element as the mid element(We will have to search for the third element afterward by one pass)
Else If a particular array element is greater than the minimum so far than this element could be a candidate middle element and now we have to check if the candidate middle element is less than the current middle element if so update the current middle element
ELSE If a particular array element is less than the minimum so far then update the minimum so far with arr[i] .
So this way for each element of the array we visit we maintain the minimum possible to its left to check for whether this element may be the middle element and also keep record of minimum middle element to its left to check for whether this element may be a candidate third element or it may form a middle element with lower value than found so far.
#include
using namespace std;
int main()
{
int i,j,k,n;
cin >> n;
int arr[n];
for(i = 0;i < n;++i)
cin >> arr[i];
int m = INT_MAX,sm = INT_MAX,smi;// m => minimum so far found to left
for(i = 0;i < n;++i)// sm => smallest middle element found so far to left
{
if(arr[i]>sm){break;}// This is the answer
else if(arr[i] < m ){m = arr[i];}
else if(arr[i] > m){if(arr[i]<sm){sm = arr[i];smi = i;}}
else {;}
}
if((i < n)&&(arr[i]>sm))
{
for(j = 0;j < smi;++j){if(arr[j] < sm){cout << arr[j] << " ";break;}}
cout << sm << " " << arr[i]<< endl;
}
else
cout << "Such Pairs Do Not Exist" << endl;
return 0;
}
Here is my O(n) solution with O(1) space complexity:-
Just a function which returns a vector consisiting of three values(if exixts)
`vector<int> find3Numbers(vector<int> A, int N)
{
int first=INT_MAX,second=INT_MAX,third=INT_MAX,i,temp=-1;
vector<int> ans;
for(i=0;i<N;i++)
{
if(first!=INT_MAX&&second!=INT_MAX&&third!=INT_MAX)
{
ans.push_back(first);
ans.push_back(second);
ans.push_back(third);
return ans;
}
if(A[i]<=first)
{
if(second!=INT_MAX)
{
if(temp==-1)
{
temp=first;
}
first=A[i];
}
else
{
first=A[i];
}
}
else if(A[i]<=second)
{
second=A[i];
temp=-1;
}
else
{
if(temp!=-1)
{
first=temp;
}
third=A[i];
}
}
if(first!=INT_MAX&&second!=INT_MAX&&third!=INT_MAX)
{
ans.push_back(first);
ans.push_back(second);
ans.push_back(third);
return ans;
}
return ans;
}`
Here is O(n) time and O(1) space complexity solution for this problem
bool increasingTriplet(vector<int>& a) {
int i,n=a.size(),first=INT_MAX,second=INT_MAX;
if(n<3)
return false;
for(i=0;i<n;i++)
{
if(a[i]<=first)
first = a[i];
else if(a[i]<=second)
second = a[i];
else
return true;
}
return false;
}
This function returns true if there exists a pair of 3 elements which are in sorted increasing order in array.
You can also modify this function to print all 3 elements or their indexes. Just update their indexes as well along with variable first and second.
My solution below.
public boolean increasingTriplet(int[] nums) {
int min1 = Integer.MAX_VALUE;
int min2 = Integer.MAX_VALUE;
for (int i =0; i<nums.length; i++) {
if (nums[i]<min1) {
min1 = nums[i];
} else if (nums[i]<min2 && nums[i]>min1) {
min2=nums[i];
} else if (nums[i]>min2) {
return true;
}
}
return false;
}
Try to create two variables:
1. index_sequence_length_1 = index i such
a[i] is minimal number
2. index_sequence_length_2 = index j such
There is index i < j such that a[i] < a[j] and a[j] is minimal
Iterate over whole array and update this variables in each iteration.
If you iterate over element that is greater than a[index_sequence_length_2], than you found your sequence.
Sorry, i couldn't resist but to solve the puzzle...
Here is my solution.
//array indices
int i, j, k = -1;
//values at those indices
int iv, jv, kv = 0;
for(int l=0; l<a.length(); l++){
//if there is a value greater than the biggest value
//shift all values from k to i
if(a[l]>kv || j == -1 || i == -1){
i = j;
iv = jv;
j = k;
jv = kv
kv = a[l]
k = l
}
if(iv < jv && jv < kv && i < j && j < k){
break;
}
}
Iterate once and done:
public static int[] orderedHash(int[] A){
int low=0, mid=1, high=2;
for(int i=3; i<A.length; i++){
if(A[high]>A[mid] && A[mid]>A[low])
break;
if(A[low]>A[i])
low=mid=high=i;
else if(low == mid && mid == high)
mid = high = i;
else if(mid == high){
if(A[high]<A[i])
high = i;
else
mid = high = i;
}
else if(A[mid]<A[i])
high = i;
else if( A[high]<A[i]){
mid = high;
high =i;
}
else
mid=high=i;
}
return new int[]{A[low],A[mid],A[high]};
}//
Then test with main:
public static void main(String[] args) {
int[][] D = {{1, 5, 5, 3, 2, 10},
{1, 5, 5, 6, 2, 10},
{1, 10, 5, 3, 2, 6, 12},
{1, 10, 5, 6, 8, 12, 1},
{1, 10, 5, 12, 1, 2, 3, 40},
{10, 10, 10, 3, 4, 5, 7, 9}};
for (int[] E : D) {
System.out.format("%s GIVES %s%n", Arrays.toString(E), Arrays.toString(orderedHash(E)));
}
}
What if you build a max-heap O(n) and then do Extract-Max O(1) 3 times?
Here is a solution with only one iteration.
I am using stack to compute for each index k whether there exists two other indices i & j such that a[i] < a[j] < a[k].
bool f(vector<int> a) {
int n = a.size();
stack<int> s;
for (int i = 0; i < n; ++i)
{
while(!s.empty() and a[s.top()]>=a[i]){
s.pop();
}
if (s.size()>=2) // s.size()>=k-1
{
return 1;
}
s.push(i);
}
return 0;
}
And important thing is that we can extend this problem to M such indices in the general case instead of k indices.