Suppose we're given an array of integers. A[n], for instance
A[11]={10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
and a list of prime numbers, B[k], for instance
B[2]={3, 5}
For each element, b_i in B[k], we find the elements in A[n] that are divisible by it and combine them into an equivalence class, and if an element in A[n] is not divisible by any element in B[k], then it's an equivalence class consisting of a single element. For instance, in the above example, the equivalence classes would be
{12, 15, 18}
{10, 15, 20}
{11}
{13}
{14}
{16}
{17}
{19}
(15 was repeated as it's divisible by both 3 and 5), where first equivalence class consists of numbers in A[n] divisible by 3, and second are the ones divisible by 5, and the rest are elements that are co-prime to 3 and 5. Basically, given A[n] and B[k], I want to calculate how many equivalence sets can be created, and in the above example, it would be 8.
and what I came up with is the following:
for(j=0; j<n; j++){
check[j]=true;
}
for(i=0; i<k; i++){
helper=0;
for(j=0; j<n; j++){
if(check[j]==true){
if(A[j]%B[i]==0){
check[j]==false;
helper++;
}
}
}
if(helper>0){
count++;
}
}
for(j=0; j<n; j++){
if(check[j]==true){
count++;
}
}
check is the array of boolean that returns false if it already belongs to some equivalence class and true if it does not belong to an equivalence class yet.
this calculates the number of equivalence sets divisible by elements in B[k], but now, I'm not sure what to do with singleton sets as check array members are all re-set to true after the loop.
(I tried
for(j=0; j<n; j++){
if(check[j]==true){
count++;
}
}
after the above loop, but it only adds n to the count)
Can someone help me on this? Is there a more efficient way of doing it? Also, what should I do with the singleton sets?
Thanks.
PS. Since 15 is repeated in 2 sets, it's not technically an equivalence class. Sorry about it.
Same code sample rewritten using standard containers:
#include <iostream>
#include <map>
#include <set>
using namespace std;
int A[]= { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
int B[]= { 3, 5 };
typedef set<int> row;
int
main()
{
map<int, row> results;
// Fill
for (auto i = begin(A); i != end(A); ++i)
for (auto j = begin(B); j != end(B); j++)
{
if (*i % *j)
results[*i] = row();
else
{
if (results.find(*j) == results.end())
results[*j] = row();
results[*j].insert(*i);
}
}
// Cleanup
for (auto j = begin(B); j != end(B); j++)
for (auto i : results[*j])
results.erase(i);
// Dump
for (auto i : results)
{
cout << "{ ";
if (i.second.size())
for (auto j = i.second.begin(), nocomma = --i.second.end(); j != i.second.end(); ++j)
cout << *j << (j == nocomma ? " " : ", ");
else
cout << i.first << " ";
cout << "}" << endl;
}
return 0;
}
The output:
{ 12, 15, 18 }
{ 10, 15, 20 }
{ 11 }
{ 13 }
{ 14 }
{ 16 }
{ 17 }
{ 19 }
Related
I use this script to print odd number from 1 to 30.
#include <iostream>
using namespace std;
int main( ) {
int i = 1 ;
// whele loop from 1 to 30
while (i <= 30) {
cout << i<< " , ";
i = i + 2;
}
return 0;
}
So the output Will be 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29
What i must to do if i want to add Even number after 4 Odd numbers. The output Will be like 1, 3, 5, 7, 10, 11, 13, 15, 17, 20, 21, 23, 25, 27, 30.
I hope someone can help me with this problem. Thank you
At each iteration you print a number as you are doing now, however, every 5th iterations what you do is a bit different. This is a condition you need to test in each iteration: if true, print like this, if false, print like that.
Start with the loop as you did. Since you using a counting variable that you always increment, a for loop seems more natural than a while.
int main() {
for(int i = 1; i <= 30; i += 2) {
cout << i << " , ";
}
return 0;
}
Now you add the condition test. For that, you can introduce another variable (numOddNumbers) to keep track of how many odd numbers you have printed.
int main() {
int numOddNumbers = 0;
for(int i = 1; i <= 30; i += 2) {
if(numOddNumbers > 0 && numOddNumbers % 4 == 0) {
cout << i + 1 << " , ";
numOddNumbers = 0;
} else {
cout << i << " , ";
numOddNumbers++;
}
}
return 0;
}
For the condition we can use numOddNumbers % 4 == 0 to check that numOddNumbers is amultiple of 4, but since we do not want the condition to be true when numOddNumbers == 0 we also make sure that numOddNumbers > 0.
Notice that differently from i, the numOddNumbers variable is only incremented when the condition is false, since that is when we print an odd number.
This code will print
1 , 3 , 5 , 7 , 10 , 11 , 13 , 15 , 17 , 20 , 21 , 23 , 25 , 27 , 30 ,
Note: An interesting exercise for you is to simplify this code to use just the counting variable, without the extra numOddNumbers variables. The pattern is well defined and you know that the difference is in every 5th itertion.
I can offer the solution of your problem.
#include <iostream>
#include <vector>
using namespace std;
void showContentVector(vector<int>& input)
{
for(int i=0; i<input.size(); ++i)
{
cout<<input[i]<<", ";
}
return;
}
void oddEvenNumbers(int start, int stop, int quantity, vector<int>& input)
{
if(start>stop)
{
return;
}
if(start%2!=0)
{
input.push_back(start);
++quantity;
}
if(quantity==4)
{
start+=3;
input.push_back(start);
quantity=0;
}
oddEvenNumbers(start+1, stop, quantity, input);
return;
}
void solve()
{
vector<int> inputVector;
oddEvenNumbers(0, 30, 0, inputVector);
cout<<"inputVector <- ";
showContentVector(inputVector);
return;
}
int main()
{
solve();
return 0;
}
Here is the result:
inputVector <- 1, 3, 5, 7, 10, 11, 13, 15, 17, 20, 21, 23, 25, 27, 30,
If you will need an explanation of the solution, write the corresponding comment.
#include <iostream>
using namespace std;
int main(void) {
int i = 1;
int step = 1;
while (i <= 30) {
if (step % 5 == 0) {
cout << (i + 1) << ",";
}else{
cout << i << ",";
}
i += 2;
step++;
}
return 0;
}
I have a pretty simple question. My goal for this short program is for it to display the set of numbers(which is hard coded), then have the user specify which index a number of the array should be deleted from. It then outputs the new array. This program works but has one major error. When I run it and choose position 2 for example, which should delete 45, instead deletes 34. The program outputs :
12
45
2
8
10
16
180
182
22
instead of :
12
34
2
8
10
16
180
182
22
notice that the number position I want removed instead removes in the position before the number I actually want removed, if you remember that lists start at 0. Thank you!
//This program demos basic arrays
#include <iostream>
using namespace std;
const int CAP = 10;
int main()
{
//read index from user, delete number in position of index they specify.
//when printing the list, number should be gone.
int size;
int list[CAP] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
size = 10;
int i, delIndex;
cout << "Your list is: " << endl;
for (i = 0; i < CAP; i++)
{
cout << list[i] << endl;
}
cout << "\nPlease enter index to delete from: ";
cin >> delIndex;
for (i = delIndex; i <= 10; i++)
{
list[i - 1] = list[i];
}
cout << "The index position you specified has been deleted." << endl;
cout << "The new array is: " << endl;
for (i = 0; i < (size - 1); i++)
{
cout << list[i] << endl;
}
return 0;
}
Replace this:
for (i = delIndex; i <= 10; i++)
{
list[i - 1] = list[i];
}
with that:
for (i = delIndex; i < size-1; i++)
{
list[i] = list[i+1];
}
Since you are with C++, why not just using a std vector?
#include <vector>
// Initialize
int vv[10] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
std::vector<int> myvector(&vv[0], &vv[0]+10);
There are other easier ways to initialize the vector depending on the compiler. See how to initialize a vector.
Then you can just use the erase method of the vector (here I assume the user knows the indexing starts with 0, otherwise you can just put delIndex-1):
myvector.erase (myvector.begin()+delIndex);
You can easily iterate over the vector to show its contents (there are easier ways of doing this depending on the compiler, use the auto keyword).
for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
std::cout << ' ' << *it;
Beginner in C++ here and learning arrays. The program below is supposed to separate positive and negative numbers in an array. However, it is returning random numbers in both the splitPos and splitNeg functions.
Could someone ever so kindly advice and show me what is incorrect in the functions and what can be done to omit these random digits so that only positive and negative digits are returned respectively by the program for each function/loop? I am obviously not seeing and/or understanding what is incorrect.
Thank you so very much for your help and time in advance!!!
#include <iostream>
using namespace std;
//function prototypes
int splitNeg(int[], int[], int);
int splitPos(int[], int[], int);
void displayArr(int[], int);
int main()
{
const int SIZE = 20;
int usedPos, usedNeg;
int origArr[SIZE] = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 17, 6, 31, -4, 3, 19, 15, -9, 12, -18 };
int posArray[SIZE];
int negArray[SIZE];
usedPos = splitPos(origArr, posArray, SIZE);
usedNeg = splitNeg(origArr, negArray, SIZE);
cout << "Positive Values: " << endl;
displayArr(posArray, usedPos);
cout << endl;
cout << "Negative Values: " << endl;
displayArr(negArray, usedNeg);
return 0;
}
int splitPos(int origArr[], int posArray[], int SIZE)
{
int j = 0;
for (int i = 0; i < SIZE; i++ && j++)
{
if (origArr[i] >= 0)
posArray[j] = origArr[i];
}
return j;
}
int splitNeg(int origArr[], int negArray[], int SIZE)
{
int k = 0;
for (int i = 0; i < SIZE; i++ && k++)
{
if (origArr[i] < 0)
negArray[k] = origArr[i];
}
return k;
}
void displayArr(int newArray[], int used)
{
for (int i = 0; i < used; i++)
cout << newArray[i] << endl;
return;
}
If you change your for-loops a bit:
int splitPos(int origArr[], int posArray[], int SIZE)
{
int j = 0;
for (int i = 0; i < SIZE; i++)
{
if (origArr[i] >= 0)
posArray[j++] = origArr[i];
}
return j;
}
int splitNeg(int origArr[], int negArray[], int SIZE)
{
int k = 0;
for (int i = 0; i < SIZE; i++)
{
if (origArr[i] < 0)
negArray[k++] = origArr[i];
}
return k;
}
you will get the result you desire.
The counter variables of your target arrays only get increased if you find a value that matches the criterion of being less (or greater) than 0.
I honestly do not understand what you tried to achieve with a ... hmmm.. "combined" increase like i++ && j++, this goes into short circuit evaluation.
j and k must be incremented only when the correct value is copied to posArray and negArray, by definition.
If the value is the wrong sign, j and k, obviously, should remain unchanged, since the number of values with the right sign, in the corresponding output array, does not change on this iteration.
This is not what the code is doing. It is incrementing them on every iteration of the loop, except for the one where i is 0.
There is a standard algorithm made just for that. It is named std::partition.
Your code with that algorithm will look like this:
struct SplitPosAndNegResult {
std::vector<int> negatives;
std::vector<int> positives;
};
auto splitPosAndNeg(std::array<int, SIZE> orig) {
// Here `it` is the first element of the second partition (positives)
auto it = std::partition(orig.begin(), orig.end(), [](int i){ return i < 0; });
return SplitPosAndNegResult{
std::vector<int>(orig.begin(), it), // negative numbers
std::vector<int>(it, orig.end()) // positive numbers
};
}
Then, use it like that:
int main () {
auto result = splitPosAndNeg({ 4, -7, 12, 6, 8, -3, 30, 7, -20, -13,
17, 6, 31, -4, 3, 19, 15, -9, 12, -18});
for (int n : result.positives) {
std::cout << n << ' ';
}
std::cout << std::endl;
for (int n : result.negatives) {
std::cout << n << ' ';
}
std::cout << std::endl;
}
This program will output this:
7 30 8 17 6 31 6 3 19 15 12 12 4
-18 -7 -9 -4 -13 -3 -20
Here's a live example at Coliru.
All the answers in this post are good, but I'm disappointed that none of them talk about the STL algorithms!
A good c++ programmer must know the language but he have to know also the C++ library.
look the following code:
#include <iostream>
#include <array>
#include <algorithm>
#include <string>
using namespace std;
template<typename T>
void print(const string& desc, T first, T last)
{
cout << desc;
for_each(first, last,
[](const auto& i ) { cout << i << ' ';});
cout << endl;
}
int main()
{
array<int, 20> originalArray = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 17, 6, 31, -4, 3, 19, 15, -9, 12, -18 };
print("original array is ", begin(originalArray), end(originalArray));
auto it = partition(begin(originalArray), end(originalArray),
[](int n) { return n >= 0; });
print("now original array is ", begin(originalArray), end(originalArray));
print("positives are: ", begin(originalArray), it);
print("negatives are: ", it, end(originalArray));
return 0;
}
More generally you want partition your set with a predicate.
Look to my code do you find any if or for? It's impossible make mistakes this way!
The only thing that does matter in the whole code is auto it = partition(begin(originalArray), end(originalArray), [](int n) { return n >= 0; }); that can be read as: partition from start to finish of originalArray elements that are positive.
#include<iostream>
using namespace std;
int main(){
int a[10]={9,4,-3,-2,1,-1,5,7,-9,-5};
int low=0;
int high=10-1;
while(low<high){
while(a[low]>=0){
low++;
}
while(a[high]<=0){
high--;
}
if(low<high){
int temp=a[low];
a[low]=a[high];
a[high]=temp;
}
}
for(int i=0;i<10;i++){
cout<<a[i]<<" ";
}
}
Time Complexity: O(n)
I tried sorting with the simple case of
test = {12, 11, 13, 5, 6};
It does the spliting and merging of subparts in lefthalf and righthalf as
{11 12} & {5 6 13}
which is desired. But during Final Merging it takes lefthalf and righthalf as
{12 11} & {13 5 6}
And this gives the wrong answer of :
{12 11 13 5 6}
Why is this Happening ? Here is my code.
void mergesrt(deque<int> mydeq){
if (mydeq.size() > 1){
int mid = mydeq.size()/2;
deque<int> lefthalf(mydeq.begin(), mydeq.begin() + mid);
deque<int> righthalf(mydeq.begin() + mid, mydeq.begin() + mydeq.size());
mergesrt(lefthalf);
mergesrt(righthalf);
int i = 0;
int j = 0;
int k = 0;
cout << "--------------merging-----------" << endl;
while (i < lefthalf.size() && j < righthalf.size()){
if (lefthalf[i] < righthalf[j]){
mydeq[k] = lefthalf[i];
k++;
i++;
}
else{
mydeq[k] = righthalf[j];
k++;
j++;
}
}
while (i < lefthalf.size()){
mydeq[k] = lefthalf[i];
k++;
i++;
}
while (j < lefthalf.size()){
mydeq[k] = righthalf[j];
k++;
j++;
}
}
return;
}
The problem here is subtle and not easily noticed by new developers. You're passing your argument to mergsrt by value, which means a copy is made. The sorting is done on this copy, and the original deque is not changed. You need to pass by reference (mergsrt(deque<int> &)) instead.
Please help me use C++ to parse an array and only display numbers that are unique. I have written a program which answers most of the question below.
Question:
Use a one-demensional array to solve the following problem. Read in 20 numbers, each of which is between 10 and 100, inclusive. As each number is read, validate and store it in the array only if it isn't a duplicate of a number already read. After reading all the values, display only the unique values that the user entered. Provide for the "worst case" in which all 20 number are different. Use the smallest possible array to solve this problem.
What I've done:
My program creates a 20 item array. Prompts user for data, validates it and displays it. I have tried several way to only display unique data, however I have not accomplished what the question asks.
Sample User Input:
11, 12, 12, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
My Program Output:
{ 11, 12, 12, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }
Correct Program Output:
{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }
Any advice where to go with this. See below for code. Thank you for your help!
#include <iostream>
#include <array> // needed for c++11 arrays
using namespace std;
int main()
{
const int arraySize = 20; // limit array length to 20
array <int, arraySize userArray> = {};
//Populate array with user input and validate it to be between 10 and 100
for (int i = 0; i < userArray.size(); i++)
{
cout << "Enter a number between 10 and 100" << endl;
cin >> userArray[i]; // get user input assign it to proper array subscript
while(userArray[i] > 100 || userArray[i] < 10)//validate user input to be between 10 and 100
{
cout << "Number needs to be between 10 and 100. Enter a new number" << endl;
cin >> userArray[i]; //reassign the proper array subscript if needed
}
}
cout << endl;
//display the information to look like an array
//result looks like [ v, w, x, y, z ]
cout << "[ ";
//display array values
for (int i = 0; i < userArray.size() - 1; i++)
{
cout << userArray[i] << ", ";
}
//properly display last array item
cout << userArray[(userArray.size() - 1)] << " ]" << endl;
return 0; }
If you can use std::vector, then you can use following solution.
template <typename Type>
std::vector<Type> unique_entries (std::vector<Type> vec) {
for (auto iter = vec.begin (); iter != vec.end (); ++iter) {
auto f = std::find_if (iter+1, vec.end (), [&] (const Type& val) {
return *iter == val; // (X)
});
if (f != vec.end ()) {
vec.erase (std::remove (iter+1, vec.end (), *iter), vec.end ());
}
}
return vec;
}
template <typename T>
void show (std::vector<T> vec) {
for (const auto& v : vec) {
std::cout << v << " ";
}
std::cout << std::endl;
}
And example would be like that:
std::vector<int> vec {11, 12, 12, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};
std::vector<short> vec2 {1, 1, 1, 2, 3, 2, 1, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 10};
std::vector<std::string> vec3 {"a", "a", "a", "aa", "b", "b", "bb", "c"};
show (vec);
show (unique_entries (vec));
show (vec2);
show (unique_entries (vec2));
show (vec3);
show (unique_entries (vec3));
And the output:
11 12 12 12 13 14 15 15 16 17 18 19 20 21 22 23 24 25 26 27
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
1 1 1 2 3 2 1 2 1 2 3 2 1 2 3 2 1 2 10
1 2 3 10
a a a aa b b bb c
a aa b bb c
Look at the line (X), basically you can use this unique_entries for all types which offer operator==, but you have to keep in mind that this will probably fail if you use this function for floating point types.
Hope this is what you are looking for........... Basically I use an another array to store the elements already entered by the user. So when the user enters a number it checks whether it is already in the array of 'entered elements' or not.
#include<iostream>
#define MAX 20
using namespace std;
int main()
{
int list[MAX],visitedElements[MAX];
int noElements,element,currentIndex;
bool flag=false;
cout<<"Enter total no. of elements(MAX=20):"<<endl;
cin>>noElements;
for(int i=0; i<noElements; i++)
{
visitedElements[i] = -1;
}
for(int i=0;i<noElements;i++)
{
currentIndex=i;
cout<<"Enter Element:"<<endl;
cin>>element;
for(i=0;i<currentIndex;i++)
{
if(visitedElements[i] == element)
{
flag==true;
break;
}
}
if(flag == false)
{
list[i]=element;
visitedElements[i] = element;
}
flag = false;
}
cout<<"Elements in list are"<<endl;
for(int i=0 ; i<noElements ;i++)
cout<<list[i]<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main(){
int tab[10];
int i=0,j;
int number=0;
int counter=1;
bool flag=true;
int tries=0;
while(tries<10){
do{
cin>>number;
tries++;
if((number>100)||(number<10)){
cout<<"Wrong number, has to be between 10 and 100"<<endl;
}
}
while((number>100)||(number<10));
flag=true;
if(i==0){
tab[i]=number;
}
else{
for(j=0; j<counter; j++){
if(tab[j]==number){
flag=false;
i--;
break;
}
}
}
if(flag==true){
tab[i]=number;
counter++;
}
i++;
}
for(i=0; i<counter-1; i++){
cout<<tab[i]<<", ";
}
}
I kinda meesed it up probably. I'm new to programing but this is my solution.
So. You said it has to take 20 digits, mine takes 10, after 10 inputs it will list the array. So if my input is "10, 10, 10, 12, 13, 15, 15, 18, 22, 22"
the output is: "10, 12, 13, 15, 18, 22"
I could probably erase half of the code but like i said I'm a beginner and i was writing it in a hurry.
EDIT: Ups, small mistake in the array declaration. I was testing it for 5 elements and forgot to make a bigger array.
The question asked to use one array, so I would loop over the numbers already in the array after reading in each number and check for duplicates. It would look something like this:
#include <iostream>
constexpr int ARRAY_SIZE = 20;
int main()
{
int userArray[ARRAY_SIZE], validNumbers = 0;
for(int i = 0; i < ARRAY_SIZE; i++)
{
int num;
bool isGood = true;
std::cin >> num;
//code to check if input is in range here
for(int j = 0; j < validNumbers; j++)
{
if(userArray[j] == num)
{
isGood = false;
break;
}
}
if(isGood)
{
userArray[validNumbers] = num;
validNumbers++;
}
}
//userArray now contains all unique numbers in the order that they were entered
for(int i = 0; i < validNumbers; i++)
{
std::cout << userArray[i];
if(i < validNumbers - 1)
{
std::cout << ' ';
}
}
std::cout << '\n';
}
inside of your for loop, instead of makign the cin go directly into the array, add another int variable and set it to equal the input
cin >> variable
then make a for loop that iterates through your current array to make sure its not a duplicate; use the line below as your for loop
for(int j = 0; j < i; j++)
if the number is already in the array, just continue. Else, add it in.
Also, instead of using a for loop in the beginning, I would use a while loop with
while(i < arraysize)
Then deincrement array size every time you see a duplicate and only increment i when you add an element