Question is given that we have to find the duplicate number in an array. Can someone please tell me why this code is not working?
int main()
{
int arr[] = {12,13,14,15,15,10};
int size = sizeof(arr)/sizeof(int);
int n;
for (int i = 0; i < size; i++)
{
for (int j = 1; j < size; j++)
{
if (arr[i] == arr[j])
{
n = arr[i];
break;
}
}
}
cout<<n;
return 0;
}
Please tell me the problem.
You need to let j start from i+1, or it may match itself as the duplicate number.
int main()
{
int arr[] = {12, 13, 14, 15, 15, 10};
int size = sizeof(arr) / sizeof(int);
int n;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (arr[i] == arr[j])
{
n = arr[i];
break;
}
}
}
cout << n;
return 0;
}
Your outer for loop doesn't break when duplicate is found. You can use another variable and set it to true if duplicate element is found.
int main()
{
int arr[] = {12, 13, 14, 15, 15, 10};
int size = sizeof(arr)/sizeof(int);
int n = 0;
bool duplicate_found = false;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (arr[i] == arr[j])
{
n = arr[i];
duplicate_found = true;
}
}
if (duplicate_found) break;
}
cout << n;
return 0;
}
Don't use goto statement here. It's a bad practice to use goto. And as #schtonn suggested start your inner loop from i+1.
break takes you out of the inner loop only. If you want to break out of both loops, you need goto statement.
Related
This is a code I have taken from GeeksForGeeks. I am trying to understand the code.
In the line in the function deleteEle which says if(i==n) return n, how could i become n if it is running for < n times in the for loop just above it?
#include <iostream >
#include <cmath>
using namespace std;
int deleteEle(int arr[], int n, int x)
{
int i = 0;
for(i = 0; i < n; i++)
{
if(arr[i] == x)
break;
}
cout << i << endl;
if(i == n)
cout<<i;
return n;
for(int j = i; j < n - 1; j++)
{
arr[j] = arr[j + 1];
}
return n-1;
}
int main() {
int arr[] = {3, 8, 12, 5, 6}, x = 13, n = 5;
cout<<"Before Deletion"<<endl;
for(int i=0; i < n; i++)
{
cout<<arr[I]<<" ";
}
cout<<endl;
n = deleteEle(arr, n, x);
cout<<"After Deletion"<<endl;
for(int i=0; i < n; i++)
{
cout<<arr[I]<<" ";
}
}
how could I become n if it is running for < n times in the for loop just above it?
Because it may happen that the if condition arr[i] == x inside the preceding for loop is never satisfied which in turn means that the break is never executed in which case the last iteration will increment i so that i becomes equal to n.
After the last iteration of this loop (if arr[i] != x for all i in range [0, n]):
for(i = 0; i < n; i++)
{
if(arr[i] == x)
break;
}
i will equal n if break is not executed.
so I had the following sorting example (Count Sort), It's kind of weird actually, but it works, so it's fine :
#include<iostream>
using namespace std;
int getMx(int* arr,int n)
{
int max = arr[0];
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
void CountSort(int* arr, int n) {
int* output = new int[n];
int max = getMx(arr, n);
int* count = new int[max + 1];
for(int i = 0; i < max + 1; i++) {
count[i] = 0;
}
for(int i = 0; i < n; i++) {
count[arr[i]]++;
}
for(int i = 1; i <= max; i++) {
count[i] += count[i - 1];
}
for(int i = n - 1; i >= 0; i--) {
output[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
for(int i = 0; i < n; i++) {
arr[i] = output[i];
}
delete[] output;
delete[] count;
}
int main () {
int arr[] = { 100, 5, 2, 0, 125 };
int n = sizeof(arr) / sizeof(arr[0]);
CountSort(arr, n);
for (int i = 0; i < n; i++) {
cout << arr[i] << endl;
}
return 0;
}
So the main idea is just to get rid of the part when I sum the numbers stored in each index on Count[i]. And just get the output after the second cycle.
Example
int arr = [3, 2, 5, 4, 1, 0]
int count=[1,1,1,1,1,1]
and from there I should get
int output= [0, 1, 2, 3, 4, 5]
So I couldn't figue this out ((
You are probably thinking of something like this:
void CountSort(int* arr, int n) {
int max = getMx(arr, n);
int* count = new int[max + 1]{};
for(int i = 0; i < n; i++) {
count[arr[i]]++;
}
int k = 0;
for(int i = 0; i <= max; i++) {
while (count[i]--) {
arr[k++] = i;
}
}
delete[] count;
}
Demo
#include<bits/stdc++.h>
using namespace std;
int
main ()
{
int a[3] = { 3, 2, 1 }, i, j, t = 0, k = 0;
int m;
for (int i = 0; i < 2; i++)
{
m = a[i];
for (int j = i++; j < 3; j++)
{
if (m > a[j])
{
m = a[j];
k = j;
}
}
t = a[i];
a[i] = m;
a[k] = t;
}
for (int i = 0; i < 3; i++)
{
cout << a[i];
}
return 0;
}
You seem to want to implement an insertion sort algorithm by hand. For this task, you should consider using std::sort. I refactored your code such that it basically does the same thing as you wanted and included some tips to make the code more readable and easier to debug for you and others:
#include <algorithm> //only include necessary headers
#include <iostream>
//do not use "using namespace std"
int main ()
{
int a[3] = { 3, 2, 1 };
/*
Declare local variables at the first point they are used an as local as possible.
It is much easier to read, if a no longer necessary variables leaves scope.
*/
for (int i = 0; i < 2; i++) {
int min = a[i]; //use names that tell something about what you are doing
int bestIndex = i;
for (int j = i+1; j<3; j++) { //here was your major bug: i++ also increcments i
if (a[j] < min){
min = a[j];
bestIndex = j;
}
}
std::swap(a[i], a[bestIndex]);
//try to use standard algorithms as often as possible. They document your code, are optimized and easier to read.
}
for (int i = 0; i < 3; i++){
std::cout << a[i];
}
return 0;
}
Look at this:
for (int i = 0; i < 2; i++)
{
for (int j = i++; j < 3; j++)
{
}
}
On the first iteration of the outer loop:
i is 0.
Then the inner loop increments it to 1.
Then the outer loop increments it to 2.
Then the outer loop is done, after just one iteration.
You want i+1 in the inner loop, not i++.
#include<bits/stdc++.h>
using namespace std;
int main ()
{
int a[3] = { 3,2,1}, t = 0, k = 0;
int m=0;
bool flag_change =false;
for (int i = 0; i < 2; i++)
{
m = a[i];
for (int j = i+1; j < 3; j++)
{
if (m < a[j]) //changing sing (<>) sort by ascending/sort by descending order
{
m = a[j];
k = j;
flag_change = true;
}
}
if(flag_change)
{
t = a[i];
a[i] = m;
a[k] = t;
flag_change = false;
}
}
for (int i = 0; i < 3; i++)
{
cout << a[i];
}
return 0;
}
I'm done correct you code. Code is working.But it is not good implementation.
#include <iostream>
using namespace std;
void myfunction(int array[], int array1[], int array2[], int, int, int);
int main()
{
int array[5], array1[5], array2[5];
cout << "Enter array:";
for (int i = 0; i < 5; i++)
{
cin >> array[i];
cin >> array1[i];
}
myfunction(array, array1, array2, 5, 5, 5);
for (int i = 0; i < 5; i++)
cout << array2[i];
}
void myfunction(int array[], int array1[], int array2[], int n, int m, int o)
{
int k = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (array[i] == array1[j])
array2[k] = array1[j];
k++;
}
for (int i = k + 1; i < o; i++)
array2[i] = 0;
}
This is the logic that I thought of. But it is giving segmentation error which I don't know about. Also, I don't know where I am wrong. Please guide me
I believe you have one major issue here:
if(array[i]==array1[j])
array2[k]=array1[j];
k++;
The k++ part is executed each time but should be done once per array iteration only when a match is found. This is the part that is giving you the seg fault.
You can fix the whole nested for like so:
for (int i = 0; i < n; ++i, ++k)
{
const auto val = array[i];
if (std::any_of(array1, array1+n, [&val](int v){return v == val;}))
array2[k] = array[i];
else
array2[k] = 0;
}
Considering you don't use c++11 you can write an equivalent of the above:
for (int i = 0; i < n; ++i, ++k)
{
bool match = false;
for (int j = 0; j < m; ++j)
{
if (array[i] == array1[j])
{
match = true;
break;
}
}
if (match)
array2[k] = array[i];
else
array2[k] = 0;
}
This way you can also skip the following loop which also had an issue:
for (int i = k + 1; i < o; i++)
In result for input data like {1, 2, 3, 3, 5} and {1, 2, 4, 4, 5} you should get {1, 2, 0, 0, 5} which according to your comment is the expected output.
In general, I'd suggest you use std::vector or std::array since you work with a const sized array. This way you won't have to pass the array sizes as hardcoded values here and there. Additionally you'll be able to use the foreach-like loops and the code will get a bit cleaner.
You problem is in the below for loops:-
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(array[i]==array1[j])
array2[k]=array1[j];
k++;//this is being incremented each iteration
}
for(int i=k+1; i<o; i++)//What are you doing here I = 5 + 1 = 6
array2[i]=0;// what will happened here it will not execute
correct it like below:-
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(array[i]==array1[j])
{
array2[k]=array1[j];
k++;
}
}
I have tried to implement selection sort here. Please let me know what is wrong here and if there is anything wrong with the implementation of selection sort
#include <iostream>
using namespace std;
void selectionsort(int arr, int size)
{
int temp = 0;
int min = 0;
int i, j, k;
for (i = 0; i<size-1;i++)
{
min = arr[i];
for(j = i+1; j<size; j++)
{
if(arr[j] < min)
{
temp = min;
min = arr[j];
arr[j] = temp;
}
else if (arr[j] >= min)
{
continue;
}
}
}
for (k = 0; k <size; k++)
{
cout<<arr[k];
}
}
int main()
{
int arr1[] = {5, 3, 4, 2, 1};
int size = sizeof(arr1)/sizeof(arr1[0]);
selectionsort(arr1, size);
return 0;
}
Please let me know what is wrong here and if there is anything wrong with the implementation of selection sort.
Main problem in your code swapping does not work as intended in selection sort.
I would suggest to store index in min variable and swap values outside of second loop.
min = i;
for (j = i + 1; j<size; j++)
{
if (arr[j] < arr[min])
{
min = j;
}
}
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
And don't forget to change parameter type as it is commented already