Comparing palindromes using different functions - c++

I am trying to call the functions so that it prints out if the array is a palindrome or not. Please tell me what I am doing wrong; it seems I am not passing the arguments correctly. If I made a mistake with the post, please let me know; I am fairly new to the website.
This is how the output is supposed to look:
This is what my output looks like:
This is my code:
#include <stdio.h>
void createReverseArray();
void printArray();
void compareArray();
int main()
{
int MyArray1[] = {1, 2, 3, 2, 1};
int MyArray2[] = {1, 2, 3, 4, 1};
int MyArray3[] = {1, 2, 3, 3, 2, 1};
int MyArray4[] = {1, 2, 3, 4, 2, 1};
int n = 5, i, j, n, temp;
createReverseArray(MyArray1[5]);
createReverseArray(MyArray2[5]);
createReverseArray(MyArray3[5]);
createReverseArray(MyArray4[5]);
compareArray(MyArray1[5]);
compareArray(MyArray2[5]);
compareArray(MyArray3[5]);
compareArray(MyArray4[5]);
printArray(MyArray1[5]);
printArray(MyArray2[5]);
printArray(MyArray3[5]);
printArray(MyArray4[5]);
}
int createReverseArray(int &a[], int n)
{
i = 0;
j = n - 1;
while(i<j) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
return reverse = a[];
}
int compareArray(int &a[], int reverse)
{
if(a[] == reverse) {
printf("The array is a palindrome")
}
else {
return 0;
}
}
void printArray(&a[])
{
printf("Array elements are:%d", a[]);
compareArray(a[]);
}

I am not sure due to the amount of uncertainties I have with the provided code, but if your objective is simply to detect whether the array is a palindrome, it is exceedingly simple and can be done in a single function:
bool isPalindrome(int[] list, int size)
{
for(int k = 0; k < size / 2 - 1; k++)
if(list[k] != list[size - k - 1])
return false;
return true;
}
This will iterate half your array, comparing it to the second half and exiting the instant one value is not equal to its mirror.
As for the mistakes in your code, I might be able to point out some of the more obvious ones, for future reference:
Calling functions with incorrect number of arguments.
Example: createReverseArray(MyArray1[5]).
Calling passing integers in place of arrays as arguments. Example:
MyArray[5] is the integer in the sixth position of MyArray.
Ignoring scope and using variables without declaring them. Example: i and j from main being used in createReverseArray. THIS DOES NOT WORK.
Comparing an integer to an array pointer. Example: if(a[] == reverse). No matter what you were trying to achieve, this will never give you a useful result.
Declaring different functions in your forward declaration and in your implementation. Example: void createReverseArray(); and int createReverseArray(int &a[], int n). You should declare them wit the same arguments and return values or the compiler will not understand they're the same thing.

Related

returning 2 values from array using recursion c++

This is the code to find a number in the array and return its index. But what if I have the same 2 numbers and I want to return both their indexs ?
int find_pos (int a[], int index, int n)
{
if ( a[index] == n)
{
return index;
}
else
{
return find_pos (a, index + 1, n);
}
}
int main()
{
int a[] = {3, 1, 5, 6, 0, 6, 8, 4};
cout << find_pos (a, 0, 6);
}
You could use a vector<int> to hold the indices of found values. That is, instead of returning when you find a matching value, just save the index into your vector and continue searching. This means that your recursion base case has to change. You'll have to search all the way to the end of the array. Since you're using a C-style array, you'll have to also pass in the length of the array too, so that recursive function calls can know when to stop.

Rotate array to right instead of left

I have some code that rotates a number array to the left but instead, I need it to rotate it to the right. There is other code online that rotates array to the right but that code lets you only rotate numbers in the middle of the array.
I have tried decrementing the loops differently & and changing where its initialized but doesn't seem to rotate the correct way.
Expected output: if array is this {1, 2, 3, 4, 5, 6, 7}. Then it should look like: {7, 1, 2, 3, 4, 5, 6}
Current output: {2, 3, 4, 5, 6, 7, 1}
#include <iostream>
using namespace std;
/*Function to left Rotate arr[] of size n by 1*/
void leftRotatebyOne(int arr[], int n);
/*Function to left rotate arr[] of size n by d*/
void leftRotate(int arr[], int d, int n)
{
int i;
for (i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
void leftRotatebyOne(int arr[], int n)
{
int i, temp;
temp = arr[0];
for (i = 0; i < n-1; i++)
arr[i] = arr[i+1];
arr[i] = temp;
}
/* utility function to print an array */
void printArray(int arr[], int size)
{
int i;
for(i = 0; i < size; i++)
cout << arr[i] << " ";
}
/* Driver program to test above functions */
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7};
printArray(arr, 7);
leftRotate(arr, 1, 7);
cout << "___" << endl;
printArray(arr, 7);
getchar();
return 0;
}
leftRotateByOne is the key function here. The others can stay the same. Have a look at what it is doing, preferably with a pen and paper to keep track of the operations:
Keeps a copy of the first element.
Moves all elements to the "left" (that is, to the element with index
one less), being careful not to overwrite anything you need later.
Puts the first element in the last place.
So you need to do the opposite:
Keep a copy of the last element.
Moves all elements to the "right" (that is, to the element with index
one more), being careful not to overwrite anything you need later.
Puts the last element in the first place.
For example:
void rightRotatebyOne(int arr[], int n)
{
int i, last;
last = arr[n-1];
for (i = n-1; i > 0; i--)
arr[i] = arr[i-1];
arr[0] = last;
}

Function not found in C++

I am using sublime text 2 and I am trying to program bubble sort, and every time I run the code below it gives me an error on bubbleSort(num[5], terms); the error is
ERROR: no matching function for call to 'bubbleSort'.
Can anyone tell me why this is happening.
The code is:
#include <iostream>
using namespace std;
void bubbleSort(int arr[], int term) {
for(int i = 0; i < term; ++i) {
for(int index = 0; index < term-i-1; ++index) {
if(arr[index] < arr[index + 1]) {
int swap;
swap = arr[index];
arr[index] = arr[index + 1];
arr[index + 1] = swap;
}
}
}
for(int counter = 0; counter < term; counter++) {
cout << arr[counter] << endl;
}
}
int main() {
cout << "Hi in this program I will do bubble sort" << endl;
cout << "The numbers are 2, 9, 5, 10, 6"<< endl;
int num[5] = {2, 9, 5, 10, 6};
int terms = sizeof (num) / sizeof (num[0]);
bubbleSort(num[5], terms);
//answer = [2, 5, 6, 9, 2, 10]
}
Although a good question should be accompanied by a complete example of the compiler error, this answer should be fine.
void bubbleSort(int arr[], int term) {
// ...
}
It's a function which accepts an array of integers as first parameter and an integer as second one.
When you try to invoke it with:
int num[5] = {2, 9, 5, 10, 6};
// ...
bubbleSort(num[5], terms);
You're passing num[5] which is not an array of integer, but it should be an element of the array num, then an integer itself.
In short you're calling the function passing
bubbleSort(INT, INT);
and not, as requested by the function
bubbleSort(ARRAY_INT, INT);
That' why the compiler doesn't find a function which names bubbleSort and accept two integers.
Additional note
It's a little be out of context, but I want to suggest you to improve your C++ base skills, because the expression:
num[5]
It's perfectly wrong in your code, because it tries to access to the 6-th element in the array (which is composed by only 5 elements), that'll produce an out-of-bound behaviour.
Thanks for helping me now I know that I am supposed to use
bubbleSort(num, terms);

func return list<int> with args (int arry[int], int array[int])

my problem is:
this algorithm work i think... but Visual Studio 2013 gives me this error:
C2893 unknown-type std::less::operator()(_Ty1 &&,_Ty2 &&) const.
i have to create a func that take 2 arrays of int and return a list with the elements of the arrays, sorted and without elements who repeat in the series into the list.
list<int> sort_array(int *elenco1[C], int *elenco2[C])
{
list<int> merge1;
list<int> merge2;
for (int i = 0; i < C; ++i)
{
merge1.push_back(*elenco1[i]);
}
for (int i = 0; i < C; ++i)
{
merge2.push_back(*elenco2[i]);
}
merge1.sort();
merge2.sort();
merge1.merge(merge2);
merge1.sort();
list<int>::iterator inizio = merge1.begin();
list<int>::iterator fine = merge1.end();
for (inizio; inizio != fine; ++inizio)
{
for (fine; fine != inizio; --fine)
{
if (*fine == *inizio)
{
merge1.erase(inizio);
}
else{}
}
}
return merge1;
}
int main()
{
list<int> stampa;
int* elenco1[C];
int* elenco2[C];
for (int i = 1; i <= 5; ++i)
{
for (int k = 0; k < C; ++k)
{
*elenco1[k] = i;
}
}
for (int i = 5; i <= 9; ++i)
{
for (int k = 0; k < C; ++k)
{
*elenco1[k] = i;
}
}
stampa = sort_array(elenco1, elenco2);
list<int>::iterator inizio = stampa.begin();
list<int>::iterator fine = stampa.end();
for (inizio; inizio != fine; ++inizio)
{
cout << *inizio << " ";
}
cout << endl;
getchar();
return 0;
}
Unless you're really set on doing things in as difficult a way as possible, use some standard algorithms (and probably std::vector instead of list). The specific algorithms you care about are std::sort and std::unique.
The basic idea is to create a vector containing the elements of both input vectors. Sort that, then use std::unique to remove duplicates. Code could look vaguely like this:
#include <vector>
#include <algorithm>
#include <iostream>
std::vector<int>
merge_sort_unique(std::vector<int> in1, std::vector<int> const &in2) {
in1.insert(in1.end(), in2.begin(), in2.end());
std::sort(in1.begin(), in1.end());
in1.erase(std::unique(in1.begin(), in1.end()), in1.end());
return in1;
}
And here's a quick demo of using this:
int main() {
std::vector<int> in1{ 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 1 };
std::vector<int> in2{ 10, 10, 9, 10, 1, 10, 9, 4, 4, 5, 2, 2, 2, 2, 8, 2, 2, 2 };
std::vector<int> out = merge_sort_unique(in1, in2);
for (int i : out)
std::cout << i << "\t";
}
One quick note: since we need a copy of the input data, I've started by passing the first argument by value, so that's a copy of one of the inputs. We then copy the content of the other input to the end of that. Then we have a single vector containing all the data, which we can then sort and remove duplicates.
This copying might initially seem wasteful, but unless we're allowed to modify one of the inputs it's really necessary.
And yes, if you're really concerned with saving space, even at the expense of slightly greater algorithmic complexity, you certainly can sort first, then remove duplicates from each input, then merge and remove duplicates again. If you expect to have a lot of duplicates, this might even be faster--but you'd need a fair amount of knowledge of the input data to be at all certain that it was faster (or even "not slower").
compiles fine here also VS 2013...
your code will not work though because of the arrays of pointers to int. You need arrays of int not arrays of pointer to int
replace
int *elenco1[C]
with
int elenco[C];
and drop the asterisk in sort_array
There's more:
for (fine; fine != inizio; --fine)
{
if (*fine == *inizio)
{
merge1.erase(inizio);
}
}
Here you are looping with an iterator but also using erase. erase will invalidate the iterator and the loop wont work anymore. erase return a new valid iterator, so better use
inizio = merge1.erase(inizio);

How to get distinct values from an arrays of different sizes?

Q:
arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9}
Ans:
values[]={1,2,5,6,7,9}
Q:
arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9}
Ans:
values[]={1,2,5,6,7,9,101,1502}
here is what i tried but not working
for(int i=0;i<(index-1);i++) {
if(data[i].age != data[i+1].age) {
c=new list;
c->value=data[i].age;
c->next=NULL; clas++;
if(age_head==NULL) {
p=c; age_head=c;
}
for(c=age_head;c!=NULL,c->next!=NULL;p=c,c=c->next) {
if(data[i].age!=c->value)
found=false;
else
found=true;
}
if((age_head!=NULL)&& (found=false)) {
p->next=c; c->next=NULL;
}
}
}
This is not the most efficient, but it has some values:
It uses STL objects
It uses a cool little known template trick for knowing at compile time the size of your C-like arrays
...
int a[] = {1,1,1,2,5,5,6,6,6,6,8,7,9} ;
int b[] = {1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9} ;
// function setting the set values
template<size_t size>
void findDistinctValues(std::set<int> & p_values, int (&p_array)[size])
{
// Code modified after Jacob's excellent comment
p_values.clear() ;
p_values.insert(p_array, p_array + size) ;
}
void foo()
{
std::set<int> values ;
findDistinctValues(values, a) ;
// values now contain {1, 2, 5, 6, 7, 8, 9}
findDistinctValues(values, b) ;
// values now contain {1, 2, 5, 6, 7, 8, 9, 101, 1502}
}
Another version could return the set, instead of taking it by reference. It would then be:
int a[] = {1,1,1,2,5,5,6,6,6,6,8,7,9} ;
int b[] = {1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9} ;
// function returning the set
template<size_t size>
std::set<int> findDistinctValues(int (&p_array)[size])
{
// Code modified after Jacob's excellent comment
return std::set<int>(p_array, p_array + size) ;
}
void foo()
{
std::set<int> valuesOne = findDistinctValues(a) ;
// valuesOne now contain {1, 2, 5, 6, 7, 8, 9}
std::set<int> valuesTwo = findDistinctValues(b) ;
// valuesTwo now contain {1, 2, 5, 6, 7, 8, 9, 101, 1502}
}
The first thing I spot in your code is
if((age_head!=NULL)&& (found=false)) {
you use assignment (=) instead of equality (==). The expression should be
if((age_head!=NULL)&& (found==false)) {
Then, in this loop
for(c=age_head;c!=NULL,c->next!=NULL;p=c,c=c->next) {
you are looking for a value in the list. However, in its current form, when the loop terminates, found will show whether the last element in the list equals to c->value. You need to check for found in the loop condition (and you need to AND the expressions instead of listing them separated by comma!):
for(c=age_head, found = false; !found && c!=NULL && c->next!=NULL; ...) {
The result of the comma operator is the result of the last subexpression inside - this is definitely not what you want. Moreover, with comma all subexpressions are evaluated, which results in dereferencing a null pointer if c == NULL - whereas the && operator is evaluated lazily, thus c->next!=NULL is evaluated only if c != NULL.
The next thing is that you need to search for the value in the list before you add it to the list! Also note that you are trying to check for two different things: that the actual data element is different from the next one, and that its value is not yet added to the list. The second condition is stronger - it will always work, while the first only works if the input data is ordered. So you can omit the first check altogether. The result of all the above, plus some more simplifications and clarifications, is
for(int i=0;i<index;i++) {
for(list* c=age_head, found=false; !found&&c&&c->next; p=c,c=c->next) {
if(data[i].age==c->value)
found=true;
}
if(!found) {
list* newc=new list;
newc->value=data[i].age;
newc->next=NULL;
clas++;
if(age_head==NULL) {
p=newc; age_head=newc;
} else {
p->next=newc; newc->next=NULL;
}
}
}
I still don't guarantee that your linked list handling logic is right though :-) In its current form, your code is hard to understand, because the different logical steps are not separated. With a bit of refactoring, the code could look a lot clearer, e.g.
for(int i=0;i<index;i++) {
if(!foundInList(data[i].age)) {
addToList(data[i].age);
}
}
Of course the simplest and most efficient would be using STL containers/algorithms instead, as shown in other answers. But I think there is much more educational value in improving your first attempt :-)
If the output need not to be sorted, you can use a Hashtable.
E.g. something like this:
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
#include <boost/unordered_set.hpp>
#include <vector>
using namespace std;
using namespace boost;
int main() {
int arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9};
size_t n = sizeof(arr1)/sizeof(int);
unordered_set<int> h;
for (size_t i = 0; i < n; ++i)
h.insert(arr1[i]);
vector<int> values;
foreach(int a, h)
values.push_back(a);
return 0;
}
The runtime is then in O(n).
An alternative to that is sorting the array and then to eliminate neighboring identical elements (advantage only STL is needed). But then the runtime is in O(n log n):
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9};
size_t n = sizeof(arr1)/sizeof(int);
sort(arr1, arr1+n);
int *end = unique(arr1, arr1+n);
vector<int> values(arr1, end);
return 0;
}
Easily done using STL.
int array[] = { 1, 1, 2, 2, 1, 3, 3, 4, 5, 4, 4, 1, 1, 2 };
int nElements = sizeof(array)/sizeof(array[0]);
std::sort(&array[0], &array[nElements]);
int newSize = std::unique(&array[0], &array[nElements]) - &array[0];
first you need to sort the array and than do something like this:
for(int i = 0; i < size -1; i++)
{
if(array[i]!=array[i+1])
unique++;
// store it wherever you want to.
stored.push(array[i]);
}
#include <vector>
#include <algorithm>
#include <iostream>
int
main ()
{
int array[] = { 1, 1, 2, 2, 1, 3, 3, 4, 5, 4, 4, 1, 1, 2 };
std::vector < int >values;
values.push_back (array[0]);
for (int i = 1; i < sizeof (array) / sizeof (int); ++i)
{
std::vector < int >::iterator it =
std::find (values.begin (), values.end (), array[i]);
if (it == values.end ())
values.push_back (array[i]);
}
std::cout << "Result:" << std::endl;
for (int i = 0; i < values.size (); i++)
std::cout << values[i] << std::endl;
}
This seems to be a duplicate of Removing duplicates in an array while preserving the order in C++
While the wording of the question is different, the result is the same.
Based on above ideas/codes, I am able to accomplish my job on finding distinct values in C++ array. Thanks every one who replied on this thread.
#include <set>
#include <iostream>
using namespace std;
// function setting the set values
template<size_t size>
void findDistinctValues(std::set<int> & p_values,int (&p_array)[size])
{
// Code modified after Jacob's excellent comment
p_values.clear() ;
p_values.insert(p_array, p_array + size) ;
}
void findDistinctValues2( int arr[],int size)
{
std::set<int> values_1 ;
std::set<int>::iterator it_1;
values_1.clear();
values_1.insert(arr,arr+size);
for (it_1=values_1.begin(); it_1!=values_1.end(); ++it_1)
std::cout << ' ' << *it_1<<endl;
}
int main()
{
int arr[] = {1,6100,4,94,93,-6,2,4,4,5,5,2500,5,4,5,2,3,6,1,15,16,0,0,99,0,0,34,99,6100,2500};
std::set<int> values ;
std::set<int>::iterator it;
int arr_size = sizeof(arr)/sizeof(int);
printf("Total no of array variables: %d\n",arr_size);
printf("Output from findDistinctValues (function 1)\n ");
findDistinctValues(values, arr) ;
for (it=values.begin(); it!=values.end(); ++it)
std::cout << ' ' << *it<<endl;
std::cout<<endl;
std::cout<<values.size()<<endl; //find the size of distict values
printf("Output from findDistinctValues (function 2) \n ");
findDistinctValues2(arr,arr_size);
getchar();
return 0;
}