Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
intent is to create an array of random numbers, and sort them in ascending order
array is created, but sorting does not work (numbers are printed in random order)
have i incorrectly applied sorting by reference?
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
void mySort(long x[])
{
long min(0), temp(0), minPosition(0), i(0), j(0);
min = x[0];
for (j = 0; j < 10; j++)
{
for (i = j; i < 10; i++)
{
if (x[i] < min)
{
min = x[i];
minPosition = i;
}
}
temp = x[minPosition];
x[minPosition] = x[j];
x[j] = temp;
}
}
int main()
{
long *myArray = new long[10];
int i(0);
srand((unsigned int)time(NULL));
for (i = 0; i < 10; i++)
{
myArray[i] = rand()%11;
}
mySort(myArray);
for (i = 0; i < 10; i++)
{
cout<<'['<<myArray[i]<<']'<<endl;
}
return 0;
}
One thing that stands out is that you need to reset min and minPosition every time your outer loop kicks off. At the moment, things will go badly wrong from the second iteration onwards.
Also, be aware that this (selection sort) is a rather inefficient way to sort a list. It runs in O(n^2) time, rather than O(n log n), which is what good sorting algorithms do (Quicksort, Heapsort, Mergesort).
Well if you dont know how to sort ...you can use sort() function as
// sort() Example using arrays.
#include <iostream>
#include <algorithm>
using namespace std;
const int SIZE = 7;
int main()
{
int intArray[SIZE] = {5, 3, 32, -1, 1, 104, 53};
//Now we call the sort function
sort(intArray, intArray + SIZE);
cout << "Sorted Array looks like this." << endl;
for (size_t i = 0; i != SIZE; ++i)
cout << intArray[i] << " ";
return 0;
}
Found in ~ #include <algorithm>
Parameter 1 myvector.begin() ~ The first parameter is where you will be putting a iterator(Pointer) to the first element in the range that you want to sort. The sort will include the element that the iterator points to.
Parameter 2 myvector.end() ~ The second parameter is almost like the first but instead of putting a iterator to the first element to sort you will be putting a iterator to the last element. One very important difference is that the search won’t include the element that this iterator points to. It is [First,Last) meaning it includes the first parameter in the sort but it doesn’t include the second parameter in the sort.
Parameter 3 myCompFunction() Optional ~ The third parameter is used to define how you do the search. For example if you have a struct that has 3 different variables in it.
Related
This question already has answers here:
Random array generation with no duplicates
(9 answers)
Closed 5 years ago.
I want to generate random numbers and save them in an array. that' all ! but here is the point, I want to avoid duplicating and not having a number two or more times in array.
my code :
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
int k, temp;
cin >> k;
int sym[k];
srand(time(NULL));
for (int i = 0; i < k; i++)
{
temp = rand() % 25 + 97;
for(int j=0; j<i; j++)
{
while(temp == sym[j])
{
temp = rand() % 25 + 97; // 25 means a and 122 means z
}
}
sym[i] = temp;
}
for(int i=0; i<k; i++)
{
cout << sym[i] << endl;
}
return 0;
}
I still get duplicated results.
I will use std::unordered_set to avoid duplicated
Random generator doesn't mean unique generation, collisions can always happen especially when the number of generated values is high and the bounds or limits for the generation is small...
to avoid duplicated elements replace this array
int sym[k];
by a set which is a container that doesn't allow duplicate entries...
std::set<int>
after that, you need to replace the logic because looping k times does not mean having k elements in the set, so you need to do a while loop until the size of the set reaches the limit k
Edit:
if you need some unsorted generated values, the instead of using a set, consider implementing an unordered_set
This is a question from Codechef but please bear with me.
https://www.codechef.com/ZCOPRAC/problems/ZCO12004
The contest is for the preparation of the Zonal Computing Olympiad held in India, so its not a competitive contest from which I'd earn something as such. Just need a little help to see what is wrong with my code, because I have a feeling I've overlooked something big and stupid. :P
The problem basically states:
Imagine there is a vector or array such that the last element is
linked to the first one. Find the lowest possible sum from adding at
least one of each adjacent pairs of elements. (refer to link please)
So answer for {1,2,1,2,2} output would be 4 by adding 1+1+2.
Here is my solution:
Basically what it does is that it iterates backwards, from the end of the vector to the beginning, and stores the lowest possible sum that can be achieved from that vector onwards, in vector M. Done using dynamic programming, basically.
The first two elements of M are the possible answers. Then I do some checks to see which is possible. If M[1] is less than M[0] then the last element of the array/vector should have been included in the sum calculated in M[1].
#include <algorithm>
#include <iostream>
#include <vector>
#define print(arr) for(auto pos = arr.begin(); pos != arr.end(); ++pos) cout << *pos << " "; cout << endl;
typedef long long int ll;
using namespace std;
int main() {
int N;
ll x;
cin >> N;
vector <ll> A;
vector <ll> M(N+2);
fill(M.begin(),M.end(),0);
for (int i = 0; i < N; i++) {
cin >> x;
A.push_back(x);
}
for (int i = N-1; i >= 0; i--) {
M[i] = A[i]+*min_element(M.begin()+i+1, M.begin()+i+3);
}
if (M[0] <= M[1]) cout << M[0] << endl;
else if (M[1] < M[0]) {
if (M[N-1] <= (M[N-2])) cout << M[1] << endl;
else cout << M[0] << endl;
}
}
However, I could not pass 2 of the test cases in subtask 2. I think the last part of my code is incorrect. Any idea what I could be doing wrong? Either that, or I have misunderstood the question. The term "adjacent pairs" is sort of ambiguous. So if there are 4 numbers 3,4,5,6 does adjacent pairs mean adjacent pairs to be {(3,4) (4,5) (5,6) (6,3)} or {either (3,4) and (5,6) or (4,5) and (6,3)}? My code considers the former.
EDIT:
Thanks a lot #User_Targaryen cleared some doubts about this question! Basically my implementation was the same as yours as my idea behind using dynamic programming was the same. Only that in this case my M (your dp) was the reverse of yours. Anyway I got AC! :) (I had left some silly debugging statements and was wondering for 15 mins what went wrong xD) Updated solution:
#include <algorithm>
#include <iostream>
#include <vector>
#define print(arr) for(auto pos = arr.begin(); pos != arr.end(); ++pos) cout << *pos << " "; cout << endl;
typedef long long int ll;
using namespace std;
int main() {
int N;
ll x, sum = 0;
cin >> N;
vector <ll> A;
vector <ll> M(N+2);
fill(M.begin(),M.end(),0);
for (int i = 0; i < N; i++) {
cin >> x;
A.push_back(x);
}
for (int i = N-1; i >= 0; i--) {
M[i] = A[i]+*min_element(M.begin()+i+1, M.begin()+i+3);
}
//print(M);
reverse(A.begin(), A.end());
vector <ll> M2(N+2);
fill(M2.begin(),M2.end(),0);
for (int i = N-1; i >= 0; i--) {
M2[i] = A[i]+*min_element(M2.begin()+i+1, M2.begin()+i+3);
}
//print(M2);
cout << min(M[0], M2[0]) << endl;
}
I am attaching my accepted solution here:
#include<iostream>
using namespace std;
int main()
{
int i,j,k,n;
cin>>n;
int a[n],dp1[n],dp2[n];
int ans;
for(i=0;i<n;i++)
{
cin>>a[i];
dp1[i]=0;
dp2[i]=0;
}
if(n <= 2)
cout<< min(a[0],a[1]);
else{
i = 2;
dp1[0] = a[0];
dp1[1] = a[1];
while (i < n){
dp1[i] = a[i] + min(dp1[i-1],dp1[i-2]);
i = i + 1;
}
dp2[0] = a[n-1];
dp2[1] = a[n-2];
i = n-3;
j = 2;
while(i >= 0){
dp2[j] = a[i] + min(dp2[j-1],dp2[j-2]);
i = i - 1;
j = j + 1;
}
ans = min(dp1[n-1], dp2[n-1]);
cout<<ans;
}
return 0;
}
dp1[i] means the most optimal solution till now by including the i-th element in the solution
dp2[i] means the most optimal solution till now by including the i-th element in the solution
dp1[] is calculated from left to right, while dp2[] is calculated from right to left
The minimum of dp1[n-1] and dp2[n-1] is the final answer.
I did your homework!
Edit: #Alex: Dynamic Programming is something that is very difficult to teach. It is something that comes naturally with some practice. Let us consider my solution (forget about your solution for some time):
dp1[n-1] means that I included the last element definitely in the solution, and the constraint that at least one of any 2 adjacent elements need to picked, is satisfied because it always follows:
dp1[i] = a[i] + min(dp1[i-1],dp1[i-2]);
dp2[n-1] means that I included the first element definitely in the solution, and the constraint that at least one of any 2 adjacent elements need to picked, is satisfied also.
So, the minimum of the above two, will give me the final result.
The idea in your M[i] array is "the minimum cost for a solution, assuming the index i is included in it".
The condition if (M[0] <= M[1]) means "if including index 0 is better than not including it, done".
If this condition doesn't hold, then, first of all, the check if (M[1] < M[0]) is superfluous - remove it. It won't fix any bugs, but will at least reduce confusion.
If the condition is false, you should output M[1], but only if it corresponds to a valid solution. That is, since index 0 is not chosen, the last index should be chosen. However, with your data structure it's impossible to know whether M[1] corresponds to a solution that chose last index - this information is lost.
To fix this, consider building two arrays - add e.g. an array L whose meaning is "the minimum cost for a solution, assuming the index i is included in it, and also index N-1 is included in it".
Then, at the end of your program, output the minimum of M[0] and L[1].
I am trying to program the Sieve of Eratosthenes, but I am not sure how to delete elements from the vector I made given a specific condition. Does anyone know how to achieve this? Here is my code:
#include <iostream>
#include <vector>
using namespace std;
int prime(int n);
int prime(int n)
{
vector<int> primes;
for(int i = 2; i <= n; i++)
{
primes.push_back(i);
int t = i % (i + 1);
if(t == 0)
{
delete t; // is there a way of deleting the elements from
// the primes vector that follow this condition t?
}
cout << primes[i] << endl;
}
}
int main()
{
int n;
cout << "Enter a maximum numbers of primes you wish to find: " << endl;
cin >> n;
prime(n);
return 0;
}
Your algorithm is wrong:
t = i % (i + 1);
is
i
which is always != 0 because i is larger than 1.
By the way if you absolutely want to remove the t-th element you have to be sure that the vector is not empty and then you do:
primes.erase(primes.begin()+t);
Even if you fix the algorithm your approach is inefficient: erasing an element in the middle of a vector means copying back of one position all the ones following the erased element.
You don't usually want to delete elements in the middle of a Sieve of Eratosthenes, but when you do want to, you usually want to use the remove/erase idiom:
x.erase(std::remove_if(x.begin(), x.end(), condition), x.end());
std::remove basically just partitions the collection into those that don't meet the specified condition, followed by objects that may have been used as the source of either a copy or a move, so you can't count on their value, but they are in some stable state so erasing them will work fine.
The condition can be either a function or a functor. It receives (a reference to a const) object that it examines and determines whether it lives or dies (so to speak).
Find here a c++ pseudocode for the sieve algorithm. Once you've understood the algorithm you can start working on this.
primes(vector& primes, size_t max){
vector primesFlag(1,max);
i=1
while(i*i<max){
++i;
for(j=i*i; j < max; j+= i){
primesFlag[j] = 0;
}
}
primes.clear()
primes.reserve(...);
for(j >= 2;
if primesFlag[j] = 1
primes.push_back(j);
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I need to sort two arrays (the first one, ascending; and the 2nd one descending)
Here goes the code where the sorting is done: -
for(int i=0;i<10;i++) //1st array, ascending
{
for(int j=0;j<10;j++)
{
if(array1[j]>array1[j+1])
{
int temp=array1[j];
array1[j]=array1[j+1];
array1[j+1]=temp;
}
}
} //Over
for(int i=0;i<10;i++) //2nd, descending
{
for(int j=0;j<10;j++)
{
if(array2[j]<array2[j+1])
{
int temp=array2[j];
array2[j]=array2[j+1];
array2[j+1]=temp;
}
}
} //Over
When I try printing these, it screws up somewhere and I'm unable to pinpoint the problem in the code. Thanks..
You can use C++ itself to sort (quite efficiently) arrays, using any valid rule you want. If you want it in ascending order, you can use the default variety, which automatically uses < effectively. If you want it in descending order, you just have to use the opposite comparison, the >.
Example:
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
vector<int> makeAscending = {3,2,1};
vector<int> makeDescending = {4,5,6};
sort(begin(makeAscending), end(makeAscending)); // could pass less<int>() if you wanted
sort(begin(makeDescending), end(makeDescending), greater<int>());
// print to see answer
copy(begin(makeAscending), end(makeAscending), ostream_iterator<int>(cout, " "));
cout << endl;
copy(begin(makeDescending), end(makeDescending), ostream_iterator<int>(cout, " "));
}
Just to be precise, a valid rule for sorting is one that produces a weak ordering of the items in the container. The Wikipedia page has the rules, but they are mostly this (calling any general "rule" the symbol < and x,y,z are items in your container):
1.) x < x is never true.
2.) If x < y is true that means y < x is false. (and if x < y is false and y < x is false, they are seen as "equal")
3.) if x < y is true and y < z is true then x < z is true.
Just had to limit the inner loop to <9.
The fixed code:
for(int i=0;i<10;i++) //1st array, ascending
{
for(int j=0;j<9;j++)
{
if(array1[j]>array1[j+1])
{
int temp=array1[j];
array1[j]=array1[j+1];
array1[j+1]=temp;
}
}
} //Over
for(int i=0;i<10;i++) //2nd array, descending
{
for(int j=0;j<9;j++)
{
if(array2[j]<array2[j+1])
{
int temp=array2[j];
array2[j]=array2[j+1];
array2[j+1]=temp;
}
}
} //Over
Thank you guys!
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I would like an algorithm that goes through a 2D array and guarantees that each column has all distinct numbers. If a dupe is found in the array it should be replaced with a random number. The random number must also preserve the uniqueness.
If we put a random number, the whole column, should be unique.
is it possible to get an O(N) solution too ?
The best way I can think of is to make an unordered_map<int,bool> for each column, iterate through the column and if you see a number for the first time set the map to true, if the value is already true it's a dupe replace it with a random number. Then check the random number in the map and do the same thing, if it's also a dupe you will have to replace it with a random number again. This algo will like run in linear time, however because of the random number dupe possibility it could run infinitely.
pseudo code
2d_array // assume M rows by N cols
array_of_hashtables // N length
for each col
for each row
if array_of_hashtables[2d_array[row][col]] == false
set it to true
else
do
set 2d_array[row][col] to random
while array_of_hashtables[2d_array[row][col]] == true
end
end
not a huge fan of writing pseudo code but this is about right
Make a std::set and insert step by step elements of every column while checking the size of the set. If the size changes the inserted value is not a duplicate, if it does just randomize a value and add it again to the set. If size changes, you can continue.
Just for the heck of it, here is an implementation of Alexandru Barbarosie's solution:
#include <iostream>
#include <set>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int L = 3;
int W = 3;
int R = 3;
int a[L][W];
srand(time(NULL));
for (int i = 0; i < L; i++)
{
for (int j = 0; j < W; j++)
{
a[i][j] = rand() % R + 1;
cout << a[i][j] << " ";
}
cout << endl;
}
cout << endl;
set<int> s;
int n = 0;
for (int j = 0; j < W; j++)
{
for (int i = 0; i < L; i++)
{
s.insert(a[i][j]);
if (s.size() != n)
n = s.size();
else
a[i--][j] = rand() % R + 1;
}
s.clear();
n = 0;
}
for (int i = 0; i < L; i++)
{
for (int j = 0; j < W; j++)
cout << a[i][j] << " ";
cout << endl;
}
}