C++ How to the total number of duplicate elements in the array? - c++

I am trying to finish my homework, but I have encountered some problems in the item of Duplicate Elements. I have tried to find out where the problem is, but I cannot find it. My code works fine when the sequence is small, but it becomes problematic when the sequence is large.
In this sequence, I expect to get the number in the picture, but I always get the number in the second picture. As you can see, there is always a problem in this item in the duplicate element.
#include <iostream>
using namespace std;
int main()
{
int count = 0;
int arrayA[25];
int arrayB[25];
int min,max;
int num;
int i = 0;
int n = 0;
int temp = 0;
int sum = 0;
//Input
cout << "Input the number of elements to store in the array: ";
cin >> n;
cout << n << endl;
cout << "Input "<< n <<" integers:" << endl;
//Store arrayA
if(count < n){
for(i = 0; i < n; i++){
cin >> num;
cout << "integer - " << count;
cout << " : " << num <<endl;
arrayA[count] = num;
count++;
}
}
//store arrayB
for(i = 0;i < count; i++){
arrayB[i] = arrayA[count - i - 1];
}
//Forwards Array
cout << "The values stored into the array are :" << endl;
for(i = 0;i < count; i++){
cout << arrayA[i] << " ";
}
cout << endl;
//Backwards Array
cout << "The values stored into the array in reverse are :" << endl;
for(i = 0; i < count; i++){
cout << arrayB[i] <<" ";
}
cout << endl;
//Sum
for(i = 0; i < count; i++){
sum += arrayA[i];
}
//Max & Min
for(i = 0; i < count;i++){
if(max < arrayA[i]){
max = arrayA[i];
}
}
for(i = 0; i < count; i++){
if(min > arrayA[i]){
min = arrayA[i];
}
if(arrayA[i]== 0){
min = 0;
break;
}
}
//Duplicate elements
count = 0;
for(i = 0; i < n; i++){
for(temp = i + 1; temp < n; temp++){
if(arrayA[i] == arrayA[temp] ){
count++;
break;
}
}
}
cout << "The sum of all elements of the array is ";
cout << " " << sum << endl;
cout << "The total number of duplicate elements in the array is ";
cout << count << endl;
cout << "The maximum and minimum element in the array are ";
cout << min << " , " << max;
return 0;
}

You should try debugging more by printing, to know what is happening. You are not really taking into account that a number can be repeated several times and depending on the spread, it will count them several times. And here is why:
//Duplicate elements
count = 0;
for(i = 0; i < n; i++){
for(temp = i + 1; temp < n; temp++){
//cout << "Comparing "<< arrayA[i] << " to "<< arrayA[temp]<<endl;
if(arrayA[i] == arrayA[temp] ){
cout << "ITEM DUPLICATED at i , "<<i<< " item "<< arrayA[i]<< " and temp "<< temp<< " item "<< arrayA[temp] << endl;
count++;
break;
}
}
}
ITEM DUPLICATED at i , 0 item 4 and temp 7 item 4
ITEM DUPLICATED at i , 2 item -2 and temp 10 item -2
ITEM DUPLICATED at i , 4 item -3 and temp 14 item -3
ITEM DUPLICATED at i , 5 item 3 and temp 11 item 3
ITEM DUPLICATED at i , 7 item 4 and temp 8 item 4
ITEM DUPLICATED at i , 12 item -1 and temp 13 item -1
As you can see, there is a 4 - 4 twice. It can be seen quite easily if you do it in paper (although you shouldn't)
4A -4B -2C 1D -3E 3F 5G 4H 4I 0J -2K 3L -1M -1N -3O
4a -4b -2c 1d -3e 3f 5g 4h 4i 0j -2k 3l -1m -1n -3o
Connections made:
4A 4h
-2C -2k
-3E -3o
3F 3l
4H 4i
So the code technically is doing what you are asking it to do. if you want to count UNIQUELY (if a 4 appears 15 times, count it as only that 4 is repeated), you should be checking if the number has already been checked. Using a vector or map (dictionaries in C++) can allow you to do that! Or lists with lists (the element, and the number of occurences)

Related

Find the product of elements located between the maximum and minimum elements of an array

#include <iostream>
using namespace std;
int main()
{
int n, a, b,min,max, Prod = 1, Sum = 0;
cout << "Initialize an array n: ";
cin >> n;
do
{
cout << "Input the start value: ";
cin >> a;
cout << "Input the end value: ";
cin >> b;
if (!(a < b))
{
cout << "a is bigger than b, please enter new values " << endl;
continue;
}
} while (!(a < b));
int* lpi_arr;
lpi_arr = new int[n];
srand(time(NULL));
cout << "Int numbers from " << a << " to " << b << endl;
for (int i = 0; i < n; i++)
{
lpi_arr[i] = rand() % (b - a) + a;
cout << lpi_arr[i] << " ";
}
max = lpi_arr[0];
for (int i = 0; i < n; i++)
{
if (max < lpi_arr[i])
max = lpi_arr[i];
}
min = lpi_arr[0];
for (int i = 0; i < n; i++)
{
if (min > lpi_arr[i])
min = lpi_arr[i];
}
cout << "\nmin element is = " << min << endl;
cout << "\nmax element is = " << max << endl;
for (int i = max + 1; i < min; i++)
Prod *= lpi_arr[i];
for (int i = 0; lpi_arr[i] < 0 && i < n; i++)
Sum += lpi_arr[i];
cout << "Summ =" << Sum << endl << "Prod = " << Prod << endl;
delete[] lpi_arr;
}
The main purpose of this code is to calculate the sum of negative numbers of an array, and multiplication of elements located between the maximum and minimum elements of an array.
The problem is that the code implements only 1(one) as an answer, and I don't know how to change it. Every other part of the code works well, but if you have any recommendations I'd also like to read it. Waiting for your help.
Your issue is that you're confusing array indexes with array values.
Here you're assigning max (and same with min) to an array value.
max = lpi_arr[i];
Here you're treating max (and same with min) as an array index.
for (int i = max + 1; i < min; i++)
Prod *= lpi_arr[i];

How to set up a partition without sorting?

I am having trouble creating a partition for set inputs. I have tried two things, the first is commented out and it is just some basic pseudo code for a partition algorithm and the second is what I interpreted from the class notes. First off the main function is fine, that was given to us. I only need to finish coding the partition function. Everything commented in the partition function is my first attempt, everything not commented is my second attempt.
Here is some inputs we are supposed to test along with the proper results:
1 2 3 4 5 6 7  pivot is 4; elements less than pivot are in the left section
8 7 6 5 4 3 2 1  pivot is 5; elements less than pivot are in the left section
5 1 4 3 6 7 8 2  pivot is 3; elements less than pivot are in the left section
4 3 1 2 7 5  pivot is 1; the left section is empty
2 6 8 4 1 7  pivot is 8; the right section is empty
int partition(int a[], int first, int last) {
/* int pivot = a[last / 2];
//cout << pivot << endl;
int i = (first - 1);
for (int j = first; j <= last; j++) {
if (a[j] < pivot) {
i++;
//cout << pivot << endl << i << endl << j << endl;
swap(a[i], a[j]);
}
}
cout << pivot << endl << i << endl << first << endl << last << endl;
//swap(a[i + 1], a[last]);
return (i + 1);
}*/
swap(a[first],a[(first+last)/2]);
int pivot = a[first];
int i = a[first];
int j = a[last];
while (i <= j)
{
if (pivot > a[i])
{i++;}
if (pivot < a[j])
{j--;}
if (i <= j)
{swap(a[i],a[j]);}
}
swap(pivot, a[j]);
return i;
}
int main()
{
int x; // number of elements
int nums[10];
cout << "How many elements would you like to enter into the array? (must
be less than 10): ";
cin >> x;
cout << "Enter the elements one per line" << endl;
for (int i = 0; i < x; i++)
{ cin >> nums[i]; }
int pivot_index = partition(nums, 0, x-1);
cout << "The array was partitioned" << endl;
// display up to the pivot without endl
for (int i = 0; i < pivot_index; i++)
cout << nums[i] << " ";
// display the pivot
cout << "| " << nums[pivot_index] << " | " ;
// display from the pivot without endl
for (int i = pivot_index+1; i < x; i++)
cout << nums[i] << " ";
cout << endl;
}

Adding an index and specified number to an array in c++

I am making a program that removes a number from the index that the user provides from the array, displays the new array, then asks the user to insert a number at whatever index they choose. The first part of this program works fine when it comes to removing an index, but I am having trouble with adding an index and number. For example, if the NEW array after the user deletes the number from index 5 is: 12 34 45 2 8 16 180 182 22, which is correct if you remember that arrays start at 0, then they request for example index 5 to be added again with the number 78, it gets messed up. It displays 12 34 45 2 78 8 16 180 182 22 (and then it also outputs the number -858993460 for some reason?) SO the problem basically is that it adds the new index and number one index BEFORE it is supposed to. Im sorry if this sounds so confusing but I have been stuck on it for hours. Thank you!
//This program demos basic arrays
#include <iostream>
using namespace std;
const int CAP = 10;
int main()
{
int size;
int list[CAP] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
size = 10;
int i, delIndex, addIndex, newInt = 0;
cout << "Your list is: " << endl;
for (i = 0; i < CAP; i++)
{
cout << list[i] << endl;
}
//Deleting an index
cout << "\nPlease enter index to delete from: ";
cin >> delIndex;
for (i = delIndex; i <= 10; i++)
{
list[i] = list[i + 1];
}
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;
}
//Adding an index
cout << "\nNow, please enter the index position to add to: " << endl;
cin >> addIndex;
cout << "\nEnter the number to add to the index: " << endl;
cin >> newInt;
for (i = size - 1; i >= addIndex - 1; i--)
{
list[i + 1] = list[i];
}
list[addIndex - 1] = newInt;
size++;
cout << "The number has been added at the specified index position." <<
endl;
cout << "The new array is: " << endl;
for (i = 0; i < size; i++)
{
cout << list[i] << endl;
}
return 0;
}
The problem is with handling size variable in your code.
Following is corrected code. See it working here:
#include <iostream>
using namespace std;
const int CAP = 10;
int main()
{
int size;
int list[CAP] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
size = CAP;
int i, delIndex, addIndex, newInt = 0;
cout << "Your list is: " << endl;
for (i = 0; i < size; i++)
{
cout << list[i] << endl;
}
//Deleting an index
cout << "\nPlease enter index to delete from: ";
cin >> delIndex;
for (i = delIndex; i < size; i++)
{
list[i] = list[i + 1];
}
size--;
cout << "The index position you specified has been deleted." << endl;
cout << "The new array is: " << endl;
for (i = 0; i < size; i++)
{
cout << list[i] << endl;
}
//Adding an index
cout << "\nNow, please enter the index position to add to: " << endl;
cin >> addIndex;
cout << "\nEnter the number to add to the index: " << endl;
cin >> newInt;
for (i = size - 1; i >= addIndex; i--)
{
list[i + 1] = list[i];
}
list[addIndex] = newInt;
size++;
cout << "The number has been added at the specified index position." <<endl;
cout << "The new array is: " << endl;
for (i = 0; i < size; i++)
{
cout << list[i] << endl;
}
return 0;
}
Note: Since we are talking about index and not position in the array, so it is treated as 0 based and element is added at index addIndex, not at addIndex-1.
There are some loopholes in your program, that you can improve.
You are declaring a constant (CAP), but the array size is changing, so point doing that.
You are printing the array multiple times, its better to use a function, and call it every time, when you need to print the entire array.
You are using literals like 10, in some sections of the program. It is advisable to use the same variable like size or CAP instead of 10 to improve readability.
You can even put insert & delete in functions so that they can be called multiple times.
This is a sample working code, you can take the idea of that. I haven't implemented Step 4, I hope you can do that easily,
LIVE CODE
Working Code
//This program demos basic arrays
#include <iostream>
using namespace std;
int CAP = 10;
void printArr(int list[]){
for (int i = 0; i < CAP; i++)
cout << list[i] << " ";
cout<<endl;
}
int main()
{
int list[CAP] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
int i, delIndex, addIndex, newInt = 0;
cout << "Your list is: " << endl;
printArr(list);
//Deleting an index
cout << "\nPlease enter index(0 indexed based) to delete from: ";
cin >> delIndex;
for (i = delIndex; i < CAP - 1; i++)
list[i] = list[i + 1];
CAP--;
cout << "The index position you specified has been deleted." << endl;
cout << "The new array is: " << endl;
printArr(list);
//Adding an index
cout << "\nNow, please enter the index position(0 indexed based) to add to: " << endl;
cin >> addIndex;
cout << "\nEnter the number to add to the index: " << endl;
cin >> newInt;
for (i = CAP; i > addIndex; i--)
list[i] = list[i-1];
list[addIndex] = newInt;
CAP++;
cout << "The number has been added at the specified index position." << endl;
cout << "The new array is: " << endl;
printArr(list);
return 0;
}

How to count how many times each number has been encountered?

I am trying to write a program to count each number the program has encountered. by putting M as an input for the number of the array elements and Max is for the maximum amount of number like you shouldn't exceed this number when writing an input in the M[i]. for some reason the program works just fine when I enter a small input like
Data input:
10 3
1 2 3 2 3 1 1 1 1 3
Answer:
5 2 3
But when I put a big input like 364 for array elements and 15 for example for max. the output doesn't work as expected and I can't find a reason for that!
#include "stdafx.h"
#include <iostream>
#include<fstream>
#include<string>
#include <stdio.h>
#include<conio.h>
using namespace std;
int ArrayValue;
int Max;
int M[1000];
int checker[1000];
int element_cntr = 0;
int cntr = 0;
int n = 0;
void main()
{
cout << "Enter the lenght of the Elements, followed by the maximum number: " << endl;
cin >> ArrayValue>> Max;
for (int i = 0; i < ArrayValue; i++)
{
cin >> M[i];
checker[i]= M[i] ;
element_cntr++;
if (M[i] > Max)
{
cout << "the element number " << element_cntr << " is bigger than " << Max << endl;
}
}
for (int i = 0; i < Max; i++)
{
cntr = 0;
for (int j = 0; j < ArrayValue; j++)
{
if (M[n] == checker[j])
{
cntr+=1;
}
}
if (cntr != 0)
{
cout << cntr << " ";
}
n++;
}
}
You have general algorithm problem and several code issues which make code hardly maintainable, non-readable and confusing. That's why you don't understand why it is not working.
Let's review it step by step.
The actual reason of incorrect output is that you only iterate through the first Max items of array when you need to iterate through the first Max integers. For example, let we have the input:
7 3
1 1 1 1 1 2 3
While the correct answer is: 5 1 1, your program will output 5 5 5, because in output loop it will iterate through the first three items and make output for them:
for (int i = 0; i < Max; i++)
for (int j = 0; j < ArrayValue; j++)
if (M[n] == checker[j]) // M[0] is 1, M[1] is 1 and M[2] is 1
It will output answers for first three items of initial array. In your example, it worked fine because the first three items were 1 2 3.
In order to make it work, you need to change your condition to
if (n == checker[j]) // oh, why do you need variable "n"? you have an "i" loop!
{
cntr += 1;
}
It will work, but both your code and algorithm are absolutely incorrect...
Not that proper solution
You have an unnecessary variable element_cntr - loop variable i will provide the same values. You are duplicating it's value.
Also, in your output loop you create a variable n while you have a loop variable i which does the same. You can safely remove variable n and replace if (M[n] == checker[j]) to if (M[i] == checker[j]).
Moreover, your checker array is a full copy if variable M. Why do you like to duplicate all the values? :)
Your code should look, at least, like this:
using namespace std;
int ArrayValue;
int Max;
int M[1000];
int cntr = 0;
int main()
{
cout << "Enter the lenght of the Elements, followed by the maximum number: " << endl;
cin >> ArrayValue >> Max;
for (int i = 0; i < ArrayValue; i++)
{
cin >> M[i];
if (M[i] > Max)
{
cout << "the element number " << i << " is bigger than " << Max << endl;
}
}
for (int i = 0; i < Max; i++)
{
cntr = 0;
for (int j = 0; j < ArrayValue; j++)
{
if (i == M[j])
{
cntr ++;
}
}
if (cntr != 0)
{
cout << cntr << " ";
}
}
return 0;
}
Proper solution
Why do you need a nested loop at all? You take O(n*m) operations to count the occurences of items. It can be easily counted with O(n) operations.
Just count them while reading:
using namespace std;
int arraySize;
int maxValue;
int counts[1000];
int main()
{
cout << "Enter the lenght of the Elements, followed by the maximum number: " << endl;
cin >> arraySize >> maxValue;
int lastReadValue;
for (int i = 0; i < arraySize; i++)
{
cin >> lastReadValue;
if (lastReadValue > maxValue)
cout << "Number " << i << " is bigger than maxValue! Skipping it..." << endl;
else
counts[lastReadValue]++; // read and increase the occurence count
}
for (int i = 0; i <= maxValue; i++)
{
if (counts[i] > 0)
cout << i << " occurences: " << counts[i] << endl; // output existent numbers
}
return 0;
}

Getting the Average,Min, and Max of numbers in 2D array

I have a problem with getting the min,max, and average of an elements of 2D array.
I have a 2D array which contains Students and Grades.
I am generating the grades with rand. For example When I enter 2,2 it prints me out
Courses : 01 02 Average Min Max
ID
01 8 50 29
02 74 59 29
, My average function takes the first ones average and doesnt take the others average.
Here is my code ;
int A[30][30];
int findAverage(int noOfStudents ,int noOfGrades ){
float sum,average;
for (int i = 0 ; i < noOfGrades ; i++) {
for (int j = 0; j<noOfStudents; j++) {
sum += A[i][j];
}
average = sum / noOfGrades;
// cout << " " << format(average);
sum = 0;
return format(average);
}
and here how I use it
int main() {
int noOfCourses , noOfStudents;
cin >> noOfCourses >> noOfStudents;
cout << "Courses : " ;
for (int i = 0; i < noOfCourses; i++) {
if (i+1 >= 10) {
cout << i+1 << " ";
}else{
cout <<"0" << i+1 << " ";
}
}
cout << "Average Min Max";
for(int i=0; i<noOfStudents; i++) { //This loops on the rows.
for(int j=0; j<noOfCourses; j++) { //This loops on the columns
A[i][j] = genGrade();
}
}
cout << "\n ID " << endl;
for(int i=0; i<noOfStudents; i++) { //This loops on the rows.
if (i+1 >= 10) {
cout <<" " << i+1 << " ";
}else{
cout <<" 0" << i+1 << " ";
}
//cout <<" 0" << i+1 << " ";
for(int j=0; j<noOfCourses; j++) { //This loops on the columns
if (A[i][j] >= 10 && A[i][j] <=99) {
cout <<" " << A[i][j] << " ";
}
if(A[i][j] < 10) {
cout <<" " << A[i][j] << " ";
}
if (A[i][j] == 100) {
cout << A[i][j] << " ";
}
}
cout <<" "<<findAverage(noOfStudents,noOfCourses);
cout << endl;
}
}
What am I doing wrong ? Also How could I get the min,max of the per array?
I would strong recommend using containers for this task. For example you could do the following
typedef std::vector<float> grades;
std::vector<grades> student_grades;
//populate
for(const grades& gr : student_grades) {
float min, max, avg;
std::tie(min, max)=std::minmax(gr.begin(), gr.end());
avg=std::accumulate(gr.begin(), gr.end(), 0.0) / gr.size());
std::cout << "Min" << min << " Max: " << max << " Avg: " << avg << std::endl;
}
http://en.cppreference.com/w/cpp/algorithm/minmax
http://en.cppreference.com/w/cpp/algorithm/accumulate
http://en.cppreference.com/w/cpp/utility/tuple/tie
For starters, you are returning from inside your loop:
for (int i = 0 ; i < noOfGrades ; i++) {
for (int j = 0; j<noOfStudents; j++) {
...
}
...
return ...;
}
Can you see how the outer loop will only ever execute once?
The problem is that in your findAverage function you have a return statement within the loop that is looping through the rows. If you want a very simple fix add another parameter to the findAverage function that indicates which row to calculate the average for.
int findAverage(int course ,int noOfGrades ){
float sum,average;
for (int j = 0; j<noOfStudents; j++) {
sum += A[course][j];
}
average = sum / noOfGrades;
return format(average);
}
and call it like this
cout <<" "<<findAverage(i,noOfCourses);