What is the role of BOOL in the given code? - c++

Here's a c++ code to sort the data of various types using template function. Can someone elaborate what does BOOL do here?
I've read about bool data type. It basically assumes only two values TRUE and FAlSE. But I've no idea, what is the role of BOOL here ?
using namespace std;
#include <iostream>
template <class T>
void sort (T array[], int size)
{ int j;
T temp;
int pass;
static int call = 0;
bool xchange = true;
for (pass = 1; pass < size && xchange == true; pass++)
{ xchange = false;
for (j=0; j < size - pass; j++)
{ if (array[j] > array[j+1])
{ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp;
xchange = true;
} /* end of if */
} /* end of inner for loop */
};
call ++;
cout << " within sort : value of call is " << call << endl;
/* end of outer for loop */
} /* end of bubble sort */
int main() {
int a[] = {1,5,6,4,0,8,5,7,9,2};
int a1[] = {1,5,6,4,0,8,5,7,9,2};
char b[] = { 'a', 'c', 'f', 'd', 'b' };
sort (a, 10);
for ( int i=0; i < 10; i++ ) cout << a[i] << " ";
cout << endl;
sort (b, 5);
for ( int i=0; i < 5; i++ ) cout << b[i] << " ";
cout << endl;
sort (a1, 10);
for ( int i=0; i < 10; i++ ) cout << a1[i] << " ";
cout << endl;
return 0;
}

The bool in the example is there to check wether any exchanges happened in that iteration of the for-loop. If no exchanges happened == the array is sorted, the sorting algorithm is done.
Giving this function a already sorted array will show the purpose of the boolean. In the first iteration through the whole array, no exchanges will take place (because the array is already sorted) -> the xchange was never set to true -> the sorting algorithm is done == the condition in the for-loop condition is false.
It is there to not do work that you dont have to do.

Related

Function call [table] not working

I have big problem.
The task is:
Write a function in C ++ that takes a array of ints tab, array size n, and the number k. The function returns returns true if each of the numbers in the table tab, at least k digits long, and false otherwise. Checking how many digits has the number should be included in the additional auxiliary functions that call from inside a basic function. You should also write the main function that reads the data, calls the base and outputs its result.
For calls (record [] is an array):
f ([123,4425,2224,222,55553], 5, 3)
The function should return true. Since each of the numbers 123,4425,2224,222,55553 at least three digital
Calls for:
f ([123,4425,2,222,5], 5, 2)
The function should return false
Because there are a number, for example 2 which is a digital one and is less than 1 k = 2
My code :
#include <iostream>
int ile_cyfr(int a)
{
int temp=0;
do
{
a = a/10;
temp++;
} while(a>0);
return temp;
}
bool funkcja(int *tab, int n, int k)
{
bool stan = false;
for (int i=0; i<n; i++)
{
if (ile_cyfr(tab[i])<k)
{
stan = false;
if (stan == false)
{
return stan;
return 0;
}
}
else
{
stan = true;
return stan;
}
}
}
int main() {
using namespace std;
int n=0, k=0;
int *tab = new int[n];
cout << "Podaj ilosc liczb: " << endl;
cin >> n;
cout << "\nPodaj liczby: " << endl;
for (int i=0; i<n; i++) {
cin >> tab[i];
}
cout << "\nPodaj minimalna ilosc liczb: " << endl;
cin >> k;
cout << funkcja([444,856,671,321], n, k);
return 0;
}
The problem is that the line:
cout << funkcja([444,856,671,321], n, k);
For starters the function funkcja is invalid. It returns true in case when the first element of the array has the number of digits greater than or equal to k. As I have understood you have to check that all elements of the array satisfy the condition.
The function can be written the following way
bool funkcja( const int *tab, int n, int k )
{
int i = 0;
while ( i < n && !( ile_cyfr( tab[i] ) < k ) ) i++;
return n != 0 && i = n;
}
As for this statement
cout << funkcja([444,856,671,321], n, k);
then it has an incorrect syntax.
You have to pass the variable tab as the first argument of the function call. These values 444,856,671,321 should be assigned to elements of the array pointed to by the pointer tab.
Thus write
cout << funkcja( tab, n, k );

Non-working while loop & Messed up Binary Search

For this program I have to fill an array with 20 random numbers (1-100), sort the array (descending) and then search for a random key value and output the position of that value if it is in the array. I am having 2 problems. First the while loop I have to exit the program is not working and I can not figure out why. Second my binary search is not returning a position value and I don't know why. This code will compile.
#include <iostream>
#include <ctime>
using namespace std;
int printArray(int *arr, int arraySize);
int fillArrayWithRandomNumbers(int *arr, int arraySize);
int bubbleSortDesc(int *arr, int arraySize);
int binarySearch(int *arr, int arraySize, int key);
int main()
{
int const arraySize = 20;
int arr[arraySize];
cout << "CMPSC 201-Extra Credit\n" << "This program fills an array, and then searches for a random key value." << endl <<endl;
char stopTheProgram = 'n';
do {
int key, result;
cout << "Unordered array:" << endl;
fillArrayWithRandomNumbers(arr, arraySize);
printArray(arr, arraySize);
cout << endl << "Array after a bubble sort : " <<endl;
bubbleSortDesc(arr, arraySize);
printArray(arr, arraySize);
key = rand()%100;
cout << endl <<"Searching for " << key << endl;
result = binarySearch(arr, key, arraySize);
if (result == -1)
{
cout << "Key " << key << " not found in the array" << endl;
}
else
{
cout << "Key " << key << " found at position " << result << endl;
}
cout << "Stop the program? (y/n) ";
cin >> stopTheProgram;
cout << endl;
} while (!(stopTheProgram == 'Y' || stopTheProgram == 'y'));
return 0;
}
int fillArrayWithRandomNumbers(int *arr, int arraySize)
{
srand((unsigned)time(NULL));
for (int i = 0; i<arraySize; i++)
{
arr[i] = (rand() % 100) + 1;
}
return *arr;
}
int printArray(int *arr, int arraySize)
{
for (int i = 0; i<arraySize; i++)
{
cout << arr[i] << " ";
}
return *arr;
}
int bubbleSortDesc(int *arr, int arraySize){
int i, j;
int temp = 0;
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize - 1; j++)
{
if (arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return *arr;
}
int binarySearch(int arr[], int key, int arraySize)
{
int i, j;
int temp = 0;
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize - 1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
int position, lowerBound = 0;
position = (lowerBound + arraySize) / 2;
while ((arr[position] != key) && (lowerBound <= arraySize))
{
if (arr[position] > key)
{
arraySize = position - 1;
}
else
{
lowerBound = position + 1;
}
position = (lowerBound + arraySize) / 2;
}
if (lowerBound <= arraySize)
{
position = 19 - position;
return position;
}
else {
return -1;
}
}
Solved: I now have fixed my problems with my binary search, and exiting my while loop. I am going to leave this here just in case anyone has my prof after me. So just to recap, this program fills an array with 20 random numbers (ranging 1-100), sorts the array in descending order and then creates a random key value (between 1-100). It then bubble sorts the array so it is in ascending order, uses a binary search to find the key value in the array and finally output the position of that key value if it is in the array.
I can see two issues with your code. First, you are shadowing the stopTheProgram variable. You define it once just before the do/while loop and initialize it to 'n'; Then once inside the do/while you define another stopTheProgram. This is a problem because of scoping. Inside the do/while loop the input from the user is assigned to the local stopTheProgram (defined in the do/while) but that ceases to exits outside the loop. So the while loop expression is always evaluated using the globally scoped stopTheProgram, which is set to 'n'. So remove the second definition. Second is an issue with the expression that controls the while loop. It always evaluates true. Draw a truth table if you can't visualize it. If stopTheProgram = 'Y' then the stopTheProgram != "Y" || stopTheProgram != 'y' is 0 || 1 which is always true. If stopTheProgram = 'y' then stopTheProgram != "Y" || stopTheProgram != 'y' is 1 || 0 which is always true. This works: while(!(stopTheProgram == 'Y' || stopTheProgram == 'y'))

C++ insertion sort

I have this function called WordSort(worddata W [], int count) that is fed two variables
1 - worddata is the array holding information on a given word in a file. count is just the counter variable to see which word in the array we are looking at.
the words.txt file that is read into this program would just be a string of words.
this is a list of words
there are letters and numbers
23 people recommend this program.
Heres the function:
void WordSort (worddata W [], int count)
{
for (int i=1; i < count; i++)
{
for (int j=i; j > 0 && W[j-1].word > W[j].word; j--)
{
Swap(W[j], W[j-1]);
}
}
}
The swap function is suppose to swap every element with the one before it as long as j > 0 or the list is over. Im confused on how to complete the swap function, here's the example i was given.
void Swap (worddata & a, worddata & b)
{
int += a;
a = b;
b =+;
}
Swap is suppose to swap every element with the one before it
I think the WordSort function works fine, the only thing missing is the Swap function. Could anyone point me in the right direction or explain insertion sorting better to me?
void insertion_sort()
{
/* Algorithm : Insertion Sort
* Coded by .
*/
int num;
/*
* Asking the User no of Integers he/she wants to enter
*/
cout << "Enter no of integers u want to enter: ";
cin >> num;
/* Creating an Array to store the integers*/
int s[num];
/*Taking Integers from the User */
for(int i = 0 ; i < num ; i++)
{
cout << "Integer " << i+1 << " is : ";
int x;
cin >> x;
s[i] = x;
}
/* The Magic of INSERTION SORT */
for(int j = 1 ; j <= (num-1) ; j++)
{
int key = s[j];
int k = j-1;
while(k >=0 && key <= s[k])
{
s[k+1] = s[k];
k = k - 1;
}
s[k+1]=key;
}
/*Printing Out the Sorted List */
cout << "The Sorted List is \n\n";
for(int i = 0 ; i < num ; i++)
{
cout << s[i] << " ";
}
}
Use standard library std::swap instead. In your loop:
for (...)
{
std:swap(W[j], W[j-1]);
}
std::swap requires worddata class to have a copy constructor and an assignment operator defined explicitly or implicitly.
Swap should look like this -- I have no idea how your example is even close.
void Swap (worddata & a, worddata & b)
{
worddata temp = a;
a = b;
b = temp;
}
Insertion sort using "for loop" (2 iterations)
#include<iostream>
using namespace std;
int insertion(int arr[], int size_arr)
{
int i,j,n, temp;
for(i=1;i<size_arr; i++){
j=i-1;
temp = arr[i];
for (j; j >= 0; j--)
{
if(arr[j] > temp){
arr[j+1] = arr[j];
arr[j] = temp;
}
}
arr[j] = temp;
}
for(i=0;i<size_arr;i++){
cout<<arr[i]<<endl;
}
return 0;
}
int main(){
int arr[] = {3,38,1,44,66,23,105,90,4,6};
int size_arr = sizeof(arr) / sizeof(arr[0]);
insertion(arr,size_arr);
return 0;
}

copy one array to another without duplicates C++

The problem is that, I have an array of 10 integers, having some duplicates. The task is to copy this array to another array of same size, but without duplicate values. That is, read one element from array1, compare it with all the elements in array2, if it's already in array2, just skip it or print that it's already in array2, go to second element of array1, and repeat the process.
Now, I've tried this but don't know where's the problem:
#include <iostream>
using namespace std;
int main()
{
int temp;
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
break;
}
}
array2[i] = array1[i-1];
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl;
system("pause");
}
array1 has 10 elements and array2 has 11, so right away the requirements haven't been met. Presumably, having 11 elements was a workaround for using incorrect index values in the for loops; the index should run from 0 to 9, not from 1 to 10.
When you add an element to the second array, you should only check it value against the elements that have already been added, not against the values in the entire array.
Finally, there's an underspecification. Once you've eliminated duplicates, you have fewer than 10 elements; array2 has 10 elements; what values should the extra elements have?
std::unique_copy is your friend:
http://en.cppreference.com/w/cpp/algorithm/unique_copy
remember to sort the source array first
In C++, break immediately ends one loop structure, and starts execution immediately after it. Thus, the line array2[i] = array1[i-1]; executes redardless of whether the inner for loop finds a duplicate. One solution is to set a variable indicating that the value is a duplicate:
int main() {
int temp;
bool isDuplicate; //added this line
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
isDuplicate=false;//added this line
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
isDuplicate=true; //added this line
break;
}
}
if(!isDuplicate) //added this line
array2[i] = array1[i-1];
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl; system("pause"); }
Alternatively (though many programmers would disagree with this practice) you could use a goto statement instead of a break statement:
int main()
{
int temp;
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[11] = {0};
for(int i = 1; i <= 10; i++)
{
temp = array1[i-1];
for(int j = 1; j <= 10; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
i++;
goto duplicate; //added this line
}
}
array2[i] = array1[i-1];
//added next line
duplicate:
}
for(int k = 1; k <= 10; k++)
cout << array2[k] << " " << endl;
system("pause");
}
You could use a std::set to ensure uniqueness for you.
http://en.cppreference.com/w/cpp/container/set
You have three approaches:
compare each element one by one (O(N^2) performance)
sort your reference array and use a binary search to determine if the element exists (O(N*lnN) performance)
create a lookup hash (O(1) performance)
I can see two main sources of problems in your code: 1) the break statement, as it is, does not solve the problem of differentiating between the case when duplicate is found, and when the element in array1 should be added to array2. 2) There is no counter which would store the number of elements inserted so far into array2, this way they could not be copied to array2 next to each other. The code which fixes both is:
#include <iostream>
using namespace std;
int main()
{
int array1[] = {10,2,5,4,10,5,6,9,8,10};
int array2[10];
int array2_elements_inserted = 0;
for(int i = 0; i < 10; i++)
{
int temp = array1[i];
bool isDuplicate = false;
for(int j = 0; j < array2_elements_inserted; j++)
{
if(temp == array2[j])
{
cout << "Duplicate " << temp << endl;
isDuplicate = true;
break;
}
}
if (!isDuplicate)
{
array2[array2_elements_inserted] = temp;
++array2_elements_inserted;
}
}
for(int k = 0; k < array2_elements_inserted; k++)
cout << array2[k] << " " << endl;
// system("pause");
}
Output:
10
2
5
4
6
9
8
First of all, use dynamic containers. Especially have a look at those provide by
the standard library, e.g. std::vector. Second, you should use a set data structure
to keep track of the elements you have seen before, e.g., std::set.
Then it's just an iteration on the input array and appending new elements to the
output array.
Here's an example:
#include <vector>
#include <set>
#include <iostream>
int main() {
// define and print input data
std::vector<int> v1 = {10,2,5,4,10,5,6,9,8,10};
for (int i : v1)
std::cout << i << " ";
std::cout << "\n";
// this will soon contain the output data
std::vector<int> v2;
// a set to keep track of the already seen elements
std::set<int> set;
// iterate the input array using range-based for loop
for (int i : v1) {
// check for duplicates
if (set.find(i) == set.end()) {
// first occurrence, insert to set, append to output data
set.insert(i);
v2.push_back(i);
}
else {
// seen before, do nothing
}
}
// print output data
for (int i : v2)
std::cout << i << " ";
std::cout << "\n";
}
The output:
$ g++ test.cc -std=c++11 && ./a.out
10 2 5 4 10 5 6 9 8 10
10 2 5 4 6 9 8
For reference:
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/language/range-for
http://en.cppreference.com/w/cpp/container/set
http://en.cppreference.com/w/cpp/container/set/find

algorithm moves the array elements

I can not figure out an algorithm for this task, maybe you have an idea?
Task: Move the array to the array in the first half would be all the elements of the odd lines and the second all elements of the pair of lines.
The simplest option would be to move elements to another array, as it could make one using temp variable?
Input data array = {1,2,3,4,5,6,7,8}
output data array = {2,4,6,8,1,3,5,7}
Is this homework? If not, use std::stable_partition():
struct IsEven {
template<class T>
bool operator()(const T& v) const { return v % 2 == 0; }
};
int* arr = {1,2,3,4,5,6,7,8};
int* mid = std::stable_partition(arr, arr+8, IsEven());
If it is a homework, then your instructor probably expects you to write the algorithm. If you don't have to maintain the ordering as in the input sequence then you can do it rather efficiently:
Find the first element that doesn't satisfy the predicate (i.e., is odd).
Find that last element that does satisfy the predicate (i.e., is even)
swap the two elements.
Repeat, starting from the positions you just found, until the two positions meet.
The point where the two positions meet is the middle of the partition, where even numbers stop and odd numbers begin.
This is roughly how std::partition() works. If you do have to maintain the relative ordering in the input array then you can still do it in-place, but it will be faster if you use a temporary buffer. Copy the elements that don't match the predicate into that buffer, and squeeze in place those that do. Finally bring back in the elements that don't match, at the end of the array, in order.
I'm reading this question such that the output array should have the elements at even indices followed by those at odd indices, though I may be incorrect.
If not, then this is how I would do it.
template<typename T>
void moveValues(const T[] input, T[] output, std::size_t length)
{
int current outputIndex = 0;
if (length > 1) // in case we have a single element array.
{
for (int i = 1; i < length; i+=2)
{
output[++outputIndex] = input[i];
}
}
for (int j = 0; j < length; j+=2)
{
output[++outputIndex] = input[j];
}
assert(outputIndex == length); // should have filled up array
}
/* *********************************************************************** */
/* Author: Bigyan Shrestha */
/* Description: C++ source code for arranging even numbers */
/* numbers of an array to one half and odd */
/* numbers to the other half. */
/* *********************************************************************** */
#include <iostream>
using namespace std;
inline bool isEven( int value ){
if( value % 2 == 0 ) {
return true;
}
else {
return false;
}
}
inline void swap( int sourceIndex, int destIndex, int **sourceArray ) {
int temp;
temp = (*sourceArray)[sourceIndex];
(*sourceArray)[sourceIndex] = (*sourceArray)[destIndex];
(*sourceArray)[destIndex] = temp;
}
void displayArray( int *sourceArray, int size ){
for( int i = 0; i < size ; i++ ) {
cout << sourceArray[i] << " " ;
}
cout << endl;
}
int main( void ){
int size;
int *input;
int evenIndex = 0; // for keeping track of even numbers
cout << "Enter the size of input array" << endl ;
cin >> size;
input = new int[size];
for( int i = 0; i < size ; i++ ) {
cout << "Please enter the input value ( " << size-i << " remaining )" << endl;
cin >> input[i] ;
}
cout << endl;
cout << "Original Input Array " << endl;
displayArray( input,size );
cout << endl;
for( int i = 0; i <size ; i++ ) {
if( isEven(input[i]) && i > evenIndex ) {
for( int j = i ; j > evenIndex; j-- ){
swap( j, j-1, &input);
}
++evenIndex;
}
}
cout << "Modified Array " << endl;
displayArray( input,size );
cout << endl;
return 0;
}