I know how to check if number exist in the array, but not in a 2D array.
Please help me in 2D.
#include<iostream>
using namespace std;
int main()
{
int a[3] = { 4,5,6 };
int b, c;
int x = 1, fact = 1;
cout << "enter no ";
cin >> b;
for (int i = 0; i < 3; i++)
{
if (b == a[i]) {
c = a[i];
break;
}
}
cout << "no entered is present" << endl;
}
I know how to check if number exist in the array, but not in 2D array!
It is like you did for the one-dimensional array, instead of one, you need to now iterate through the rows and column. In another word, you need one more iteration.
#include<iostream>
int main()
{
int a[2][3]{ { 1,2,3 }, { 4,5,6 } };
int userInput = 5;
bool found = false;
for (int row = 0; !found && row < 2; ++row) // if not found and row size < 2
{
for (int col = 0; col < 3; ++col) // if column size < 3
{
if (userInput == a[row][col]) // access the element like this
{
// other codes
std::cout << "No entered is present\n";
found = true;
break;
}
}
}
}
However, using the row size and column size like this, I will not recommend so. You should be using better std::array(if you know the size at compile time), or std::vector(if the sizes are known at run time).
For example, using std::array you could have the following code(example code). Using the range based for-loop, and a simple function makes the code more readable and less error-prone. Also, you need to know the sizes known at compile time. (See live demo)
#include <iostream>
#include <array> // std::array
bool isIn2DArray(const std::array<std::array<int, 3>, 2>& arr, int val) /* noexcept */
{
// range based for-loop instead of index based looping
for (const std::array<int, 3> & row : arr)
for (const int element : row)
if (element == val)
return true; // if found in the array, just return the boolean!
return false; // if not found!
}
int main()
{
std::array<std::array<int, 3>, 2> a{ { { 1,2,3 }, { 4,5,6 } } };
int userInput = 5;
if (isIn2DArray(a, userInput)) // you call the function like this!
{
std::cout << "Found in the array!\n";
}
else
{
std::cout << "Didn't find!\n";
}
}
In case of wondering, how to provide isIn2DArray for any arbitrary array, do it by providing the sizes as non-template parameters as below. (See live demo)
#include <array> // std::array
template<std::size_t Row, std::size_t Col>
bool isIn2DArray(const std::array<std::array<int, Col>, Row>& arr, int val)/* noexcept */
{
// range based for-loop instead of index based looping
for (const std::array<int, 3> & row : arr)
for (const int element : row)
if (element == val)
return true; // if found in the array, just return the boolean!
return false; // if not found!
}
If the array is an actual 2D array, if you know how to check if a number exists in a 1D array, you can use the exact same code to determine if a value exists in a regular 2D array.
The trick is to write the code using pointers to the start and ending elements of the array. The reason why is that a 2D array stores its data in contiguous memory, no different than a 1D array.
Here is an example of the same search function working for both 1-dimensional and 2-dimensional arrays:
#include<iostream>
bool exists(int *start, int *end, int value)
{
while (start != end)
{
if ( value == *start )
return true;
++start;
}
return false;
}
int main()
{
int a[3] = {4,5,6};
bool found = exists(a, a + 3, 5);
if ( found )
std::cout << "The number 5 was found\n";
else
std::cout << "The number 5 was not found\n";
// now a 2d array
int a2[3][4] = {{1,2,3,4},{7,8,9,10},{2,43,2,0}};
found = exists(&a2[0], &a2[2][4], 43);
if ( found )
std::cout << "The number 43 was found\n";
else
std::cout << "The number 43 was not found\n";
found = exists(&a2[0][0], &a2[2][4], 11);
if ( found )
std::cout << "The number 11 was found\n";
else
std::cout << "The number 11 was not found\n";
// Let's try a 3D array for fun
int a3[2][3][4] = {{{1,2,3,4},{7,8,9,10},{2,43,2,0}},
{{6,9,1,56},{4,8,2,10},{2,43,2,87}}};
found = exists(&a3[0][0][0], &a3[1][2][4], 56);
if ( found )
std::cout << "The number 56 was found\n";
else
std::cout << "The number 56 was not found\n";
}
Output:
The number 5 was found
The number 43 was found
The number 11 was not found
The number 56 was found
Surprisingly, the same function worked for 1-dimensional, 2-dimensional arrays, and even 3 dimensional arrays, all due to the data being stored in contiguous memory.
The address of the starting element, and the address of one past the ending element in the array are provided to the function, thus the function knows where to start and where to end the search.
bool check2dArray(vector<vector<int>> mat, int n){
int rows = mat.size();
if (rows==0) return false;
int cols = mat[0].size();
for (int i=0; i<rows; i++){
for (int j=0; j<cols; j++){
if (n == mat[i][j]) return true;
}
}
return false;
}
template <class Matrix, class CheckValue>
bool CheckExists(const Matrix& M, const CheckValue& Value) {
for (const auto& m : M)
for (const auto& v : m)
if (v == Value)
return true;
return false;
}
int main(int, char**)
{
int cArray[10][100]; auto exists = CheckExists(cArray, 10);
std::vector<std::vector<int>> vec; exists = CheckExists(vec, 0);
std::array<std::array<int, 10>, 100> arr; exists = CheckExists(arr, 0);
return 0;
}
Related
Here is the function:
void printArray(const char arr[][3], int rows, int cols) {
// rows == 3 && cols == 3 is currently a placeholder. I have to confirm whether these are
// actually correct.
if (rows == 3 && cols == 3 && rows > 0 && cols > 0 && rows <= SIZE && cols <= SIZE) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << arr[i][j];
}
cout << '\n';
}
}
}
I need to figure out if the rows parameter inputted into the equation is actually correct. To do this, I need to calculate the size of the const char array from within the function.
I have tried adding the following to the if statement:
rows == sizeof(arr)/sizeof(arr[0])
cols == sizeof(arr[0])/sizeof(arr[0][0])
rows == sizeof(arr)/sizeof(arr[0])
cols == sizeof(arr[0])
None of these have worked. Please advise many thanks.
It does not work this way. arr is a pointer type (const char (*)[3]) and you cannot derive a size from it unless you use a function template:
#include <iostream>
using std::cout;
template <int rows, int cols>
void printArray(const char (&arr)[rows][cols])
{
static_assert(rows == 3 && cols == 3, "Dimension must be 3x3, mate!");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << arr[i][j];
}
cout << '\n';
}
}
int main()
{
char good[3][3] {};
char bad[2][3] {};
printArray(good);
printArray(bad);
}
Note that the above will automatically infer the dimensions from the array, and create an appropriate function. Additionally, there's a static assertion here that will fail to compile for anything other than a 3x3 array:
error: static assertion failed: Dimension must be 3x3, mate!
8 | static_assert(rows == 3 && cols == 3, "Dimension must be 3x3, mate!");
| ~~~~~^~~~
My advise top using "C" style arrays and move to C++ std::array.
//You could change your call to arr[3][3] but in general I would advice to switch to using std::array or std::vector in C++.E.g.printArray
#include <array>
#include <iostream>
// array is an object so unlike "C" style arrays you can return them from functions
// without having to use something like char** (which looses all size information)
std::array<std::array<char,3>,3> make_array()
{
std::array<std::array<char, 3>, 3> values
{ {
{'a','b','c'},
{'d','e','f'},
{'g','h','i'},
} };
return values;
}
// pass by const reference, content of array will not be copied and not be modifiable by function
// only will compile for 3x3 array
void show(const std::array<std::array<char, 3>, 3>& values)
{
// use range based for loops they cannot go out of bounds
for (const auto& row : values)
{
for (const char value : row)
{
std::cout << value;
}
std::cout << "\n";
}
}
int main()
{
auto values = make_array();
show(values);
return 0;
}
Note : the size of the arrays can be templated so your code will work for other array/matrix sizes as well.
I have an array of integers with a bunch of numbers from 1-10
Then I have an array of names(strings) which belong with the numbers a.e.
Numbers[0] = 5, Numbers[1] = 2
Names[0] = "Jeremy", Names [1] = "Samantha".
I can easily order the numbers with:
int n = sizeof(Numbers) / sizeof(Numbers[0]);
sort(Numbers, Numbers + n, greater<int>());
But then the names and numbers don't match at all.
How do I fix this?
A very common approach is to create an array of indices and sort that:
std::vector<int> indices(Numbers.size());
std::iota(indices.begin(), indices.end(), 0);
std::sort(indices.begin(), indices.end(),
[&](int A, int B) -> bool {
return Numbers[A] < Numbers[B];
});
The original arrays are not altered, but now indices can be used to access both arrays in the desired order.
If we want to reorder Numbers or Names in place, then we can
create a set of "back indices" that record where to find the element i in the sorted array:
std::vector<int> back_indices(indices.size());
for (size_t i = 0; i < indices.size(); i++)
back_indices[indices[i]] = i;
Now we can reorder, for example, Names in place in the desired order:
int index = 0;
std::string name = Names[index];
for (int i = 0; i < back_indices.size(); i++) {
index = back_indices[index];
std::swap(name,Names[index]);
}
I've tested this code which should give you the required behavior:
struct numberName {
int num;
string name;
};
bool compare(numberName a, numberName b){
return a.num < b.num; // if equal, no need to sort.
}
int main() {
numberName list[2];
list[0].num = 5, list[1].num = 2;
list[0].name = "Jeremy", list[1].name = "Samantha";
sort(list, list+2, compare);
}
Like HAL9000 said, you want to use a struct since this keeps variables that belong to each other together. Alternatively you could use a pair, but I don't know if a pair would be good practice for your situation or not.
This is a great example of the complexities introduced by using parallel arrays.
If you insist on keeping them as parallel arrays, here is a possible approach. Create a vector of integer indexes, initialised to { 0, 1, 2, 3, etc }. Each integer represents one position in your array. Sort your vector of indexes using a custom comparision function that uses the indexes to refer to array1 (Numbers). When finished you can use the sorted indexes to reorder array1 and array2 (Names).
One could also write their own sort algorithm that performs swaps on the extra array at the same time.
Or one could trick std::sort into sorting both arrays simultaneously by using a cleverly designed proxy. I will demonstrate that such a thing is possible, although the code below may be considered a simple hackish proof of concept.
Tricking std::sort with a cleverly-designed proxy
#include <iostream>
#include <algorithm>
constexpr size_t SZ = 2;
int Numbers[SZ] = {5, 2};
std::string Names[SZ] = {"Jeremy", "Samantha"};
int tempNumber;
std::string tempName;
class aproxy {
public:
const size_t index = 0;
const bool isTemp = false;
aproxy(size_t i) : index(i) {}
aproxy() = delete;
aproxy(const aproxy& b) : isTemp(true)
{
tempName = Names[b.index];
tempNumber = Numbers[b.index];
}
void operator=(const aproxy& b) {
if(b.isTemp) {
Names[index] = tempName;
Numbers[index] = tempNumber;
} else {
Names[index] = Names[b.index];
Numbers[index] = Numbers[b.index];
}
}
bool operator<(const aproxy& other) {
return Numbers[index] < Numbers[other.index];
}
};
int main() {
aproxy toSort[SZ] = {0, 1};
std::sort(toSort, toSort+SZ);
for(int i=0; i<SZ; ++i) {
std::cout << "Numbers[" << i << "]=" << Numbers[i] << std::endl;
std::cout << "Names[" << i << "]=" << Names[i] << std::endl;
}
return 0;
}
...and an even more cleverly-designed proxy could avoid entirely the need to allocate SZ "aproxy" elements.
Tricking std::sort with an "even more cleverly-designed" proxy
#include <iostream>
#include <algorithm>
class aproxy;
constexpr size_t SZ = 2;
int Numbers[SZ] = {5, 2};
std::string Names[SZ] = {"Jeremy", "Samantha"};
aproxy *tempProxyPtr = nullptr;
int tempNumber;
std::string tempName;
class aproxy {
public:
size_t index() const
{
return (this - reinterpret_cast<aproxy*>(Numbers));
}
bool isTemp() const
{
return (this == tempProxyPtr);
}
~aproxy()
{
if(isTemp()) tempProxyPtr = nullptr;
}
aproxy() {}
aproxy(const aproxy& b)
{
tempProxyPtr = this;
tempName = Names[b.index()];
tempNumber = Numbers[b.index()];
}
void operator=(const aproxy& b) {
if(b.isTemp()) {
Names[index()] = tempName;
Numbers[index()] = tempNumber;
} else {
Names[index()] = Names[b.index()];
Numbers[index()] = Numbers[b.index()];
}
}
bool operator<(const aproxy& other) {
return Numbers[index()] < Numbers[other.index()];
}
};
int main() {
aproxy* toSort = reinterpret_cast<aproxy*>(Numbers);
std::sort(toSort, toSort+SZ);
for(int i=0; i<SZ; ++i) {
std::cout << "Numbers[" << i << "]=" << Numbers[i] << std::endl;
std::cout << "Names[" << i << "]=" << Names[i] << std::endl;
}
return 0;
}
Disclaimer: although my final example above may technically be in violation of the strict-aliasing rule (due to accessing the same space in memory as two different types), the underlying memory is only used for addressing space-- not modified-- and it does seems to work fine when I tested it. Also it relies entirely on std::sort being written in a certain way: using a single temp variable initialized via copy construction, single-threaded, etc. Putting together all these assumptions it may be a convenient trick but not very portable so use at your own risk.
i have to return the max len of consecutive seq present in an array.
consider the example:-
N = 7
a[] = {2,6,1,9,4,5,3}
my code should return 6 but its giving 1. don't know how?
int findLongestConseqSubseq(int arr[], int N)
{
//Your code here
unordered_map<int,int> mp;
int ans=0;
for(int i=0;i<N;i++){
if(mp.count(arr[i])>0){
continue;
}
int len1=mp[arr[i]-1];
int len2=mp[arr[i]+1];
int ns=len1+len2+1;
ans=max(ans,ns);
mp[arr[i]-len1]=ns;
mp[arr[i]+len2]=ns;
// ans=max(ans,ns);
}
return ans;
}
There are two problems with your implementation.
The first issue is the code:
if(mp.count(arr[i])>0){
continue;
}
this code is not sufficient to ensure that repeated numbers do not make it into the rest of your loop (to see why this is, consider what happens with neither len1 or len2 are zero).
You can replace it with something like:
if(!mp.insert(pair<int,int>(arr[i], 1)).second) {
continue;
}
This will skip the rest of the loop if an entry for arr[i] exists, but also ensures that an entry will exist after the if expression is evaluated.
The second issue is with the code:
int len1=mp[arr[i]-1];
int len2=mp[arr[i]+1];
the subscript operator for maps in C++ has a side-effect of creating an entry if one does not exist. This is problematic for your algorithm because you do not want this to happen. If it did it would cause the previous piece of code to skip numbers it shouldn't. The solution is to use find but since the code for this is a little ugly (IMHO) it's probably neater to write a helper function:
inline int findOrDefault(const unordered_map<int, int>& map, int key, int defaultValue) {
auto find = map.find(key);
return (find == map.end()) ? defaultValue : find->second;
}
and use this to update your code to:
int len1=findOrDefault(mp, arr[i]-1, 0);
int len2=findOrDefault(mp, arr[i]+1, 0);
Putting this all together you end up with:
inline int findOrDefault(const unordered_map<int, int>& map, int key, int defaultValue) {
auto find = map.find(key);
return (find == map.end()) ? defaultValue : find->second;
}
int findLongestConseqSubseq(int arr[], int N)
{
unordered_map<int,int> mp;
int ans=0;
for(int i=0;i<N;i++){
if(!mp.insert(pair<int,int>(arr[i], 1)).second) {
continue;
}
int len1=findOrDefault(mp, arr[i]-1, 0);
int len2=findOrDefault(mp, arr[i]+1, 0);
int ns=len1+len2+1;
ans=max(ans,ns);
mp[arr[i]-len1]=ns;
mp[arr[i]+len2]=ns;
}
return ans;
}
Ok had a moment to look at this again and I came up with this. First we sort the array to make things easier. Then we can go through the numbers with one pass, counting each time the next consecutive number is greater by one. If the next number is not one greater after sorting, then we reset and start counting again, storing the highest streak count in max.
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
cout << "Get Longest Consecutive Streak: " << endl;
int intArray[] = { 9, 1, 2, 3, 4, 6, 8, 11, 12, 13, 14, 15 ,16 };
int arrayLength = size(intArray);
sort(intArray, intArray + arrayLength); //Sort Array passing in array twice plus amount of indexes in array
cout << "Sorted Array looks like this:" << endl; //Outputting sorted array to check
for (int i = 0; i < arrayLength; i++) {
cout << intArray[i] << " ";
}
cout << endl;
int count = 1;
int max = 1;
/*
* Loop through array, if the next number is one greater than current then add to count
* If it is not, reset the count.
* Store highest count value found passing through.
* */
for (int i = 0; i < arrayLength -1; i++) {
if (intArray[i + 1] == intArray[i] + 1) { //checking next value - is it equal to this one + 1?
count++;
}
else { //else if it is not, store the value if it is higher that what is currently there, then reset
if (max < count) {
max = count;
}
count = 1;
}
}
//Edge case: check again one more time if the current count (when finishing) is greater than any previous
if (max < count) {
max = count;
}
cout << "Longest Consecutive Streak:" << endl;
cout << max << endl;
return 0;
}
I have created a simple mode calculator and I am displaying random list - something like this:
12 14 11 10 15 13 16 13 14 14 11 13 16 15 15 15 10 14 13 14 12 13 14 12
The mode value is 6
The mode is 14
. But my problem is I can't get the pair list to show instead of showing the list way - I want to display it this as a item-count pair list :
{2,3}, {4,3}, {5,2}, {3,2}, {1,2}
and the modes are clearly 2 and 4.
can anyone help me solve this issue? thanks for the help.
Here is an image for more details: https://imgur.com/a/FYNcxkv
here is my code:
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
#include <random>
using namespace std;
default_random_engine e(static_cast<unsigned>(time(NULL)));
void fill(int a[], int size, int value)
{
for(int i = 0; i < size; i++)
a[i] = value;
}
void randomFill(int a[], int size, int lb, int up)
{
uniform_int_distribution<int> u(lb, up);
for(int i = 0; i < size; i++)
a[i] = u(e);
}
void show(int a1d[], int size)
{
for(int i = 0; i < size; i++)
cout << setw(2) << a1d[i] << ' ';
cout << endl;
}
int count(int a1d[], int size, int value)
{
int vcount = 0;
for(int i = 0; i < size; i++)
if(a1d[i] == value) vcount++;
return vcount;
}
int findLargest(int a1d[], int size)
{
int largest = a1d[0];
for(int i = 1; i < size; i++)
if(a1d[i] > largest) largest = a1d[i];
return largest;
}
/*
the mode of a set of things is that thing that appears the greater number of times in the set
a set may have several modes
*/
int computemodes(int source[], int size, int modes[], int& msize)
{
/*
1. fill the modes array with zeroes
*/
fill(modes, size, 0);
/*
2. store the number of times each source element appears in the modes array.
if an element appears more than once in the source array then its counts appears
more than once the modes array.
source and modes form a parallel array structure
*/
for(int i = 0; i < size; i++)
modes[i] = count(source, size, source[i]);
/*
3. calculate the largest number in the modes array. this number is the number of
times the mode or modes appears in the source array
*/
int modevalue = findLargest(modes, size);
/*
4. assign -1 to the mode array elements that are less than the mode value
now only mode values in the modes array are not equal to -1.
the corresponding elements in the source array are the modes.
*/
for(int i = 0; i < size; i++)
if(modes[i] != modevalue) modes[i] = -1;
/*
5. we use the modes array to identify the source elements that are modes:
any element in the modes array that is not -1 corresponds to a mode in the
source array. if the mode is 1 then every source element is a mode
and no element in the modes array is -1; if the mode is greater than 1 then
a. many modes array entries are -1
b. the number of times a mode appears in the source equals its corresponding modes value
c. the number of modes array entries that are not -1 are the number of times the modes
appear in the source array
the following nested for loop transforms the modes array into an array in which
the first appearance of a mode in the source corresponds to a modes array entry
that is not -1 and subsequent appearances of this mode in the source correspond to
modes array entries that are -1.
*/
for(int i = 0; i < size; i++)
if(modes[i] != -1) //first appearance of the mode in the source
for(int j = i + 1; j < size; j++)
if(source[i] == source[j]) modes[j] = -1;
//subsequent appearances
/*
at this point the usage of the modes array changes.
heretofore, an entry that is not -1 in the modes array is the number of times
a mode appears in the source array. now an entry in the modes array is a mode.
the loop adds modes from the source array to the modes array.
msize serves 2 purposes:
a. it is number of modes copied so far.
b. it is the next free modes array position.
*/
msize = 0;
for (int i = 0; i < size; i++)
if (modes[i] != -1) //first occurrence of a mode in the source
{
modes[msize] = source[i];
msize++;
}
return modevalue;
}
int main()
{
const int size = 24;
int a[size];
int m[size];
randomFill(a, size, 10, 16);
show(a, size);
int msize = 0;
int modevalue = computemodes(a, size, m, msize);
cout << "The mode value is " << modevalue << endl;
if (msize == 1)
cout << "The mode is ";
else
cout << "The modes are ";
show(m, msize);
system("pause");
return 0;
}
You can create your map count with:
template <typename T>
std::map<T, std::size_t> map_count(const std::vector<T>& v)
{
std::map<T, std::size_t> res;
for (const auto& e: v) { res[e]++; }
return res;
}
and from that:
template <typename T>
std::pair<const T, std::size_t> find_mode(const std::map<T, std::size_t>& m)
{
if (m.empty()) {throw std::runtime_error("empty map");}
return *std::max_element(m.begin(),
m.end(),
[](const auto& lhs, const auto& rhs){ return lhs.second < rhs.second; }
);
}
Demo
I would design your code problem something like this:
#include <iostream>
#include <string>
#include <random>
#include <vector>
#include <map>
#include <algorithm> // could be used in your calculate function - algorithm
#include <numeric> // same as above.
class ModeCaclulator {
private:
std::vector<int> generatedNumbers_;
int highestModeCount_;
int highestModeValue;
typedef std::map<int,int> Modes;
Modes allModeCounts_;
public:
ModeCalculator() = default; // default constructor
template<typename T = int> // variadic constructor
ModeCalculator( T&&... t ) : generatedNumbers_{ t... } {
calculateModes();
}
std::vector<int>& getAllNumbers() const { return generatedNumbers_; }
int getHighestModeCount() const { return getHighestModeCount_; }
int getHighestModeValue() const { return getHighestModeValue_; }
Modes getAllModes() const { return allModeCounts_; }
void generateNumbers(int count, int lower, int upper) {
std::random_device rd;
std::mt19937 gen( rd() );
std::uniform_int_distribution<> dis( lower, upper );
for ( int i = 0; i < count; i++ )
generateNumbers_.push_back( dis( gen ) );
}
void calculateModes() {
// This is where you would perform your algorithm
// After doing the proper calculations this is where you would
// save the highestModeValue_ & highestModeCount_ as well as
// populating the vector of maps member.
// In this function you can use local lambdas to find the highest mode count and value.
}
void displayModeInformation() const {
std::cout << Random Values: << '\n';
for ( auto& v : generatedNumbers )
std::cout << v << " ";
std::cout << '\n'
std::cout << "Highest Mode Count: " << highestModeCount_ << '\n';
std::cout << "Highest Mode Value: " << highestModeValue_ << '\n';
std::cout << "\n"
std::cout << "All Mode Count & Value Pairs:\n";
for ( auto& p : allModeCounts_ ) {
std::cout << "{" << p.first << "," << p.second << "}" << " "
}
std::cout << '\n';
}
};
int main() {
ModeCalculator mc;
mc.generateNumbers( 15, 1, 16 );
mc.calculateModes();
mc.displayModeInformation();
// If using variadic constructor
ModeCalculate mc2( 12, 15, 14, 19, 18, 12, 15, 19, 21, 12, 18, 19, 21, 14 );
// no need to call calculateModes() this constructor does that for u
mc2.displayModeInformation();
return 0;
}
This makes the code much more readable, and look how clean main is, and all of the functionality is encapsulated into a single class instead of a handful of floating functions... Internal data is protected or hidden and can only be retrieved through accessor functions. The use of stl containers provides a clean interface instead of the use of C style arrays and also helps to prevent the use of raw pointers, and dynamic memory - via new & delete or new[] & delete[]. It also allows the code to be easier to manage and to debug, and provides a user with a generic reusability.
I'm trying to delete all elements of an array that match a particular case.
for example..
if(ar[i]==0)
delete all elements which are 0 in the array
print out the number of elements of the remaining array after deletion
what i tried:
if (ar[i]==0)
{
x++;
}
b=N-x;
cout<<b<<endl;
this works only if i want to delete a single element every time and i can't figure out how to delete in my required case.
Im assuming that i need to traverse the array and select All instances of the element found and delete All instances of occurrences.
Instead of incrementing the 'x' variable only once for one occurence, is it possible to increment it a certain number of times for a certain number of occurrences?
edit(someone requested that i paste all of my code):
int N;
cin>>N;
int ar[N];
int i=0;
while (i<N) {
cin>>ar[i];
i++;
}//array was created and we looped through the array, inputting each element.
int a=0;
int b=N;
cout<<b; //this is for the first case (no element is deleted)
int x=0;
i=0; //now we need to subtract every other element from the array from this selected element.
while (i<N) {
if (a>ar[i]) { //we selected the smallest element.
a=ar[i];
}
i=0;
while (i<N) {
ar[i]=ar[i]-a;
i++;
//this is applied to every single element.
}
if (ar[i]==0) //in this particular case, we need to delete the ith element. fix this step.
{
x++;
}
b=N-x;
cout<<b<<endl;
i++;
}
return 0; }
the entire question is found here:
Cut-the-sticks
You could use the std::remove function.
I was going to write out an example to go with the link, but the example form the link is pretty much verbatim what I was going to post, so here's the example from the link:
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ' ' << *p;
std::cout << '\n';
return 0;
}
Strictly speaking, the posted example code could be optimized to not need the pointers (especially if you're using any standard container types like a std::vector), and there's also the std::remove_if function which allows for additional parameters to be passed for more complex predicate logic.
To that however, you made mention of the Cut the sticks challenge, which I don't believe you actually need to make use of any remove functions (beyond normal container/array remove functionality). Instead, you could use something like the following code to 'cut' and 'remove' according to the conditions set in the challenge (i.e. cut X from stick, then remove if < 0 and print how many cuts made on each pass):
#include <iostream>
#include <vector>
int main () {
// this is just here to push some numbers on the vector (non-C++11)
int arr[] = {10,20,30,30,20,10,10,20}; // 8 entries
int arsz = sizeof(arr) / sizeof(int);
std::vector<int> vals;
for (int i = 0; i < arsz; ++i) { vals.push_back(arr[i]); }
std::vector<int>::iterator beg = vals.begin();
unsigned int cut_len = 2;
unsigned int cut = 0;
std::cout << cut_len << std::endl;
while (vals.size() > 0) {
cut = 0;
beg = vals.begin();
while (beg != vals.end()) {
*beg -= cut_len;
if (*beg <= 0) {
vals.erase(beg--);
++cut;
}
++beg;
}
std::cout << cut << std::endl;
}
return 0;
}
Hope that can help.
If you have no space bound try something like that,
lets array is A and number is number.
create a new array B
traverse full A and add element A[i] to B[j] only if A[i] != number
assign B to A
Now A have no number element and valid size is j.
Check this:
#define N 5
int main()
{
int ar[N] = {0,1,2,1,0};
int tar[N];
int keyEle = 0;
int newN = 0;
for(int i=0;i<N;i++){
if (ar[i] != keyEle) {
tar[newN] = ar[i];
newN++;
}
}
cout<<"Elements after deleteing key element 0: ";
for(int i=0;i<newN;i++){
ar[i] = tar[i];
cout << ar[i]<<"\t" ;
}
}
Unless there is a need to use ordinary int arrays, I'd suggest using either a std::vector or std::array, then using std::remove_if. See similar.
untested example (with c++11 lambda):
#include <algorithm>
#include <vector>
// ...
std::vector<int> arr;
// populate array somehow
arr.erase(
std::remove_if(arr.begin(), arr.end()
,[](int x){ return (x == 0); } )
, arr.end());
Solution to Cut the sticks problem:
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
// Cuts the sticks by size of stick with minimum length.
void cut(vector<int> &arr) {
// Calculate length of smallest stick.
int min_length = INT_MAX;
for (size_t i = 0; i < arr.size(); i++)
{
if (min_length > arr[i])
min_length = arr[i];
}
// source_i: Index of stick in existing vector.
// target_i: Index of same stick in new vector.
size_t target_i = 0;
for (size_t source_i = 0; source_i < arr.size(); source_i++)
{
arr[source_i] -= min_length;
if (arr[source_i] > 0)
arr[target_i++] = arr[source_i];
}
// Remove superfluous elements from the vector.
arr.resize(target_i);
}
int main() {
// Read the input.
int n;
cin >> n;
vector<int> arr(n);
for (int arr_i = 0; arr_i < n; arr_i++) {
cin >> arr[arr_i];
}
// Loop until vector is non-empty.
do {
cout << arr.size() << endl;
cut(arr);
} while (!arr.empty());
return 0;
}
With a single loop:
if(condition)
{
for(loop through array)
{
if(array[i] == 0)
{
array[i] = array[i+1]; // Check if array[i+1] is not 0
print (array[i]);
}
else
{
print (array[i]);
}
}
}