Deleting from an array and shifting - c++

For an array, say, size 5,
I'm trying to find a random position between 0 and the current last element of the array.
(This last position is 4 the first time, will be 3 the second time, and so on.)
Delete whatever element is in that array position, shifting all elements above it down so that there are no empty spots in the array.
I am trying to be as time-efficient as possible, so I want to avoid setting said random position to 0 or something like that.
So if my array looked something like int n[] = {1,3,5,7,9}; and my random position finder chose position 2, how would I move 5(position 2) to the end and shift everything down so that my resulting array looks like {1,3,7,9,5} ?
So far I have:
for (int j = 0; j < 5; j++)
{
printf ("before removal:\n");
printarray (array, 5);
int randompos = ( rand() % (5-j) ); //selects random number from 0 to active last pos.
/* ?????? */ = array[randompos]; // What position will hold my random position?
//Also, what goes in place of the 'deleted' element?
insertion_sort (array, 5-j); //sort only the active elements
printf ("after removal:\n");
printarray (array, 5);
}
desired output:
before removal:
1,3,5,7,9
(say random position was array position 2, storing number 5)
after removal:
1,3,7,9,5

Given the array {1,3,5,7,9} and pos = 2, you can do the following:
int main()
{
int pos = 2;
int arr[] = {1, 3, 5, 7,9};
int length =sizeof(arr)/sizeof(arr[0]);
int val = arr[pos];
for (int i = pos; i < length; i++){
int j = i + 1;
arr[i] = arr[j];
}
arr[length - 1] = val;
return 0;
}

#include <iostream>
#include <algorithm>
#include <random>
int main() {
int n[] = {1, 3, 5, 7, 9};
std::size_t n_size = sizeof(n) / sizeof(int);
std::default_random_engine generator;
for(std::size_t i(0), sz(n_size); i < sz; ++i) {
std::cout << "before removal:" << std::endl;
std::cout << " ";
for(std::size_t j(0); j < n_size; ++j) std::cout << n[j] << " ";
std::cout << std::endl;
--n_size;
std::uniform_int_distribution<int> distribution(0, n_size);
std::size_t idx = distribution(generator);
std::cout << " Removing index: " << idx << std::endl;
std::swap(n[idx], n[n_size]);
std::sort(std::begin(n), std::begin(n) + n_size); // use your sorting here
std::cout << "after removal:" << std::endl;
std::cout << " ";
for(std::size_t j(0); j < n_size; ++j) std::cout << n[j] << " ";
std::cout << "\n" << std::endl;
}
}
LIVE DEMO

Related

Filter out duplicate values in array in C++

I have a row of ten numbers for example:
5 5 6 7 5 9 4 2 2 7
Now I want a program that finds all duplicates and gives them out in the console like 3 times 5, 2 times 2, 2 times 7.
While I did code an algorithm that finds duplicates in a row of numbers I can't give them out in the console as described. My program will output:
3 times 5
2 times 5
2 times 7
2 times 2
How can I solve this problem?
#include <iostream>
using namespace std;
int main()
{
int arr[10];
int i,j;
int z = 1;
for(i = 0; i < 10; i++) {
cin >> arr[i];
}
for(i = 0; i < 10; i++){
for(j = i+1; j < 10; j++){
if(arr[i] == arr[j]){
z++;
}
}
if(z >= 2){
cout << z << " times " << arr[i] << endl;
z = 1;
}
}
return 0;
}
You can use the STL here (C++11):
int arr[10];
std::map<int, int> counters;
for (auto item : arr)
{
cin >> item;
++counters[item];
}
std::for_each(counters.begin(), counters.end(), [](const std::pair<int,int>& item)
{
if(item.second > 1) std::cout << item.second << " times " << item.first << std::endl;
});
You need to check that arr[i] is not already found before, like this for example:
if(z >= 2) {
int found_before = 0;
for(j = 0; j < i; ++j)
if(arr[i] == arr[j])
found_before = 1;
if(!found_before)
cout << z << " times " << arr[i] << endl;
z = 1;
}
which will print:
3 times 5
2 times 7
2 times 2
That way you don't print 5 again.
With your code it would print that it found 5 three times (for the first 5 in your array), and then when it would move to he second 5 in your array, it would forgot about the first 5 in your array, and report that it found 5 twice (itself and the 5th number of the array).
Why not use STL?
std::map<int, int> counter;
for (i = 0; i < 10; i++)
counter[arr[i]] ++;
for (i = 0; i < 10; i++) {
if (counter.count(arr[i]) > 0){
std::cout << counter[arr[i]] << " times "<< arr[i] << std::endl;
counter.erase(arr[i]);
}
}
std::map is a convenient tool for this job. You can easily count up occurrences of a specific number. After counting, you can print the count of each array element. With counter.erase, it's guaranteed that you won't print the same element for multiple times.
Why keeping your algorithm idea, I suggest to create sub method:
std::size_t count(const int* arr, std::size_t start, std::size_t end, int value)
{
std::size_t res = 0;
for (std::size_t i = start; i != end; ++i) {
if (arr[i] == value) {
++res;
}
}
return res;
}
then your fixed algorithm would be:
for (std::size_t i = 0; i != 10; ++i) {
if (count(arr, 0, i, arr[i]) != 0) {
continue; // Already visited
}
auto total = count(arr, i, 10, arr[i]);
if(total >= 2){
std::cout << z << " times " << arr[i] << std::endl;
}
}
An easy way is to make another array for it, especially if the numbers are not that big.
Lets say you have initialized your array like so: int nums[10] = { 5, 5, 6, 7, 5, 9, 4, 2, 2, 7 }
int result[max(nums)]; //Fill with zeroes, max(nums) is the highest number in the array
for(int i = 0; i < 10; i++) {
result[nums[i]]++;
}
for(int i = 0; i < max(nums); i++) {
if (result[i] > 1) cout << result[i];
}
Mind you this isn't optimized for memory. For larger number contents you might want to consider hashmaps.
If you don't need performance but rather compact code, then std::multiset with std::upper_bound is an alternative:
#include<set>
#include<iostream>
#include<algorithm>
int main(int a, char** b)
{
int array[] = {5, 5, 6, 7, 5, 9, 4, 2, 2, 7};
std::multiset<int> a(std::begin(array), std::end(array));
for(auto it = a.begin(); it != a.end(); it = std::upper_bound(a.begin(), a.end(), *it))
{
if(a.count(*it) > 1)
std::cout << *it << " times " << a.count(*it) << std::endl;
}
return 0;
}

How to move elements in an array, putting odds to the beginning of the array (smallest to largest), and evens to the back ( largest to smallest )

I have to write a functioncalled moveAndSortInt() that will receive an array of integers as an argument, and move all the even values down to the second half of the array and sort them from largest to smallest, while all the odd values will be sorted from smallest to largest. How can I improve my code?
#include <iostream>
using namespace std;
void moveAndSortInt(int[], int);
void displayName();
int main() {
int ary1[] = { -19, 270, 76, -61, 54 };
int size = 5;
int i;
int ary2[] = {9, 8, -103, -73, 74, 53};
int size2 = 6;
int j;
displayName();
cout << endl;
cout << "Original ary1[]" << endl;
for (i = 0; i < size; i++) {
cout << " " << ary1[i] << " ";
}
cout << endl;
cout << "\nCallingMoveAndSortInt() --\n " << endl;
moveAndSortInt(ary1, size);
cout << "Updated ary1[]" << endl;
for (i = 0; i < size; i++) {
cout << " " << ary1[i] << " ";
}
cout << endl;
cout << "\nOriginal ary2[]" << endl;
for (j = 0; j < size2; j++) {
cout << " " << ary2[j] << " ";
}
cout << endl;
cout << "\nCallingMoveAndSortInt() --\n" << endl;
moveAndSortInt(ary2, size2);
cout << "Updated ary2[]" << endl;
for (j = 0; j < size2; j++) {
cout << " " << ary2[j] << " ";
}
}
void moveAndSortInt(int ary[], int size) {
int i, j;
int temp;
for (i = 0; i < 1 + size / 2; i++) {
if (ary[i] % 2 == 0) {
for (j = size - 1; j > size / 2; j--) {
if (ary[j] % 2 != 0) {
temp = ary[i];
ary[i] = ary[j];
ary[j] = temp;
j = 0;
}
}
}
}
return;
I would suggest using std::sort, the standard algorithm for sorting, which is often implemented with a Quicksort. It is very fast, and also supports custom comparison. Here's some code to get you started:
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> data = { 2, 213, 2, 2, 3 ,123, 4, 213, 2132, 123 };
std::sort(data.begin(), data.end(), [](int lhs, int rhs)
{
if (lhs % 2) // if lhs is odd
if (rhs % 2) // and rhs is odd then just use comparision
return lhs < rhs;
else // and if rhs is even then rhs is "bigger"
return false;
else // if lhs is even
if (rhs % 2)
return true; // and rhs is odd then lhs is "bigger"
else // and if they are both even just use comparision.
return lhs < rhs;
});
}
I'm sorry if that code is a little hard to read, but it does the trick.
This of course would work with C-style arrays too, just replace data.begin() with data and data.end() with data + size.
Alright, so I looked at it a bit. Let's start with conventions.
int i;
for (i = 1; i < 10; i++)
Can be shortened to:
for (int i = 1; i < 10; i++)
Which looks better and is more readable. It would also be nice to have a few more comments, but that's something everyone needs to get better at, no matter how good they are.
So it seems that your code does correctly sort the array into even and odd halves. That's all you need to do yourself as long as you know where they end because sorting them largest to smallest is something that std::sort can do for you.
Edit: It was pointed out to me that my previous example is not exactly the same, as with the second one i can only be used in the loop. For your purposes, they work the same.
You can just reorder it
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
int main()
{
auto const shuffle = [] (int input)
{
if ( input % 2 )
{
unsigned const dist_from_min = (unsigned)input - INT_MIN;
return dist_from_min >> 1;
}
else
{
unsigned const dist_from_max = INT_MAX - (unsigned)input;
return INT_MIN + (dist_from_max >> 1);
}
};
auto const ordering = [shuffle] (int left, int right)
{ return shuffle (left) < shuffle (right); };
std::vector <int> data =
{ 5, 2, 3, 0, -1, -3, 1, 100
, INT_MIN, INT_MIN + 1, INT_MAX, INT_MAX - 1
, -567, -765, 765, 567, -234, -432, 234, 432
};
std::sort ( data.begin ( ), data.end ( ), ordering );
for ( auto item : data )
std::cout << item << "\n";
}

Split array into sub blocks

What I am trying to achieve is this:
I have an image and I need to split it into sub blocks of 16x16 and I am working on the algorithm for this. For testing purposes though, I am using a small matrix:
A = {1, 2, 3, 4}
Now what I want to end up is this: 2 blocks containing:
A[1] = {1 2};
A[2] = {3, 4};
I have tried to use the following:
double matrix[4] = {1, 2, 3, 4};
for(int i = 0; (i < 4); i++)
{
for(unsigned j=i; (j < 2); j +=2)
{
std::cout << j << ' ';
}
std::cout << std::endl;
}
My thought process was to loop through the entire array (4) and then increment by 2 each time to create the 1x2 block. This did not work however.
Where am I going wrong here?
Something like that? (Does both output and assignment)
int LEN = 4;
int INNER = 2;
int OUTER_LEN = LEN/INNER_LEN;
double matrix[LEN] = {1, 2, 3, 4};
double* matrix2[OUTER_LEN];
for(int i = 0; i < OUTER_LEN; i++)
{
matrix2[i] = &matrix[i*INNER_LEN];
for(unsigned j=0; j < INNER_LEN; j++)
{
std::cout << matrix[i*INNER_LEN+j] << ' ';
}
std::cout << std::endl;
}
Just for output you could do something like that:
#include <iostream>
int main(){
const size_t SIZE = 4;
const size_t PART_SIZE = 2;
double matrix[4] = {1, 2, 3, 4};
for(int i = 0; (i < SIZE); i += PART_SIZE)
{
for(size_t j = i; (j < i + PART_SIZE) && j < SIZE; j += 1)
{
std::cout << matrix[j] << ' ';
}
std::cout << std::endl;
}
}
To add another matrix:
#include <iostream>
int main(){
const size_t SIZE = 4;
const size_t PART_SIZE = 2;
size_t partsNumber = SIZE / PART_SIZE; // Beware of SIZE that is not divisible by PART_SIZE - partsNumber will be too small
double matrix[4] = { 1, 2, 3, 4 };
// To do it properly I should make it dynamic array with size of partsNumber instead of the 2 literals
double parts_matrix[2][PART_SIZE];
for (int i = 0; (i < SIZE); i += PART_SIZE) {
for (size_t j = i; (j < i + PART_SIZE) && j < SIZE; j += 1) {
std::cout << matrix[j] << ' ';
parts_matrix[j / partsNumber][j % PART_SIZE] = matrix[j];
}
std::cout << std::endl;
}
std::cout << parts_matrix[0][0] << " " << parts_matrix[0][1] << std::endl << parts_matrix[1][0] << " " << parts_matrix[1][1]; // Check if it works
}
The following is a demo of how to do the splitting for custom block size (rough cut though, corner cases and input verification are ommited) using boost range and the boost::slice functionality (here "output creation" is presented)
#include <iterator>
#include <iostream>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/algorithm/copy.hpp>
using namespace std;
using namespace boost::adaptors;
template<typename T, size_t N>
void split(T (&input)[N], size_t block_size)
{
for (size_t i(0); i <= N-block_size; i += block_size)
{
cout << "{ ";
boost::copy(input | sliced(i, i+block_size),
std::ostream_iterator<int>(std::cout, " "));
cout << "}\n";
}
}
int main()
{
int A[] = {1, 2, 3, 4};
split(A, 2);
}
Demo
Output
{ 1 2 }
{ 3 4 }
What if I don't want to do output
To some the following may look more readable
template<typename T, size_t N>
void split(T (&input)[N], size_t block_size)
{
for (size_t i(0); i <= N-block_size; i += block_size)
{
cout << "{ ";
// do whatever with the i slice (again I'm showing output)
for (auto k : (input | sliced(i, i+block_size))) cout << k << " ";
cout << "}\n";
}
}

Randomizing/Modifing Arrays

So I'm trying to randomize an array of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. Then ask for the user to select a position in the array, and modify it. After that, it should display the number the user entered for all of the 10 values. Finally, it will need to get the original array that was randomized and reverse it.
So far, I have this
#include <iostream>
using namespace std;
int array [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int rarray [10];
int main() {
cout << "Random Array = ";
for (int i = 0; i < 10; i++) {
int index = rand() % 10;
int temp = array[i];
array[i] = array[index];
array[index] = temp;
}
for (int i = 1; i <= 10; i++) {
cout << array[i] << " "; //somehow, this display needs to be entered into another array
}
system("PAUSE");
}
But as stated in the comment, I'm stuck on as how to do this.
You can accomplish this by using std::shuffle, std::copy, and std::reverse from the C++ Standard Library.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int position;
// Get the position to modify and make sure it's within our bounds.
do
{
cout << "Select a position: ";
}
while (!(cin >> position) || position < 0 || position > 9);
int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int rarray[10];
// Shuffle the array. We use std::begin and std::end to get the bounds of
// of the array instead of guessing it's size.
std::random_shuffle(std::begin(array), std::end(array));
// Copy it to the new array
std::copy(std::begin(array), std::end(array), rarray);
// Modify the new array and display it. Add your own code here to get the
// value it is modified with.
rarray[position] = 100;
for (auto value : rarray)
cout << value << " ";
cout << endl;
// Reverse the original array and display it
std::reverse(std::begin(array), std::end(array));
for (auto value : array)
cout << value << " ";
cout << endl;
system("PAUSE");
}
or if you are not allowed to use the C++ Standard Library you will need to handle everything manually. This is a tedious task but a great example of why the C++ Standard Library should be leveraged whenever possible. This is also more prone to errors, more difficult to maintain, and ugly to look at.
int main()
{
int position;
do
{
cout << "Select a position: ";
} while (!(cin >> position) || position < 0 || position > 9);
int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < 10; i++)
{
int index = rand() % 10;
int temp = array[i];
array[i] = array[index];
array[index] = temp;
}
// Copy the array
int rarray[10];
for (int i = 0; i < 10; i++)
{
rarray[i] = array[i];
}
// Modify the new array and display it
rarray[position] = 100;
for (int i = 0; i < 10; i++)
{
cout << rarray[i] << " ";
}
cout << endl;
// Reverse the old array and display it
for (int i = 0; i < 10 / 2; i++)
{
int tmp = array[i];
array[i] = array[9 - i];
array[9 - i] = tmp;
}
for (int i = 0; i < 10; i++)
{
cout << array[i] << " ";
}
cout << endl;
system("PAUSE");
}
Both implementations are close to your original request but you may need to expand on it a little to match your requirements exactly. They should get you moving along nicely though.

C++ Array copying/shift

We had a project that asked us to Write a program that allows a user to enter a series of numbers "read numbers into an array for further processing, user signals that they are finished by entering a negative number (negative not used in calculations), after all numbers have been read in do the following, sum up the #'s entered, count the #'s entered, find min/max # entered, compute average, then output them on the screen. So the working version of this that I made looks like so
/* Reads data into array.
paramater a = the array to fill
paramater a_capacity = maximum size
paramater a_size = filled with size of a after reading input. */
void read_data(double a[], int a_capacity, int& a_size)
{
a_size = 0;
bool computation = true;
while (computation)
{
double x;
cin >> x;
if (x < 0)
computation = false;
else if (a_size == a_capacity)
{
cout << "Extra data ignored\n";
computation = false;
}
else
{
a[a_size] = x;
a_size++;
}
}
}
/* computes the maximum value in array
paramater a = the array
Paramater a_size = the number of values in a */
double largest_value(const double a[], int a_size)
{
if(a_size < 0)
return 0;
double maximum = a[0];
for(int i = 1; i < a_size; i++)
if (a[i] > maximum)
maximum = a[i];
return maximum;
}
/* computes the minimum value in array */
double smallest_value(const double a[], int a_size)
{
if(a_size < 0)
return 0;
double minimum = a[0];
for(int i = 1; i < a_size; i++)
if (a[i] < minimum)
minimum = a[i];
return minimum;
}
//computes the sum of the numbers entered
double sum_value(const double a [], int a_size)
{
if (a_size < 0)
return 0;
double sum = 0;
for(int i = 0; i < a_size; i++)
sum = sum + a[i];
return sum;
}
//keeps running count of numbers entered
double count_value(const double a[], int a_size)
{
if (a_size < 0)
return 0;
int count = 0;
for(int i = 1; i <= a_size; i++)
count = i;
return count;
}
int _tmain(int argc, _TCHAR* argv[])
{
const int INPUT_CAPACITY = 100;
double user_input[INPUT_CAPACITY];
int input_size = 0;
double average = 0;
cout << "Enter numbers. Input negative to quit.:\n";
read_data(user_input, INPUT_CAPACITY, input_size);
double max_output = largest_value(user_input, input_size);
cout << "The maximum value entered was " << max_output << "\n";
double min_output = smallest_value(user_input, input_size);
cout << "The lowest value entered was " << min_output << "\n";
double sum_output = sum_value(user_input, input_size);
cout << "The sum of the value's entered is " << sum_output << "\n";
double count_output = count_value(user_input, input_size);
cout << "You entered " << count_output << " numbers." << "\n";
cout << "The average of your numbers is " << sum_output / count_output << "\n";
string str;
getline(cin,str);
getline(cin,str);
return 0;
}
That went fine, the problem I am having now is part 2. Where we are to "copy the array to another and shift an array by N elements". I'm not sure where to begin on either of these. I've looked up a few resources on copying array's but I was not sure how to implement them in the current code I have finished, especially when it comes to shifting. If anyone has any thoughts, ideas, or resources that can help me on the right path it would be greatly appreciated. I should point out as well, that I am a beginner (and this is a beginners class) so this assignment might not be the 'optimal' way things could be done, but instead incorporates what we have learned if that makes sense.
for(int i = 0; i < n; ++i){
int j = (i - k)%n;
b[i] = a[j];
}
Check it. I'm not sure
If this works you could improve it to
for(int i = 0; i < n; ++i)
b[i] = a[(i - k)%n];//here can be (i +/- k) it depends which direction u would shift
If you only want to copy the array into another array and shift them
ex : input = 1, 2, 3, 4, 5; output = 3, 4, 5, 1, 2
The cumbersome solution is
//no template or unsafe void* since you are a beginner
int* copy_to(int *begin, int *end, int *result)
{
while(begin != end){
*result = *begin;
++result; ++begin;
}
return result;
}
int main()
{
int input[] = {1, 2, 3, 4, 5};
size_t const size = sizeof(input) / sizeof(int);
size_t const begin = 2;
int output[size] = {0}; //0, 0, 0, 0, 0
int *result = copy_to(input + begin, input + size - begin, output); //3, 4, 5, 0, 0
copy_to(input, input + begin, result); //3, 4, 5, 1, 2
return 0;
}
How could the stl algorithms set help us?
read_data remain as the same one you provided
#include <algorithm> //std::minmax_element, std::rotate_copy
#include <iostream>
#include <iterator> //for std::begin()
#include <numeric> //for std::accumulate()
#include <string>
#include <vector>
int main(int argc, char *argv[]) //don't use _tmain, they are unportable
{
const int INPUT_CAPACITY = 100;
double user_input[INPUT_CAPACITY];
int input_size = 0;
double average = 0;
cout << "Enter numbers. Input negative to quit.:\n";
read_data(user_input, INPUT_CAPACITY, input_size);
auto const min_max = std::minmax_element (user_input, user_input + input_size); //only valid for c++11
std::cout << "The maximum value entered was " << min_max.second << "\n";
std::cout << "The lowest value entered was " << min_max.first << "\n";
double sum_output = std::accumulate(user_input, user_input + input_size, 0);
cout << "The sum of the value's entered is " << sum_output << "\n";
//I don't know the meaning of you count_value, why don't just output input_size?
double count_output = count_value(user_input, input_size);
cout << "You entered " << count_output << " numbers." << "\n";
cout << "The average of your numbers is " << sum_output / count_output << "\n";
int shift;
std::cout<<"How many positions do you want to shift?"<<std::endl;
std::cin>>shift;
std::vector<int> shift_array(input_size);
std::rotate_copy(user_input, user_input + shift, user_input + input_size, std::begin(shift_array));
//don't know what are they for?
std::string str;
std::getline(std::cin,str);
std::getline(std::cin,str);
return 0;
}
if your compiler do not support c++11 features yet
std::minmax_element could replace by
std::min_element and std::max_element
std::begin() can replace by shift_array.begin()
I don't know what is the teaching style of your class, in my humble opinion, beginners should
start with those higher level components provided by c++ like vector, string, algorithms
and so on.I suppose your teachers are teaching you that way and you are allowed to use the
algorithms and containers come with c++(Let us beg that your class are not teaching you "c with classes" and say something like "OOP is the best thing in the world").
ps : You could use vector to replace the raw array if you like