Removing odd numbers from an array - c++

I am trying to remove odd numbers from an array, but I'm not allowed to create a new array to store the new values.
So, if I have arr[1,2,3,4,5,6,7,8,9]
then I need it to be arr[2,4,6,8] so that arr[0] will be 2 and not 1.
I can't seem to be able to drop the even numbers without creating a new array to store the values and then feed it back into the original array with the new values.
I have tried to make arr[i] = 0 if its an odd number but then I wasn't able to drop the 0 and replace it with the next even number.
So far, I have this:
void removeOdd(int arr[], int& arrSize){
int i, j = 0;
int temp;
int newArrSize;
for(i = 0, newArrSize = arrSize; i < arrSize; i++){
if(arr[i] % 2 != 0){
arr[i] = 0;
}
}
arrSize = newArrSize;
}

// Moves all even numbers into the beginning of the array in their original order
int removeOdd(int arr[], int arrSize) {
int curr = 0; // keep track of current position to insert next even number into
for (int i = 0; i < arrSize; ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
return curr;
}
int main() {
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int newSize = removeOdd(arr, 10);
for (int i = 0; i < newSize; ++i) {
std::cout << arr[i] << " ";
}
}
0 2 4 6 8
You might want to use std::vector:
void removeOdd(std::vector<int>& arr) {
int curr = 0;
for (int i = 0; i < (int)arr.size(); ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
arr.resize(curr);
}
int main() {
std::vector<int> arr = { 0,1,2,3,4,5,6,7,8,9 };
removeOdd(arr);
for (int number : arr) {
std::cout << number << " ";
}
}

Normally (unless this is homework of some sort), you should use the algorithms in the <algorithm> header.
Using std::remove_if with std::vector's erase member function, you will accomplish exactly what you want with less code:
std::vector<int> vec{ 1,2,3,4,5,6,7,8,10 };
vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](auto const& i) {
return i % 2 != 0;
}), std::end(vec));
Demo

Related

Finding two associated indexes where the sum of two elements equals a target value

Background:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
Question:
I have a list of numbers 1,2,3,4,5. My target value is 8, so I should return indices 2 and 4. My first thought is to write a a double for loop that checks to see if adding two elements from the list will get my target value. Although, when checking to see if there is such a solution, my code returns that there is none.
Here is my code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.push_back(4);
list.push_back(5);
int target = 8;
string result;
for(int i = 0; i < list.size(); i++) {
for(int j = i+1; j < list.size(); j++) {
if(list[i] + list[j] == target) {
result = "There is a solution";
}
else {
result = "There is no solution";
}
}
}
cout << result << endl;
return 0;
}
Perhaps my approach/thinking is plain wrong. Could anyone provide any hints or suggestions to solving this problem?
Your approach is correct but you are forgetting you are in a loop that continues after finding the solution.
This will get you halfway there. I recommend putting both loops in a function, and returning once you find a match. One thing you could do is return a pair<int,int> from that function or you could simply output the results from within that point in the loop.
bool solutionFound = false;
int i,j;
for(i = 0; i < list.size(); i++)
{
for(j = i+1; j < list.size(); j++)
{
if(list[i] + list[j] == target)
{
solutionFound = true;
}
}
}
Here is what the function approach might look like:
pair<int, int> findSolution(vector<int> list, int target)
{
for (int i = 0; i < list.size(); i++)
{
for (int j = i + 1; j < list.size(); j++)
{
if (list[i] + list[j] == target)
{
return pair<int, int>(i, j);
}
}
}
return pair<int, int>(-1, -1);
}
int main() {
vector<int> list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.push_back(4);
list.push_back(5);
int target = 8;
pair<int, int> results = findSolution(list, target);
cout << results.first << " " << results.second << "\n";
return 0;
}
Here's the C++ incorporating Dave's answer for linear execution time and a couple helpful comments:
pair<int, int> findSolution(vector<int> list, int target)
{
unordered_map<int, int> valueToIndex;
for (int i = 0; i < list.size(); i++)
{
int needed = target - list[i];
auto it = valueToIndex.find(needed);
if (it != valueToIndex.end())
{
return pair<int, int>(it->second, i);
}
valueToIndex.emplace(list[i], i);
}
return pair<int, int>(-1, -1);
}
int main()
{
vector<int> list = { 1,2,3,4,5 };
int target = 10;
pair<int, int> results = findSolution(list, target);
cout << results.first << " " << results.second << "\n";
}
You're doing this in n^2 time. Solve it in linear time by hashing each element, and checking each element to see if it's complement wrt. the total you're trying to achieve is in the hash.
E.g., for 1,2,3,4,5, with a target of 8
indx 0, val 1: 7 isn't in the map; H[1] = 0
indx 1, val 2: 6 isn't in the map, H[2] = 1
indx 2, val 3: 5 isn't in the map, H[3] = 2
indx 3, val 4: 4 isn't in the map, H[4] = 3
indx 4, val 5: 3 is in the map. H[3] = 2. Return 2,4
Code, as requested (Ruby)
def get_indices(arr, target)
value_to_index = {}
arr.each_with_index do |val, index|
if value_to_index.has_key?(target - val)
return [value_to_index[target - val], index]
end
value_to_index[val] = index
end
end
get_indices([1,2,3,4,5], 8)
Basically the same as zzxyz's most recent edit but a little quicker and dirtier.
#include <iostream>
#include <vector>
bool FindSolution(const std::vector<int> &list, // const reference. Less copying
int target)
{
for (int i: list) // Range-based for (added in C++11)
{
for (int j: list)
{
if (i + j == target) // i and j are the numbers from the vector.
// no need for indexing
{
return true;
}
}
}
return false;
}
int main()
{
std::vector<int> list{1,2,3,4,5}; // Uniform initialization Added in C++11.
// No need for push-backs of fixed data
if (FindSolution(list, 8))
{
std::cout << "There is a solution\n";
}
else
{
std::cout << "There is no solution\n";
}
return 0;
}

removing and shifting duplicates in array c++

I am trying to delete any duplicates but not having much success..
void deleatingRepeatingElement (int myArrayLength, int myArray[])
{
for (int i = 1 ; i < myArrayLength; i++){
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i ; j++){
if (myArray[i] == myArray[j]){
myArray[j] = myArray[j + 1];
myArrayLength--;
}
}
}
}
I think there were two main mistakes:
You didn't shift all of the following items when deleting.
You didn't "reset" after deleting.
Here is annotated code that seems to work:
#include <iostream>
/* Remove element at given index from array
* Returns the new array length
* (Note that "int array[]" means exactly the same as "int *array",
* so some people would consider "int *array" better style)
*/
int arrayRemoveAt(int index, int array[], int arrayLength)
{
// Check whether index is in range
if (index < 0 || index >= arrayLength)
return arrayLength;
for (int i = index + 1; i < arrayLength; i++)
{
array[i - 1] = array[i];
}
return arrayLength - 1;
}
/*
* Returns the new length of the array
*/
int deleatingRepeatingElement(int myArrayLength, int myArray[])
{
for (int i = 1; i < myArrayLength; i++)
{
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i; j++)
{
if (myArray[i] == myArray[j])
{
myArrayLength = arrayRemoveAt(i, myArray, myArrayLength);
// After deleting an entry, we must "reset", because now the index i
// might point to another number, which may be a duplicate
// of a number even before the current j.
// The i-- is so that after i++, we will end up with the same i
i--;
break;
}
}
}
// Important: The caller needs this for looping over the array
return myArrayLength;
}
int main(int argc, char **argv)
{
int array[] = {5, 6, 2, 1, 2, 6, 6};
int newSize = deleatingRepeatingElement(7, array);
for (int i = 0; i < newSize; i++)
{
std::cout << array[i] << std::endl;
}
return 0;
}
If you use a static array (such as in my example, as opposed to a dynamic one), you may consider using std::array or a template construction as shown in https://stackoverflow.com/a/31346972/5420386.
Here is the solution to your problem:
#include <iostream>
#include <set>
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))
using namespace std;
int *deleteRepeatedElements(int myArray[], int arrayLength) {
set<int> setArray (myArray, myArray+arrayLength);
int setLength = setArray.size();
static int myPointer[4];
int i = 0;
for (set<int>::iterator it = setArray.begin(); it != setArray.end(); ++it) {
myPointer[i] = *it;
i++;
}
return myPointer;
}
int main() {
int myArray[6] = {5, 3, 5, 6, 2, 4};
int arrayLength = ARRAY_SIZE(myArray);
int* myPointer = deleteRepeatedElements(myArray, arrayLength);
int pointerLength = sizeof(myPointer)/sizeof(*myPointer);
for (int* i = &myPointer[0]; *myPointer != 0; i = ++myPointer) {
cout << *i << " ";
}
cout << '\n';
return 0;
}

How can I sort array elements by number of divisors?

My problem is that I hit an obstacle while I was solving some exercises.
The source of the problem is that I have to write a program which sort descending an array by the number of each element's divisors, but when two element has the same number of divisors it should sort ascending those values.
My code so far:
#include <iostream>
#include <fstream>
using namespace std;
int cntDiv(int n) //get number of divisors
{
int lim = n;
int c = 0;
if(n == 1)
return 1;
for(int i = 1; i < lim; i++)
{
if(n % i == 0)
{
lim = n / i;
if(lim != i)
c++;
c++;
}
}
return c;
}
int main()
{
ifstream fin("in.txt");
int n, i, j;
fin >> n;
int v[n];
for(i = 0; i < n; i++)
fin >> v[i];
int div[n];
for(i = 0; i < n; i++)
div[i] = cntDiv(v[i]);
for(i = 0; i < n - 1; i++)
{
for(j = i + 1; j < n; j++)
{
if(div[i] < div[j] && div[i] != div[j]) //if the number of divisors are different
{
int t = v[i];
v[i] = v[j];
v[j] = t;
t = div[i];
div[i] = div[j];
div[j] = t;
}
if(div[i] == div[j] && v[i] > v[j]) //if the number of divisors are the same
{
int t = v[i];
v[i] = v[j];
v[j] = t;
}
}
}
for(i = 0; i < n; i++)
{
cout << v[i] << " ";
}
return 0;
}
In.txt:
5
12 20 4 100 13
Output:
100 12 20 4 13
Although it works fine with this one and many other. For bigger inputs it exceeds the time limit which is 0.1s. Any advice how should I rewrite the sorting? (I wrote bubble sort because I could not implement sorting array by property via quicksort)
Use an array of structures. The structure would contain the original value and a container of divisors:
struct Number_Attributes
{
int number;
std::list<int> divisors;
};
You can then write a custom comparator function and pass to std::sort:
bool Order_By_Divisors(const Number_Attributes& a,
const Number_Attributes& b)
{
return a.divisors.size() < b.divisors.size();
}
The sorting then becomes:
#define ARRAY_CAPACITY (20U)
Number_Attributes the_array[ARRAY_CAPACITY];
//...
std::sort(&array[0], &array[ARRAY_CAPACITY], Order_By_Divisors);
The generation of divisors is left as an exercise for the OP.
Reworking your code with std::sort:
std::vector<std::pair<int, int>> customSort(const std::vector<int>& v)
{
std::vector<std::pair<int, int>> ps;
ps.reserve(v.size());
// We don't have zip sort :/
// So building the pair
for (auto e : v)
{
ps.emplace_back(e, cntDiv(e));
}
std::sort(ps.begin(), ps.end(), [](const auto&lhs, const auto& rhs) {
// descending number of divisors, increasing value
return std::make_tuple(-lhs.second, lhs.first)
< std::make_tuple(-rhs.second, rhs.first);
});
return ps;
}
int main()
{
const std::vector<int> v = {12, 20, 4, 100, 13};
const auto res = customSort(v);
for(const auto& p : res)
{
std::cout << p.first << " ";
}
}
Demo

Function returning the index of largest value, skipping previously returned values

I need to make a function in c++ that returns the index of the largest value. Whenever it is called it should skip the index it returned previously and return the index storing the next largest value.
for eg if : -
int a[8] = {2,6,4,12,5,7,12,8}
the function should return 3 then 6 then 7, 5,1,4,2,0
Edit :-
#include <iostream>
#include <vector>
using std::vector;
int return_max_index(vector<int> valuebyweight, int n)
{
int max_index = 0;
for(int i=0; i<n; i++)
{
if(valuebyweight[i] >= valuebyweight[max_index])
{
max_index = i;
}
}
return max_index;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
double value = 0.0;
vector<int> valuebyweight(n);
for(int i=0; i<n; i++)
{
valuebyweight[i] = values[i] / weights[i];
}
while(capacity!=0)
{
int max_index = return_max_index(valuebyweight, n);
if(weights[max_index] <= capacity)
{
capacity -= weights[max_index];
value += values[max_index];
}
else
{
value += (valuebyweight[max_index] * capacity);
capacity = 0;
}
}
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values,n);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
Trying to implement Fractional Knapsack algorithm. If I run the code on input
3 50
60 20
100 50
120 30
it should give the answer 180 but it returns 200 instead because my 'return_max_index' function is returning the same index again (2) but I somehow want it to skip the index it returned previously (2) and return the index that has the next highest 'valuebyweight' i.e 0.
Try this code.I made some minor changes.
#include <iostream>
#include <vector>
using std::vector;
int return_max_index(vector<int> valuebyweight, int n)
{
int max_index = 0;
for(int i=0; i<n; i++)
{
if(valuebyweight[i] >= valuebyweight[max_index])
{
max_index = i;
}
}
//if all the values in valuebyweight are 0
if(valuebyweight[max_index]==0)
{
return -1;
}
else
return max_index;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
double value = 0.0;
vector<int> valuebyweight(n);
for(int i=0; i<n; i++)
{
valuebyweight[i] = values[i] / weights[i];
}
while(capacity!=0)
{
int max_index = return_max_index(valuebyweight, n);
if(max_index==-1)
{
break;
}
if(weights[max_index] <= capacity)
{
capacity -= weights[max_index];
value += values[max_index];
// assign valuebyweight[max_index] to 0 as it already participated in optimal solution and need no longer to participate.
valuebyweight[max_index]=0;
}
else
{
value += (valuebyweight[max_index] * capacity);
capacity = 0;
}
}
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values,n);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
One way to do this is to just keep the list of found indices in a static local. But then, how do you know you haven't already seen this one before? So better to make it a class. Then you can also do some optimization: sort the array once, then just pop the next highest index from the result whenever it's called:
struct mysort{
const std::vector<int>& _tosort;
mysort(const std::vector<int> tosort) : _tosort(tosort) {}
bool operator()(int a, int b){ return _tosort[a] < _tosort[b]; }
}
class IndexFinder{
private:
std::vector<int> sorted_indices;
int invoked;
public:
IndexFinder(const std::vector<int>& tosort) :
sorted_indices(tosort.size()) {
invoked = 0;
for(size_t i=0; i<tosort.size(); ++i)
sorted_indices[i] = i;
std::stable_sort(sorted_indices.begin(), sorted_indices.end(),
mysort(tosort));
}
int IndexFinder::operator()(){
return sorted_indices[invoked++];
}
};
You should put in protections to IndexFinder::operator()() to handle what happens if the user calls it more times than there are indices in the vector. As a bonus you should be pretty easily able to change it into a template class to sort things other than ints.
This is not pretty (it modifies the array), but gives an idea:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int index_of_largest(int array[], size_t len) {
int r = INT_MIN;
int d = 0;
for (int i = 0; i < len; i++) {
if (array[i] > r) {
d = i;
r = array[i];
}
}
if (r != INT_MIN) {
array[d] = INT_MIN;
}
return d;
}
int main(){
int a[8] = {2, 6, 4, 12, 5, 7, 12, 8};
int len = (int)(sizeof(a) / sizeof(a[0]));
for (int i = 0; i < len; i++) {
printf("%d\n", index_of_largest(a, len));
}
}
OUTPUT
3
6
7
5
1
4
2
0
This is a little different than the previous answer #bloer gave, but shows somewhat of a shorter method (it still uses a class) by using C++ 11 (std::iota and usage if lambda in std::sort).
#include <algorithm>
#include <iostream>
#include <vector>
class MaxIndex
{
private:
std::vector<int> index;
public:
MaxIndex(const std::vector<int>& tosort) : index(tosort.size())
{
// initialize the indices
std::iota(index.begin(), index.end(), 0);
// sort the indices based on passed-in vector
std::sort(index.begin(), index.end(), [&](int n1, int n2)
{ return tosort[n1] > tosort[n2];});
}
// return the nth highest index
int getNthMaxIndex(int n) const { return index[n]; }
};
using namespace std;
int main()
{
std::vector<int> a = {2,6,4,12,5,7,12,8};
MaxIndex mi(a);
for (size_t i = 0; i < a.size(); ++i)
cout << mi.getNthMaxIndex(i) << endl;
}
Live Example
Second, is there a reason to consistently use n if you're going to use std::vector? A std::vector knows its own size, so passing (and using) extraneous variables denoting the number of elements in a vector is inviting a bug to be introduced somewhere. Just use the std::vector::size() function if you want to get the number of elements, or just pass the vector by itself.
In addition, you should be passing things like std::vector by either reference or const reference, depending on whether the passed-in vector will be changed or not. Passing std::vector by value (as you're doing now) incurs an (unnecessary) copy.

calculate the biggest sum of consecutive Elements ( in a list)

I'm trying to calculate the biggest sum of consecutive elements of a vector<int>, but I don't really know how to do:
I started to code that:
#include <iostream>
#include <vector>
using namespace std;
void calcule_somme(vector<int> tab);
void calcule_somme(vector<int> tab) {
int somme_partielle(0);
vector<int> element_les_plusgrand;
for(size_t i(0);tab.size();++i) {
for(size_t j(i+1);tab.size();++i) {
element_les_plusgrand.pushback(tab[i]);
if (tab[i]+tab[j]>compteur) {
element_les_plusgrand.push_back(tab[j]);
compteur = tab[i]+tab[j];
}
}
int main() {
return 0;
}
The function has to return: the biggest sum of consecutive element is "4,5,78" which is equal to 87.
#include <iostream>
#include <vector>
using namespace std;
int sum(const vector<int>& tab) {
int sum = 0;
for (size_t i = 0; i < tab.size(); i++) {
sum += tab[i];
}
return sum;
}
vector<int> calculate_sume(const vector<int>& tab) {
vector<int> ret, current;
int previous = -32767;
for (size_t i = 0; i < tab.size(); i++) {
if ((tab[i] > previous) == false) {
if (current.size() >= ret.size() && sum(current) > sum(ret))
ret = current;
current.clear();
}
current.push_back(tab[i]);
previous = tab[i];
}
for(size_t w(0);w<ret.size();++w) {
cout << ret[w]<< " ";
}
return ret;
}
int main() {
vector<int> tab ={-4,5,6,-9,24,-35,4,5,78};
sum(tab);
calculate_sume(tab);
return 0;
}
Tell me -4 5 6
First off, you'll need to keep track of two vectors, one to hold the largest sequence of characters and one to hold the values that currently being calculated.
From there, you just need to iterate through the elements in the source vector keeping track of the previous and current value in the vector.
If the current value is greater than the previous value, you push the current value into the current vector and then assign the previous value to the current value.
If it's less than (or I'm assuming equal), the consecutive sequence is completed and you should start with the next sequence. This means that you need to do the following:
Determine if the current vector's size is greater than or equal the largest vector's size and the sum of the current vector is greater than the sum of the largest. If it is, assign largest = current;
Clear the current list
Assign previous to the current int value.
Here is how I would write it:
int sum(const vector<int>& tab) {
int sum = 0;
for (size_t i = 0; i < tab.size(); i++) {
sum += tab[i];
}
return sum;
}
vector<int> calculate_some(const vector<int>& tab) {
vector<int> ret, current;
int previous = tab[0];
current.push_back(previous);
for (size_t i = 1; i < tab.size(); i++) {
current.push_back(tab[i]);
if (tab[i] <= previous || i == (tab.size() - 1)) {
if (current.size() >= ret.size() && sum(current) > sum(ret))
ret = current;
current.clear();
}
previous = tab[i];
}
return ret;
}
And here is how I am calling it:
int main() {
vector<int> tab = { -4,5,6,-9,24,-35,4,5,78 };
vector<int> results = calculate_some(tab);
for (size_t w(0); w<results.size(); ++w) {
cout << results[w] << " ";
}
system("pause");
return 0;
}
pseudocode:
Algorithm Biggest_Consecutive_Sum
Input: Vector v
Output: Biggest_Sum
begin
index = 0, Biggest_Sum = 0
while(index < v.size()){
Sum = 0
while (Sum + V[index] > Sum){
Sum = Sum + V[index]
index = index + 1
}
if(Sum > Biggest_Sum) Biggest_Sum = Sum
index = index + 1
}
return Biggest_Sum
end