finding elements in an array using a function c++ - c++

I am new to C++ and have just started learning functions. I have made a program to search an element in a 1-d array using a function search. But there is a logical error I can't comprehend! Is it because of the way the function is declared ?
int pos;
using namespace std;
int search(int *a, int size, int num);
int search(int *a, int size, int num)
{
int i;
for(i=0; i<size; i++)
{
if(a[i]==num)
{
pos=i; return 1;
}
else
return 0;
}
}
int main()
{
int a[5], size, num, i;
system("cls");
cout<<"Enter size(<5) \n";
cin>>size;
cout<<"Enter the elements of the array \n";
for(i=0; i<size; i++)
cin>>a[i];
cout<<"Enter the number to be searched \n";
cin>>num;
int b = search( a, size, num);
if(b==0)
{
cout<<"Element not found!"; exit(0);
}
else
cout<<"Element found at position "<<(pos+1);
system("pause");
return 0;
}
Output:
Enter size(<5)
4
Enter the elements of the array
4
3
2
1
Enter element to be searched
4
Element not found!

Your function always returns in the first loop iteration. If the first element is not the one to be searched, 0 is returned immediately. The loop never enters the second iteration.

you must return not found if you dont found any thing, with this code, you will always return zero, if the first element is not what you are searching for. something like this :
int search(int *a, int size, int num)
{
int i;
for(i=0; i<size; i++)
{
if(a[i]==num)
{
pos=i; return 1;
}
}
return 0;
}

It is in your logic
int search(int *a, int size, int num)
{
int i;
for(i=0; i<size; i++)
{
if(a[i]==num)
{
pos=i; return 1;
}
else
return 0;
}
}
Let's step through that. I'm going to give it [1, 2, 3, 4], 4, and 3.
i => 0
a[0] => 1
a[0] == 3 => false
return false
So, you check the first one, and if that doesn't work, it will immediately fail.
So try this:
int search(int *a, int size, int num)
{
for(int i = 0; i < size; ++i)
{
if(a[i]==num)
{
pos = i;
return 1;
}
}
return 0;
}
However, the better way would be to do something like this, and get rid of your global variable
int search(int *a, int size, int num)
{
for(int i = 0; i < size; ++i)
{
if(a[i]==num)
{
return i;
}
}
return -1;
}
Then if you get something != -1 you have found it.

Your search function is not doing what you think it is doing: it will return 0 as soon as a[i]!=num, thus not considering the rest of the elements of the array.
You'd better use someting like this, with a (non-global) variable returned:
#include <cstdlib>
// returns -1 if not found, else the found index
int search(int *a, int size, int num)
{
int pos = -1;
for(int i=0; i<size; i++)
{
if(a[i]==num)
{
pos = i;
break;
}
}
return pos;
}
// ... main() and parsing stuff goes here
if( (b = search( a, size, num)) == -1)
{
std::cerr<<"Element not found!";
return EXIT_FAILURE;
}

The problem is with your else statement. If the the element is not found straight away, it will automatically return 0. Furthermore, you use the integer 0 to indicate that the element is not found, but what if the element is found at position 0 (i.e it is the first element of the array)? Then you will still say that the element is not found, even though it clearly it exists in the array. Here is how I would do it.
bool search(int *a, int size, int num)
{
for (int i = 0; i < size; ++i)
{
if (a[i] == num)
{
cout << "Element found at position " << i << " of the array!" << endl;
return true;
}
}
cout << "Element not found!" << endl;
return false;
}
I hope you have learned about booleans (i.e true or false.) Since your function's main purpose is to search, it should return whether the element is found (true) or whether it is not found (false). Therefore, we loop through the array, and if we find it, we output the position of the element, and return true. Otherwise, if we exit the loop, this means the element has not been found, so we output that and return false. This gets rid of the global variable usage and the previous problems that I have mentioned.

Related

checking specific condition in array

have a little problem in exercise in arrays and functions.
I need to write a code that checks every cell in the array for two conditions. The first is that every cell value left to the index exist to the right of the index, and the second is the opposite, every cell value on the right exist to the left.
If those two conditions exist then the cell is "good" and I will add it to the counter of the good cells.
for example: input is 38 79 38 38 17 79 38
For this input I expect that cell #4 will answer the conditions and it will print 1. It will answer the conditions because 38 and 79 exist on the left of #4 and the opposite. Currently for this input it's printing 0 for some reason.
I will gladly use some hints on where the problem is because currently I'm stuck.
Thank you!
// include section
#include <iostream>
#include <cstdlib>
// using section
using std::cin;
using std::cout;
using std::endl;
// constant section
const int N = 7;
// functions section
void input(int arr[]);
bool check_cell(int array[], int cell_index);
bool check_cond_left_to_right(int array[], int cell_index);
bool check_cond_left_to_right(int array[], int cell_index);
bool check_cond_right_to_left(int array[], int cell_index);
bool search_cell_on_the_right(int array[], int cell_value, int original_cell_index);
bool search_cell_on_the_left(int array[], int cell_value, int original_cell_index);
int main() {
int array[N],
cell_counter = 0;
input(array);
for (int index = 1; index < N - 1; index++) {
if (check_cell(array, index)) {
cell_counter++;
}
}
cout << cell_counter;
}
void input(int arr[]) { // input function
for (int index = 0; index < N; index++)
cin >> arr[index];
}
bool check_cell(int array[], int cell_index) {
if (check_cond_left_to_right(array, cell_index) &&
check_cond_right_to_left(array, cell_index))
return true;
else
return false;
}
bool check_cond_left_to_right(int array[], int cell_index) { // check the cells on the left and send them to the right
for (int i = 0; i < cell_index; i++) {
if (search_cell_on_the_right (array, array[i], cell_index) == false)
return false;
}
return true;
}
bool check_cond_right_to_left(int array[], int cell_index) {
for (int i = N; i > cell_index; i--) {
if (search_cell_on_the_left(array, array[i], cell_index) == false)
return false;
else
continue;
}
return true;
}
bool search_cell_on_the_right(int array[], int cell_value, int original_cell_index) { // getting cells on the left and checks if they exist on the right
for (int i = original_cell_index + 1; i < N; i++) {
if (cell_value == array[i])
return true;
}
return false;
}
bool search_cell_on_the_left(int array[], int cell_value, int original_cell_index) {
for (int i = 0; i < original_cell_index; i++) {
if (cell_value == array[i])
return true;
}
return false;
}
I have tried to identified where the problem is but couldn't find it. Will gladly use some help.
You have an Index out of bounds in one of your functions. If you want to iterate through an array backwards, you have to start at N-1, because N isn't a valid index.
Below is a corrected code
bool check_cond_right_to_left(int array[], int cell_index) {
for (int i = N - 1; i > cell_index; i--) {
if (search_cell_on_the_left(array, array[i], cell_index) == false)
return false;
else
continue;
}
return true;
}

find the element that appears once in the array when others appear twice

I wrote the code with o(n^2) complexity.I could not find the error.My idea was to first sort the array and then starting from the first element if the second next is equal increment i by 2 and when the if condition is not fulfilled the element is found Can someone please help me this.
Thanks in advance
#include<iostream>
using namespace std;
int main()
{
int arr[100];
int n,i,j,temp;
cin>>n;
for(i=0;i<n;i++)
{
cin>>arr[i];
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(arr[i]>arr[j])
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
i=0;
for(j=i+1;j<n;j++)
{
if(arr[i] == arr[j])
{
i=i+2;
}
}
cout<<arr[i];
return 0;
}
To find a non-repetitive element in an array the first thing that comes to mind is that if we first sort the array and then try to manipulate it. The sorting process is easy and as follows:
int arr[] = {/*Some array*/};
int arrSize = sizeof(arr)/sizeof(int);
//Lets sort the array
for(int i=0;i<arrSize;i++)
{
for(int j=i;j<arrSize;j++)
{
if(arr[i]>arr[j])
{
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
After sorting the array we may see different scenarios like:
int arr1[] = {1,1,2,2,3};
int arr2[] = {1,2,2,3,3};
int arr3[] = {1,1,2,3,3};
We have to design an algorithm such that it can differentiate and easily manipulate the three scenarios. Let n be our number. The first scenario is to check if the last isn't the same as the previous one by:
if(arr[arrSize-1] != arr[arrSize-2]) //The last is not the same as the previous
{
n=arr[arrSize-1];
}
The second one is similar to the first:
if(arr[0] != arr[1]) // The first element is not the same as the second
{
n = arr[0];
}
The third one is easy too, we just have to check if two neighbors are never equal to the middle number, this is as follows:
for(int i=1;i<arrSize-1;i++)
{
if(arr[i-1] != arr[i] && arr[i] != arr[i+1])
{
n=arr[i];
break;
}
}
And so the full code would become:
#include <iostream>
using namespace std;
int main()
{
int arr[] = {1,2,3,4,2,3,1};
int arrSize = sizeof(arr)/sizeof(int);
//Lets sort the array
for(int i=0;i<arrSize;i++)
{
for(int j=i;j<arrSize;j++)
{
if(arr[i]>arr[j])
{
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
int n;
if(arr[0] != arr[1]) // The first element is not the same as the second
{
n = arr[0];
}
else if(arr[arrSize-1] != arr[arrSize-2]) //The last is not the same as the previous
{
n=arr[arrSize-1];
}
else //Lets search for a number such that its not the same as the numbers on the left and on the right
{
for(int i=1;i<arrSize-1;i++)
{
if(arr[i-1] != arr[i] && arr[i] != arr[i+1])
{
n=arr[i];
break;
}
}
}
cout << n;
}
The Second Way (Better one).
Here's another way we could solve this problem. Suppose that I have a number n=3, if i XORed it with 3 i will get 0, so if we have an array lets say arr[] = {1,2,1}, I first assign n=0, then XOR it with the firs element (1), next I XOR n with the second element and then with the third element. What will happen? The third XOR will cancel the effect of the first thus n will equal to 1. Sample Code:
#include <iostream>
using namespace std;
int main()
{
int arr[] = {1,2,3,4,2,3,1};
int arrSize = sizeof(arr)/sizeof(int);
int n=0;
for(int i=0;i<arrSize;i++)
{
n^=arr[i];
}
cout << n;
}
This code is O(n).
Use XOR. XOR of all array elements gives us the number with a single occurrence.
#include <bits/stdc++.h>
using namespace std;
int singleoccurence(int arr[], int n)
{
int res = arr[0];
for (int i = 1; i < n; i++)
{
res = res ^ arr[i];
}
return res;
}
int main()
{
int arr[] = {7, 3, 5, 4, 5, 3, 4};
int n = sizeof(arr) / sizeof(arr[0]);
int val = singleoccurence(arr, n);
cout << "ELEMENT OCCURING ONLY ONCE IS :" << val;
}
Solution in C#
public static int lonelyinteger(List<int> a)
{
int lonely = 0;
foreach(var item in a)
{
List<int> listTemp = a.Where(x => x == item).ToList();
if(listTemp.Count == 1)
lonely = listTemp.FirstOrDefault();
}
return lonely;
}

How to properly compare two arrays stored in memory?

I'm trying to build a function which is supposed to compare to arrays, one generated by itself(the lottery digits) and the second array is submitted and stored by user input.
This is supposed to count the matching digits between the lottery and the ones submitted by the user input. If they match, a message should be displayed telling the user that he has won the big prize ,etc.
This is supposed to be the function that compares both arrays; I assume is right(to make it more clear: The program is to compare the corresponding elements in the two arrays and keep a count of the digits that match)?
int compare(int user[], int lottery[]){
int matches = 0;
for (int i = 0; i < SIZE; i++) {
if (user[i] == lottery[i]) {
matches++;
}
}
return matches;
}
the problem comes when it returns to the main function which is supposed to tell if the user has won or not. Here it is the small block of code that I created in the main function:
int matches = compare(user, lottery);
if (matches) {
cout << "Congratulations, you have won the big prize" << endl;
}
else {
cout << "Please, try again" << endl;
}
The expected should be to display a message if user won and to count the user digits that match with the lottery numbers.
The actual output is the digits entered by the user. Hopefully I could explain myself.
Here is the complete code, if you feel like helping and need a bit of more information.
http://cpp.sh/8ivyc
In your case it is enough to have only one time the same value at the same index to match, but all the values must be equals
First possibility with minimal changes from your code :
int compare(int user[], int lottery[]){
int matches = 0;
for (int i = 0; i < SIZE; i++) {
if (user[i] == lottery[i]) {
matches++;
}
}
return (matches == SIZE); /* <<< modified */
}
But it is useless to continue to compare after a different value was found, so can be :
int compare(int user[], int lottery[]){
for (int i = 0; i < SIZE; i++) {
if (user[i] != lottery[i]) {
return 0;
}
}
return 1;
}
and because you are in C++ :
bool compare(int user[], int lottery[]){
for (int i = 0; i < SIZE; i++) {
if (user[i] != lottery[i]) {
return false;
}
}
return true;
}
(also changing the call to use a bool rather than an int to be more clear of course)
The simplest way is to just use std::array. If you use std::array, you can just use == to compare them!
The functions populate and show_values can be written like this:
void populate(std::array<int, SIZE>& nums) {
srand(time(0));
for (int& value : nums) {
value = rand() % 9;
}
}
void showValues(std::array<int, SIZE>& nums) {
for (int i = 0; i < SIZE; i++) {
cout << setw(3) << nums[i];
}
cout << endl;
}
And compare is especially simple:
bool compare(std::array<int, Size>& nums1, std::array<int, Size>& nums2) {
return nums1 == nums2;
}
Check for inequality rather than equality.
You'll return out of the function as soon as an user element not equal to lottery element
int compare(int user[], int lottery[]){
for (size_t i = 0; i < SIZE; i++) {
if (user[i] != lottery[i]) {
return 0;
}
}
return 1;
}

Can't get my code to correctly sort user input array of numbers (using recursion)

For the life of me I can't get this code to sort correctly. This is a recursion practice, by sorting five numbers that the user inputs, then I display those five numbers from least to greatest. It does most of it correctly, but occasionally it will mess the first or last number up, and switch it with another number in the array. I know the problem is inside the function where is does the swapping, in that second 'if' statement, but I can't figure out how to fix it, I would really appreciate some direction as to how to proceed. Here is my code:
#include <iostream>
#include <array>
using namespace std;
void mySort(int nums[], int first, int size);
int main()
{
int fiveNumbers[5];
int firstNum = 0;
int size = 5;
cout << "Please enter five numbers, pressing enter after each.\n\n";
for (int i = 0; i < 5; i++)
{
cout << "Enter a number: ";
cin >> fiveNumbers[i];
cout << endl;
}
mySort(fiveNumbers, firstNum, size);
for (int i = 0; i < size; i++)
{
cout << fiveNumbers[i] << endl;
}
system("PAUSE");
return 0;
}
void mySort(int nums[], int first, int size)
{
if (size == 0)
{
return;
}
for (int i = 0; i < 5; i++)
{
if (first < nums[i])
{
swap(nums[first], nums[i]);
}
}
first++;
size--;
return mySort(nums, first, size);
}
Changed my function to reflect the value of the array AT point 'first', instead of the variable 'first' itself. So far it has worked every time!
void mySort(int nums[], int first, int size)
{
if (size == 0)
{
return;
}
for (int i = 0; i < 5; i++)
{
if (nums[first] < nums[i])
{
swap(nums[first], nums[i]);
}
}
first++;
size--;
return mySort(nums, first, size);
}
EDIT: Got your code working but forgot the most important part, namely:
You're comparing the index to the array value, use:
if (nums[first] < nums[i])
Instead of:
if (first < nums[i])
Also, you always start swapping from the beginning when you should be starting one past first.
Instead of:
for (int i = 0; i < 5; i++)
You want:
for (int i = first + 1; i < 5; i++)

Heap Sort in C++

Okay, so after struggling with trying to debug this, I have finally given up. I'm a beginner in C++ & Data Structures and I'm trying to implement Heap Sort in C++. The code that follows gives correct output on positive integers, but seems to fail when I try to enter a few negative integers.
Please point out ANY errors/discrepancies in the following code. Also, any other suggestions/criticism pertaining to the subject will be gladly appreciated.
//Heap Sort
#include <iostream.h>
#include <conio.h>
int a[50],n,hs;
void swap(int &x,int &y)
{
int temp=x;
x=y;
y=temp;
}
void heapify(int x)
{
int left=(2*x);
int right=(2*x)+1;
int large;
if((left<=hs)&&(a[left]>a[x]))
{
large=left;
}
else
{
large=x;
}
if((right<=hs)&&(a[right]>a[large]))
{
large=right;
}
if(x!=large)
{
swap(a[x],a[large]);
heapify(large);
}
}
void BuildMaxHeap()
{
for(int i=n/2;i>0;i--)
{
heapify(i);
}
}
void HeapSort()
{
BuildMaxHeap();
hs=n;
for(int i=hs;i>1;i--)
{
swap(a[1],a[i]);
hs--;
heapify(1);
}
}
void main()
{
int i;
clrscr();
cout<<"Enter length:\t";
cin>>n;
cout<<endl<<"Enter elements:\n";
for(i=1;i<=n;i++) //Read Array
{
cin>>a[i];
}
HeapSort();
cout<<endl<<"Sorted elements:\n";
for(i=1;i<=n;i++) //Print Sorted Array
{
cout<<a[i];
if(i!=n)
{
cout<<"\t";
}
}
getch();
}
I've been reading up on Heap Sort but I'm not able to grasp most of the concept, and without that I'm not quite able to fix the logical error(s) above.
You set hs after calling BuildMaxHeap. Switch those two lines.
hs=n;
BuildMaxHeap();
When I implemented my own heapsort, I had to be extra careful about the indices; if you index from 0, children are 2x+1 and 2x+2, when you index from 1, children are 2x and 2x+1. There were a lot of silent problems because of that. Also, every operation needs a single well-written siftDown function, that is vital.
Open up Wikipedia at the Heapsort and Binary heap articles and try to rewrite it more cleanly, following terminology and notation where possible. Here is my implementation as well, perhaps it can help.
Hmmm now that I checked your code better, are you sure your siftDown/heapify function restricts sifting to the current size of the heap?
Edit: Found the problem! You do not initialize hs to n before calling BuildMaxHeap().
I suspect it's because you're 1-basing the array. There's probably a case where you're accidentally 0-basing it but I can't spot it in the code offhand.
Here's an example if it helps.
#include <iostream>
#include <vector>
using namespace std;
void max_heapify(std::vector<int>& arr, int index, int N) {
// get the left and right index
int left_index = 2*index + 1;
int right_index = 2*index + 2;
int largest = 0;
if (left_index < N && arr[left_index] > arr[index]) {
// the value at the left_index is larger than the
// value at the index of the array
largest = left_index;
} else {
largest = index;
}
if (right_index < N && arr[right_index] > arr[largest]) {
// the value at the right_index is larger than the
// value at the index of the array
largest = right_index;
}
// check if largest is still the index, if not swap
if (index != largest) {
// swap the value at index with value at largest
int temp = arr[largest];
arr[largest] = arr[index];
arr[index] = temp;
// once swap is done, do max_heapify on the index
max_heapify(arr, largest, N);
}
}
void build_max_heap(std::vector<int>& arr, int N) {
// select all the non-leaf except the root and max_heapify them
for (int i = N/2 - 1; i >= 0; --i) {
max_heapify(arr, i, N);
}
}
void heap_sort(std::vector<int>& arr) {
int N = arr.size();
int heap_size = N;
// build the max heap
build_max_heap(arr, N);
// once max heap is built,
// to sort swap the value at root and last index
for (int i = N - 1; i > 0; --i) {
// swap the elements
int root = arr[0];
arr[0] = arr[i];
arr[i] = root;
// remove the last node
--heap_size;
// perform max_heapify on updated heap with the index of the root
max_heapify(arr, 0, heap_size);
}
}
int main() {
std::vector<int> data = {5,1,8,3,4,9,10};
// create max heap from the array
heap_sort(data);
for (int i : data) {
cout << i << " ";
}
return 0;
}
# include <iostream> //Desouky//
using namespace std;
void reheapify(int *arr, int n, int i)
{
int parent = i; // initilaize largest as parent/root
int child1 = 2 * i + 1; // to get first chid
int child2 = 2 * i + 2; // to get second child
if (child1 < n && arr[child1] > arr[parent]) // if child2 > parent
{
parent = child1;
}
//if child > the parent
if (child2 < n && arr[child2] > arr[parent])
{
parent = child2;
}
// if the largest not the parent
if (parent != i)
{
swap(arr[i], arr[parent]);
// Recursively heapify the affected sub-tree
reheapify(arr, n, parent);
}
}
void heapsort(int *arr, int n)
{
// build a heap
for (int i = n - 1; i >= 0; i--)
{
reheapify(arr, n, i);
}
// One by one extract an element from heap
for (int i = n - 1; i >= 0; i--)
{
// Move current root to end
swap(arr[0], arr[i]);
// call max heapify on the reduced heap
reheapify(arr, i, 0);
}
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
heapsort(arr, n);
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
}