I need to flip a part of an array, keeping the rest unchanged.
I have a function that flips and entire array, but... To use it, I have to take a part from my array, flip it with the function and paste it on its place. It's uncomfortable and not so fast. I need a method that works very fast.
Example:
int array[10] = {1,2,3,4,5,6,7,8,9,10};
flip(array,2,6); //Flip the part between index 2 and 6
After that, the array should look so:
{1,2,7,6,5,4,3,8,9,10}
Please, help, I need a really quick answer...
There is an algorithm in the standard library exactly for this: void reverse( BidirIt first, BidirIt last );
Here is an example of how to solve your problem with std::reverse function.
#include <algorithm>
#include <iostream>
int main() {
int array[10] = {1,2,3,4,5,6,7,8,9,10};
std::reverse(array + 2, array + 7);
for (int i = 0; i < 10; ++i) {
std::cout << array[i] << " ";
}
}
Please note that I replaced indices 2 and 6 in your example with 2 and 7. This is because std::reverse reverses the elements in the range [first, last).
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
An array of length L is given. Elements are '–ve' and +ve integers. Make a function that figure out all positive numbers in the array that have their opposites in it as well.
Input : 4,5,8,3,2,-5,-8,-4,-2,-3,-5,8,-8
Output : 2,-2,3,-3,4,-4,5,-5,8,-8
I copied this code from the web but couldn't understand it, is there some other easier way.
#include <bits/stdc++.h>
using namespace std;
void printPairs(int arr[], int n)
{
vector<int> v;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
// If absolute values are equal print pair.
if (abs(arr[i]) == abs(arr[j]))
v.push_back(abs(arr[i]));
if (v.size() == 0)
return;
for (int i = 0; i < v.size(); i++)
cout << -v[i] << " " << v[i] << " ";
}
int main()
{
int arr[] = { 4, 8, 9, -4, 1, -1, -8, -9 };
int n = sizeof(arr) / sizeof(arr[0]);
printPairs(arr, n);
return 0;
}
Using standard algorithms does not always immediately make code easier, but standard algorithms are well documented. If you do not understand application of a standard algorithm you can find plenty of documentation. That isnt the case for self-written algorithms.
Know your algorithms! I will use a simpler example: 2,1,-2,2, and I will use a std::vector.
std::sort can be used to sort the vector to 1,2,2,-2 by using a custom comparator that compares the elements absolute values and places positive elements before negative ones ( to achive that you can compare std::pairs of {abs(element),element<0}).
std::unique can be used to move adjacent duplciates to the end of the vector, resulting in 1,2,-2,2. The returned iterator refers to the 2 because thats the end of the vector that has only the unique elements. (Here it is not actually needed to erase the duplicates from the vector)
std::adjacent_find can be used to find pairs of adjacent elements for which abs(a) == abs(b).
Thats all you need.
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
int main() {
std::vector<int> x{4,5,8,3,2,-5,-8,-4,-2,-3,-5,8,-8};
std::sort(x.begin(),x.end(),[](auto a,auto b){ return std::make_pair(std::abs(a),a<0) < std::make_pair(std::abs(b),b<0);});
auto last = std::unique(x.begin(), x.end());
//x.erase(last, x.end()); // no need to actually erase
auto it = x.begin();
while (it != last) {
it = std::adjacent_find(it,last,[](auto a,auto b){ return std::abs(a) == std::abs(b);});
if (it != last) {
std::cout << *it << " " << *std::next(it) << "\n";
it += 2;
}
}
}
I am not expecting that you find this code much simpler to read compared to the original, but if you just spend some time on the documentation of the used algorithms it should become clear how it works.
I think the algorithm is not correct, just looking at absolute values.
Also it is quadratic O(n²), 1,000 items would need 500,000 steps.
Sort the array. -8, -5, -4, 2, 4, 8, 9
Now you can have two iterators, from the beginning (-8) for negative numbers and from the end (9) for positive numbers.
As long the iterators are in the negative resp. positive range, you can advance to absolutely identical numbers. Mind repeats ..., 13, 13, 13, ....
The coding I leave to you. Would not like to spoil it.
This question already has answers here:
Unique (non-repeating) random numbers in O(1)?
(22 answers)
Closed 1 year ago.
My goal is creating an array of 5 unique integers between 1 and 20. Is there a better algorithm than what I use below?
It works and I think it has a constant time complexity due to the loops not being dependent on variable inputs, but I want to find out if there is a more efficient, cleaner, or simpler way to write this.
int * getRandom( ) {
static int choices[5] = {};
srand((unsigned)time(NULL));
for (int i = 0; i < 5; i++) {
int generated = 1 + rand() % 20;
for (int j = 0; j < 5; j++){
if(choices[j] == generated){
i--;
}
}
choices[i] = generated;
cout << choices[i] << endl;
}
return choices;
}
Thank you so much for any feedback. I am new to algorithms.
The simplest I can think about is just create array of all 20 numbers, with choices[i] = i+1, shuffle them with std::random_shuffle and take 5 first elements. Might be slower, but hard to introduce bugs, and given small fixed size - might be fine.
BTW, your version has a bug. You execute line choices[i] = generated; even if you find the generated - which might create a copy of generated value. Say, i = 3, generated is equal to element at j = 0, now your decrement i and assign choices[2] - which becomes equal to choices[0].
C++17 code with explanation of why and what.
If you have any questions left don't hesitate to ask, I'm happy to help
#include <iostream>
#include <array>
#include <string>
#include <random>
#include <type_traits>
// container for random numbers.
// by putting the random numbers + generator inside a class
// we get better control over the lifecycle.
// e.g. what gets called when.
// Now we know the generation gets called at constructor time.
class integer_random_numbers
{
public:
// use std::size_t for things used in loops and must be >= 0
integer_random_numbers(std::size_t number, int minimum, int maximum)
{
// initialize the random generator to be trully random
// look at documentation for <random>, it is the C++ way for random numbers
std::mt19937 generator(std::random_device{}());
// make sure all numbers have an equal chance. range is inclusive
std::uniform_int_distribution<int> distribution(minimum, maximum);
// m_values is a std::vector, which is an array of which
// the length be resized at runtime.
for (auto n = 0; n < number; ++n)
{
int new_random_value{};
// generate unique number
do
{
new_random_value = distribution(generator);
} while (std::find(m_values.begin(), m_values.end(), new_random_value) != m_values.end());
m_values.push_back(new_random_value);
}
}
// give the class an array index operator
// so we can use it as an array later
int& operator[](const std::size_t index)
{
// use bounds checking from std::vector
return m_values.at(index);
}
// reutnr the number of numbers we generated
std::size_t size() const noexcept
{
return m_values.size();
}
private:
// use a vector, since we specify the size at runtime.
std::vector<int> m_values;
};
// Create a static instance of the class, this will
// run the constructor only once (at start of program)
static integer_random_numbers my_random_numbers{ 5, 1, 20 };
int main()
{
// And now we can use my_random_numbers as an array
for (auto n = 0; n < my_random_numbers.size(); ++n)
{
std::cout << my_random_numbers[n] << std::endl;
}
}
Generate 5 random numbers from 1 to 16, allowing duplicates
Sort them
Add 1 to the 2nd number, 2 to the 3rd, 3 to 4th, and 4 to the 5th.
The last step transforms the range from [1,16] to [1,20] by remapping the possible sequences with duplicates into sequences with unique integers. [1,2,10,10,16], for example, becomes [1,3,12,13,20]. The transformation is completely bijective, so you never need to discard and resample.
The question is to count the number of repeating elements in the given array:
Suppose the input is:
1
1 2 3 3 3
2
1 2 2 3 3 3 4 5
Then the output should be 3 for the first input and 5 for the second one.
I have written the code, according to logic its output should be 3 but I'm getting the output as 5 could anyone spot the error.
#include <bits/stdc++.h>
using namespace std;
int main() {
int a[5] = {
1,
4,
2,
4,
4
};
int b[101];
memset(b, 0, 101);
int cp = 0, i = 0;
b[a[i]] = 1;
for (int j = i + 1; j < 5; j++) {
if (b[a[j] > 0]) {
if (b[a[j]] == 1)
cp++;
cp++;
b[a[j]]++;
} else
b[a[j]] = 1;
}
cout << cp;
return 0;
}
There is a typo in your code - you wrote if(b[a[j]>0]) instead of if (b[a[j]] > 0), which produces completely different behavior.
To avoid such mistakes, you should format your code properly and give meaningful names to variables. For example, your main function could be rewritten as:
int main() {
const size_t SIZE = 5;
int a[SIZE] = {1, 4, 2, 4, 4};
const int MAX_VALUE = 100;
int count[1 + MAX_VALUE] = {};
int duplicates = 0;
for (int j = 0; j < SIZE; j++) {
if (count[a[j]] > 0)
duplicates++;
if (count[a[j]] == 1)
duplicates++;
count[a[j]]++;
}
cout << duplicates;
}
Note how I also removed a special case for the first array element - it is unnecessary and often prone to errors.
If I read something like
#include <bits/stdc++.h>
using namespace std;
and the variable names, then I assume that this question is related to some competetive programming site. So, my guess is that there are more constraints that we do not know. We see for example the magic number 101 here. Maybe there is a constraint that we have only integers in the range 0..100. Anyway, we do not know.
I would like to show a C++ solution. Basically this is using the standard approach for counting items, by using a std::map or std::unordered_map.
Please see the following code which basically consists of 2 lines. I will explain it afterwards:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <numeric>
std::vector testData{ 1,4,2,4,4 };
int main() {
std::unordered_map<int, size_t> counter{};
// Count the occurence of each integer value
for (const int i : testData) counter[i]++;
// Accumulate repeating values and show result
std::cout << std::accumulate(counter.begin(), counter.end(), 0U, [](size_t c, const auto& p) { return c+(p.second > 1 ? p.second : 0U); });
return 0;
}
As said, we use the standard approach with maps. The important point here is to understand the index operator of a map. Please see here. And read:
Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.
The important point is: It will either return a reference to a value, if it is already in the map. If not, it will create the value in the map and again return a reference to the value. And because we get a reference to the value in any way, we can simply increment it.
After we have done this for all source values from our "testData"-vector in a very simple for loop, we have the count of all values. If the count for one value is greater then 1, then it is a duplicate or "repeated".
Therefore, we just need to accumulate all counters that are greater than 1. And for this we use the dedicated function std::accumulate.
If you should have any questions, then please ask.
I am new to C++, I have a problem of array manipulation. I have an array of X with length 100, I need to fill the value of X with integer value of 1 to 10 (1,2,3,4,5,6,7,8,9,10) randomly.
I know that there will be duplicate, maybe like 1 printed ten times, etc, but that's really what I want.
Here is what I have:
an array of X:
int X[100];
Here is my code snippet:
int* X = NULL;
int* val = NULL;
int length1= 100;
int length2= 10;
X = new int[length1];
val = new int[length2];
int i;
int j;
for (i = 0; i < isi; i++) {
val[i] = i;
for (j = 0; j < length1; j++) {
if (j > i) {
X[j] = val[i];
} else {
X[j] = val[0];
}
cout << "X[" << j << "] = " << X[j] << "\n";
Sleep(1);
}
}
Code above makes the array X from index 0 to 99 has value of 0, then index 0 to 99 has value of 1 and so the other index until the index 0 to 99 has value of 9.
This is not what I want, what I want is to make it (if it is not random) index 0 to 9 has value of 0, then 10 to 19 has value of 1 ... until index 90 to 99 has value of 9. Hope my explanation clear.
I have come to a question in stackoverflow: How would you make an array of 10000 with only values of 1-1000 inclusive?
But still can't resolve my problem my self.
Can someone please give me solution to this.
Thank you in advance
#include <stdlib.h>
int main(int argc, char **argv) {
int r[100];
for (int i = 0; i < 100; ++i) {
r[i] = rand() % 10 + 1;
}
}
For some output, you can #include <iostream> and then std::cout << "r[" << i << "] = " << r[i] << "\n" inside the loop after each assignment.
If you want to seed the random number generator for a different sequence each time, then #include <time.h> and then srand(time(NULL)) before your first call to rand.
You can also use generate function:
#include <iostream>
#include <algorithm>
#include <random>
using namespace std;
int main()
{
int arr[100];
random_device rd;
default_random_engine dre(rd());
uniform_int_distribution<int> uid(0,9);
generate(arr, arr + sizeof(arr) / sizeof(int), [&] () { return uid(dre); });
for (int a : arr)
cout << a << " ";
}
Here are two ways to solve this problem - since this is a learning experience, only pseudo code (and relevant links) are provided. Each "task" can be looked up and solved separately. Note that neither method uses a secondary array.
If the amount of each number in the final result does not need to be the same (eg. 2 might appear 17 times) then consider the following loop-and-assign-random approach. A standard C for-each loop is sufficient.
# for every index pick a random value in [0, 10) and assign it
for i in 0 to last array index:
array[i] = random in range 0, 10
If the amount of numbers need to be the same, then consider filling the array and then shuffling it. The modulus operator is very handy here. (This assumes the array length is a multiple of the group size.)
# fill up array as 0,1,2,3,4,5,6,7,8,9,0,1,2.. (will be 10 groups)
for i in 0 to last array index:
array[i] = i % 10
# and randomly rearrange order
shuffle array
For the shuffle see Fisher-Yates, which even shows a C implementation - there are "more C++" ways, but this is a good technique to learn and practice with loops. (One cool property about Fisher-Yates is that as soon an item is swapped into the current index it is at the final swap location - thus the shuffle loop can be modified to shuffle and immediately perform an action such as displaying the value.)
In both cases a random function should be used; else the numbers will not be .. random.
To loop over the items of a collection the most natural C++ loop is the range based for loop.
In order to assign something to each item, the formal item name should be a reference, thus:
for( auto& item : X )
{
// E.g. assign to item here.
}
This serves up each item of the array, in order, to the code marked by a comment.
There are two different random generators in C++, the old C library one, which is just a pair of functions, and the more general and modern but also not-so-easy-to-grok C++11 thingy. I suggest you google it and try out things. Ask new more specific question if/when stuck.
I think others have pointed it out but you have to first write the pre-compiler directive #include <ctime> and then use the srand function. Most would say don't use that but since you and I are at the basics our teachers, respectively, start us off with that. And it might work with your compiler as well.
Here is a link to learn more about it. I would have commented but I can't.
http://www.cplusplus.com/reference/cstdlib/srand/
I'm pretty new to C++, and I need help figuring out the code for dropping the lowest value of a randomly generated set of numbers. Here is my code so far:
//Create array and populate the array with scores between 55 and 10
// Drop lowest Score
#include <iostream>
#include <cstdlib>//for generating a random number
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
//function prototype
int *random (int);
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
//random function, generates random numbers between 55 and 100 ??
int *random(int num)
{ int *arr; //array to hold numbers
//return null if zero or negative
if (num <= 0)
return NULL;
//allocate array
arr = new int[num];
//seed random number generator
srand(time (0));
//populate array
for (int count = 0; count < num; count++)
arr[count] = (rand()%(45) +55);
//return pointer
//
return arr;
}
For this piece of code, how would I sort or find the lowest score to drop it after the function returns the random numbers?
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
Your suggestions are appreciated!
In general, to find the lowest value in an array, you can follow this psuedo-algorithm:
min = array[0] // first element in array
for (all_values_in_array)
{
if (current_element < min)
min = current_element
}
However, you can't "drop" a value out of a static array. You could look into using a dynamic container (eg. vector), or swapping the lowest value with the last value, and pretending the size of the array is 1 less. Another low level option would be to create your own dynamic array on the heap, however, this is probably more complicated than you are looking for.
Using an vector would be much easier. To drop the lowest element, you just have to sort in reverse order, then remove the last element. Personally, I would recommend using a vector.
The obvious approach to find the smallest element is to use std::min_element(). You probably want to use std::vector<T> to hold your elements but this isn't absolutely necessary. You can remove the smallest value from an array like this:
if (count) {
int* it = std::min_element(array, array + count);
std::copy(it + 1, array + count--, it);
}
Assuming you, reasonable used std::vector<int> instead, the code would look something like this:
if (!array.empty()) {
array.erase(std::min_element(array.begin(), array.end()));
}
First find the index of the lowest number:
int lowest_index=0, i;
for (i=0; i<20; i++)
if (arr[i]<arr[lowest_index])
lowest_index=i;
Now that we know the index, move the numbers coming after that index to overwrite the index we found. The number of numbers to move will be 19 minus the found index. Ie, if index 2 (the third number, since the first is at index 0) is lowest, then 17 numbers comes after that index, so that's how many we need to move.
memcpy(&arr[lowest_index],&arr[lowest_index+1],sizeof(int)*(19-lowest_index))
Good luck!
Sort the array ascending.
The lowest value will be at the beginning of the array.
Or sort the array descending and remove the last element.
Further to what others have said, you may also choose to use something like, perhaps a std::list. It's got sorting built-in, also offering the ability to define your own compare function for two elements. (Though for ints, this is not necessary)
First, I typically typedef the vector or list with the type of the elements it will contain. Next, for lists I typedef an iterator - though both of these are merely a convenience, neither is necessary.
Once you've got a list that will holds ints, just add them to it. Habit and no need to do otherwise means I'll use .push_back to add each new element. Once done, I'll sort the list, grab the element with the lowest value (also the lowest 'index' - the first item), then finally, I'll remove that item.
Some code to muse over:
#include <cstdio>
#include <cstdlib>
#include <list>
using namespace std;
typedef list<int> listInt;
typedef listInt::iterator listIntIter;
bool sortAsc(int first, int second)
{
return first < second;
}
bool sortDesc(int first, int second)
{
return first > second;
}
int main (void)
{
listInt mList;
listIntIter mIter;
int i, curVal, lowestScore;
for (i=1; i<=20; i++)
{
curVal = rand()%45 + 55;
mList.push_back(curVal);
printf("%2d. %d\n", i, curVal);
}
printf("\n");
mList.sort();
// mList.sort(sortAsc); // in this example, this has the same effect as the above line.
// mList.sort(sortDesc);
i = 0;
for (mIter=mList.begin(); mIter!=mList.end(); mIter++)
printf("%2d. %d\n", ++i, *mIter);
printf("\n");
lowestScore = mList.front();
mList.pop_front();
printf("Lowest score: %d\n", lowestScore);
return 0;
}
Oh, and the choice to use printf rather than cout was deliberate too. For a couple of reasons.
Personal preference - I find it easier to type printf("%d\n", someVar);
than cout << someVar << endl;
Size - built with gcc under windows, the release-mode exe of this example is 21kb.
Using cout, it leaps to 459kb - for the same functionality! A 20x size increase for no gain? No thanks!!
Here's an std::list reference: http://www.cplusplus.com/reference/stl/list/
In my opinion the most optimal solution to your problem would be to use a linked list to store the numbers, this way you can use an algorithm with complexity O(N) = N to find the smallest element in the list, it is a similar finding method given by user1599559 or Mikael Lindqvist, you only need stored together with the minimum value the pointer to the Item(ItemX) in the linked list that store it, then to eliminate Item X just tell Item X - 1 points to Item X + 1 and free memory allocated by Item X