copy one array to another without duplicates C++ - 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

Related

Print the array value which can produce the input by using addition operator

How do I edit the given program to get all possible combinations of array values which will provide the given data using addition operator?
The following code works fine only if there is only one combination. For example, in the array = {1,2,3,4,5}, the given value = 6; the only possibility is the sum of 2 and 4. Thus the output desired is array [1] & array[3]. Attached coding works fine for this. But for array ={1, 3, 3, 4, 2}, there is two possibilities but the code returns nothing...
#include<iostream>
using namespace std;
int main() {
int n = 5; int m = 0;
int givendata;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
cin >> givendata;
if (m < n) {
for (int i = 0; i < n; i++) {
int sum = a[n - i] + a[m];
if (sum == givendata) {
cout << m << " " << n - i;
}
}
}
m = m + 1;
return 0;
}
You need to use a double loop to compare all the values:
// start at 0, the first position of the array. Loop until the 2nd to last element
for (int i=0; i<n-1;i++)
{
// start this index at one higher than i. Since a+b == b+a, there's no need to
// add the later values in the array with the previous ones, we've already
// done that
for (int j=i+1; j<n; j++)
{
int sum = a[i]+a[j];
if (sum == givendata)
{
std::cout << a[i] << " + " << a[j] << " = " << givendata << std::endl;
}
}
}
Demonstration
Also see Why is "using namespace std;" considered bad practice?

Shift array elements

I need some help, I know this question was asked before but I don't get it and I cant solve it, so I need help. I need to move the elements of my array to a position to left. So if the input will be 1,2,3,4,5 then the output will be 2,3,4,5,1. I have done the same to right but to left I cant figure it out, please also explain the logic , thanks.
#include <iostream>
using namespace std;
int a[100],n,i,tempr,templ;
int main()
{
cin>>n;
for(i=1;i<=n;i++) cin >> a[i];
for(i=1;i<=n;i++)
{
tempr = a[n];
a[n] = a[i];
a[i] = tempr;
cout<<"Right: "<<a[i]<<endl;
}
for(i=1;i<=n;i++)
{
templ = a[2];
a[2] = a[i];
a[i] = templ;
cout<<"Left: "<<a[i]<<endl;
}
return 0;
}
Please help!
First problem is bad indexing:
for(i=1;i<=n;i++) cin >> a[i]; //wrong logic, C++ indexing start from 0
Correct approach:
for(i=0;i<n;i++) //all your loops
Second problem is wrong logic for shifting elements:
Corrected version:
//input example: 1 2 3 4 5
//to the left
int temp = a[0]; //remember first element
for(i=0;i<n-1;i++)
{
a[i] = a[i+1]; //move all element to the left except first one
}
a[n-1] = temp; //assign remembered value to last element
//output: 2 3 4 5 1
cout << "To left: " << endl;
for(i=0;i<n;i++)
cout << a[i] << endl;
//to the right
temp = a[n-1]; //remember last element
for(i=n-1;i>=0;i--)
{
a[i+1] = a[i]; //move all element to the right except last one
}
a[0] = temp; //assign remembered value to first element
//output: 1 2 3 4 5 because elements are shifted back by right shift
cout << "To right: " << endl;
for(i=0;i<n;i++)
cout << a[i] << endl;
EDIT:
How to display both shifts:
#include <iostream>
using namespace std;
int to_left[5], to_right[5],n,i,tempr,templ;
int main()
{
cout << "Input array size: ";
cin >> n;
for(i=0;i<n;i++)
{
cin >> to_left[i]; //read values to first array
to_right[i]=to_left[i]; //then copy values to second one
}
//shift first array to left
int temp = to_left[0];
for(i=0;i<n-1;i++)
{
to_left[i] = to_left[i+1]; //move all element to the left except first one
}
to_left[n-1] = temp; //assign remembered value to last element
//output: 2 3 4 5 1
cout << "To left: " << endl;
for(i=0;i<n;i++)
cout << to_left[i] << endl;
//shift second array to right
temp = to_right[n-1]; //remember last element
for(i=n-1;i>=0;i--)
{
to_right[i+1] = to_right[i]; //move all element to the right except last one
}
to_right[0] = temp; //assign remembered value to first element
//output: 1 2 3 4 5 because elements are shifted back by right shift
cout << "To right: " << endl;
for(i=0;i<n;i++)
cout << to_right[i] << endl;
return 0;
}
Note that your code look very much like C code. In C++, you can declare variables in any segment of code, not just at the beginning. In C++, you can declare variable in for loop like this: for(int i=0; i<...) - no need for global variable i
For reference, this would be good C++ code example that satisfies problem you are facing:
#include <iostream>
#include <vector>
int main()
{
std::size_t n; //size_t is unsiged type used for various sizes of containers or types
std::cout << "Input array size: ";
std::cin >> n;
std::vector<int> to_left(n), to_right(n); //two dynamic arrays containing integers, takin n as their size
for(std::size_t i=0;i<to_left.size();++i) //use vector size(), instead of n, also ++i in considered better for loops that i++ (may be faster)
{
std::cin >> to_left[i];
to_right[i]=to_left[i];
}
int temp = to_left[0]; //declare temp here, not at the begining of code
for(std::size_t i=0;i<n-1;++i)
to_left[i] = to_left[i+1];
to_left[n-1] = temp;
std::cout << "To left: " << std::endl;
for(std::size_t i=0;i<n;++i)
std::cout << to_left[i] << std::endl;
temp = to_right[n-1]; //reuse temp
for(int i=to_right.size()-1;i>=0;--i) //note int, not std::size_t, because size_t is always >=0, loop would never end.
to_right[i+1] = to_right[i];
to_right[0] = temp;
std::cout << "To right: " << std::endl;
for(std::size_t i=0;i<n;i++)
std::cout << to_right[i] << std::endl;
return 0;
}
And here would be ideal C++ code:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::size_t n;
std::cout << "Input array size: ";
std::cin >> n;
std::vector<int> to_left(n), to_right(n);
for(std::size_t i=0;i<to_left.size();++i)
{
std::cin >> to_left[i];
to_right[i]=to_left[i];
}
// rotate first array to the left
std::rotate(to_left.begin(), to_left.begin() + 1, to_left.end());
// rotate second array to right
std::rotate(to_right.rbegin(), to_right.rbegin() + 1, to_right.rend());
std::cout << "To left:" << std::endl;
for(auto x : to_left) //C++11 feature, x iterates through container
std::cout << x << std::endl;
std::cout << "To right:" << std::endl;
for(auto x : to_right)
std::cout << x << std::endl;
return 0;
}
Or you can use memmove(...) projected exactly for those purpose, here your sample:
#include <iostream>
#include <cstring>
using namespace std;
//rotate Left
void r_left(int *a,int n)
{
int tmp=a[0];
memmove(a,a+1,sizeof(int)*(n-1));
a[n-1]=tmp;
}
//rotate right
void r_right(int *a,int n)
{
int tmp=a[n-1];
memmove(a+1,a,sizeof(int)*(n-1));
a[0]=tmp;
}
void show(int *a,int n)
{
while(n--)
cout<<*a++<<' ';
cout<<endl;
}
int main()
{
int ar[]={1,2,3,4,5};
int n=sizeof(ar)/sizeof(ar[0]);
r_left(ar,n);
show(ar,n);
r_right(ar,n);
show(ar,n);
return 0;
}
easiest way to swap elements in C++ is to use std::iter_swap()
so for an array of 4 elements to swap elements 1 and 4 you would do the following
int a[4];
std::iter_swap(a, a+3);
note that you also need to #include <algorithm> for this to work
the basic logic of the function is that you give the location in memory of the 2 elements, so as the first element of an array is also its location in memory, you can pass a + n, when n is equal to the n-1 index number of the element you want to swap
As other already have stated it's all about indices. In a for-loop you are almost always in trouble if your stop condition is i <= size, because arrays in C++ are zero-indexed.
Where Black Moses alogrithm is far the easiest to understand (and probably the fastes), I read your code as if you try to swap the first value of the array through the array to the last position. Below I have tried to pin out this approach.
#include <stdio.h>
#include <tchar.h>
#include <iostream>
void ShiftLeft(int* pArr, size_t length)
{
for (size_t i = 1; i < length; i++)
{
int tmp = pArr[i - 1]; // Preserves the previous value
pArr[i - 1] = pArr[i]; // Overwrites the previous position with the current value
pArr[i] = tmp; // Stores the previous value in the current position
// All in all the first value is swapped down the array until it is at the length - 1 position
// and all the other values are swapped to the left.
/* For an array with 4 values the progression is as follows:
i = 0: 1 2 3 4
i = 1: 2 1 3 4
i = 2: 2 3 1 4
i = 3: 2 3 4 1
*/
}
}
void ShiftRight(int* pArr, size_t length)
{
for (size_t i = length - 1; i > 0; i--)
{
// This code does exactly the same as for ShiftLeft but the loop is running backwards
int tmp = pArr[i - 1];
pArr[i - 1] = pArr[i];
pArr[i] = tmp;
}
}
void Print(int* pArr, size_t length)
{
for (size_t i = 0; i < length; i++)
{
std::cout << pArr[i] << " ";
}
std::cout << std::endl;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
size_t length = sizeof(arr) / sizeof(arr[0]);
Print(arr, length);
ShiftLeft(arr, length);
Print(arr, length);
ShiftRight(arr, length);
Print(arr, length);
return 0;
}
#include <iostream>
using namespace std;
int a[100], outR[100], outL[100], n, i;
int main() {
cin >> n;
for (i = 0; i < n; i++) cin >> a[i];
// Right
for (i = 0; i < n; i++) {
outR[i+1]= a[i];
}
outR[0] = a[n-1]; // add first number
// Left
for (i = 1; i < n; i++) {
outL[i-1]= a[i];
}
outL[n-1] = a[0]; // add last number
// Answer
cout << "Right:\n";
for(i=0; i<n; i++) {
cout << outR[i] << endl;
}
cout << "Left:\n";
for(i = 0; i < n; i++) {
cout << outL[i] << endl;
}
return 0;
}
Simple answer where you can easily see everything, good luck.
You may be interested in ,,vector coding", it seems be easier if you spend some time on this:
#include <iostream>
#include <vector>
using namespace std;
vector <int> a, outR, outL;
size_t i;
int main () {
int n, temp_int;
cin >> n;
while (n--) {
cin >> temp_int; // here you read number to your vector
a.push_back(temp_int); // here you add this to vector
// remember that vector start from element 0 as like arrays
}
// Left
// remember that last element will be first
// you may have acces to size of your vector easily
for (i = 0; i < (a.size()-1); i++) {
outL.push_back(a.at(i+1)); // here you create new vector
}
outL.push_back(a.at(0)); // add last elemet which rotated
// Right
// to rotate left first you have push last element so
outR.push_back(a.at(a.size()-1)); // add first elemet which rotated
for (i = 1; i < a.size(); i++) {
outR.push_back(a.at(i-1)); // here you push rest
}
cout << "Left" << "\n";
for (i = 0; i < a.size(); i++) {
cout << outL.at(i) << endl; // here you print value
}
cout << "Right" << "\n";
for (i = 0; i < a.size(); i++) {
cout << outR.at(i) << endl; // here you print value
}
return 0;
}
int* leftShiftOneByOneWIthoutTemp(int arr[], int sz)
{
for (int i=0 ;i < sz-1; i++)
{
arr[i] = arr[sz-1] + arr[i];
arr[sz-1] = arr[i] - arr[sz-1] ;
arr[i] = arr[i] - arr[sz-1] ;
std::cout << "iter "<< i << std::endl;
printArray(arr,5);
}
std::cout << "final "<< std::endl;
printArray(arr,5);
return arr;
}
Replace your code (to shift array left) with below code.
templ = a[0];
for(i=0;i<n-1;i++)
{
a[i] = a[i+1];
cout<<"Left: "<<a[i]<<endl;
}
a[n-1] = templ;
cout<<"Left: "<<a[n-1]<<endl;

Create randomly sized (within a certain range) arrays over many iterations

I am trying to create many arrays consisting of random numbers and of random size between the range of, say, 1 and 20 elements. My code works SOMETIMES.
I am using a random number between my desired range to determine the array size. If the first iteration produces an array size of value 10, say, then for some reason my code does not want to create any arrays of size larger than 10. Various arrays will be created (and the list of those arrays will be outputed) until a certain iteration produces a random number larger than 10. Then I get this error:
Array index out of range numbers->[11] valid upto numbers[9]
"numbers" is the name of the array. Here is the relevant portion of my code:
srand(time(0));
int j, flag = 0;
int temp;
int rand=1;
for(int t=0; t<50; t++)
{
int length = rand()% 20 + 1;
cout<<"length is " << length << endl;
int numbers[length];
for(int i = 0; i < length; i++)
{
numbers[i]=rand();
cout << numbers[i] << endl;
}
for(j=0; (j<=length); j++)
{
for (int i=0; i<(length-1); i++)
{
if(numbers[i+1]<numbers[i])
{
temp=numbers[i];
numbers[i]=numbers[i+1];
numbers[i+1]=temp;
flag++;
}
}
}
cout << "Number of Swaps : " << flag << endl;
}
As #Bob__ wrote, allocating variable length arrays is not C++ standard. It might work sometimes on specific compilers, but it may break on others.
But there are good alternatives. You can allocate dynamic memory with new. For instance:
int *array = new int[size];
array[0] = 3;
array[1] = 5;
cout << array[1];
delete [] array;
Don't forget to delete the memory with delete afterwards.
Or you could use vector<int>. It's a STL-container, that was made for exactly this purpose.
#include <vector>
using namespace std;
...
vector<int> vec(size);
vec[0] = 3;
vec[1] = 5;
cout << vec[1];
Variable Length Arrays are not in C++ standard, but only offered as extension by some compilers. I wouldn't trust them and you don't really need anything like that in your code.
You can declare your array outside the outer for loop as you know its max lenght:
#define MAXL 20
int numbers[MAXL];
for ...
int length = rand() % MAXL + 1;
...
Besides, if you are implementing a bubble sort I think that the condition of the inner i loop should be i < length - j
rand is used in two contexts. As a variable int rand and as a function std::rand(). I'd suggest to delete any using namespace std; but since the variable is not needed anyways you could as well delete int rand = 1;. Note that rand() is a C function. You may use it but IMHO std::rand() is more pure C++.
int numbers[length]; will not compile because length is a non-constant. Use std::vector<int> numbers(length); instead.
And that's about it.
#include <iostream>
#include <vector>
#include <time.h>
int main()
{
std::srand(time(0));
int j, flag = 0;
int temp;
for (int t = 0; t < 50; t++)
{
int length = std::rand() % 20 + 1;
std::cout << "length is " << length << std::endl;
std::vector<int> numbers(length);;
for (int i = 0; i < length; i++)
{
numbers[i] = std::rand();
std::cout << numbers[i] << std::endl;
}
for (j = 0; (j <= length); j++)
{
for (int i = 0; i < (length - 1); i++)
{
if (numbers[i + 1] < numbers[i])
{
temp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = temp;
flag++;
}
}
}
std::cout << "Number of Swaps : " << flag << std::endl;
}
}

Int to Char array(part sums)

I have problem with "tab" output. My program is going to show part sums.
I want to save those part sums in tab array but it shows only first sum.
here is code I wrote:
const char numbers[] = { "1 2 3 4" };
cout << numbers << endl;
for (int i = 0; i < strlen(numbers); ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < strlen(numbers); ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
How I can make it to show proper part sums like: 1 3 6 10
sizeof shows the size of the array in bytes, not the number of elements in the array.
Something like this will give you the number of elements:
int num_element = sizeof(numbers)/sizeof(numbers[0]);
Or a full solution:
const char numbers[] = { "1 2 3 4" };
int num_elements = sizeof(numbers)/sizeof(numbers[0]);
cout << numbers << endl;
for (int i = 0; i < num_elements; ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < num_elements; ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
Although the above should work after replacing num_element into your for loops, I suggest you looking into a std::array or std::vector
Your code has several problems. The first one is that function atoi will return an error because is will consider all string starting from &numbers[i] till the terminating zero. The other problem is that this in expression
_itoa_s(sum,&tab[i],sizeof(tab),10);
using tab[i] is incorrect.
Try the following code.
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
//...
const char numbers[] = { "1 2 3 4" };
char tab[20];
char *p = tab;
int sum = 0;
for ( size_t i = 0, n = std::strlen( numbers ); i < n; i++ )
{
if ( std::isdigit( numbers[i] ) )
{
sum += numbers[i] - '0';
p += std::sprintf( p, "%d ", sum );
}
}
std::cout << tab << std::endl;
At least I got output
1 3 6 10
Also it would be better to use std::istringstream instead of the for loop where you are extracting digits.
You are not retrieving the size of your arrays here.
Use SIZEOF_ARRAY to get the size of numbers in C.
But you tagged C++, so consider using std::array<> instead of a C-style array (it will expose the size of the array for you)
Firstly, cout << tab; prints only the first element.
Secondly, instead of writing the result to tab[i], create int cnt = 0; _itoa_s(sum,&tab[cnt],sizeof(tab),10); cnt++ By that way, you won't have empty characters in you tab array.
Thirdly, you can keep int tab[20], rather than to keep in char tab[].
Forthly, int num_elem = sizeof(numbers)/sizeof(numbers[0]);(as said above).

Can't find logic error, and need a second pair of eyes

Hi I'm working on this acm problem, and I can't seem to figure out why my algorithm isn't working.
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=482
My sillySort function is supposed to be finding all the different subarrays, and then minimizing the sum of the swapped values.
My output is very close to their output, but I'm not sure what's wrong. I have sat down and even written the problem out on a whiteboard. Can anyone spot it?
#include <iostream>
void swap(int* array, int index1, int index2)
{
int temp;
temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
void printArray(int* array, int size)
{
for(int i = 0; i < size; i++)
{
std::cout << array[i] << " ";
}
std::cout << "\n";
}
int sillySort(int* array, int size)
{
int minSum = 0;
bool firstSwap = true;
printArray(array, size);
for(int i = 0; i < size; i++)
{
for(int i2 = i + 1; i2 < size; i2++)
{
//Found a swappable pair
if(array[i] > array[i2])
{
int sum = array[i] + array[i2];
std::cout << "Swapping: " << array[i] << " and " << array[i2] << " (" << sum << ")" << std::endl;
//Temporary swap the array to call silly on it
swap(array, i, i2);
//Calculate silly on new array
int minSilly = sillySort(array, size);
//Found a new minimum
if((minSilly + sum) < minSum || firstSwap)
{
firstSwap = false;
minSum = minSilly + sum;
}
//Move array back into position
swap(array, i, i2);
}
}
}
std::cout << "Returning: " << minSum << std::endl;
return minSum;
}
int main()
{
const int arraySize = 6;
int array[arraySize];
array[0] = 8;
array[1] = 4;
array[2] = 5;
array[3] = 3;
array[4] = 2;
array[5] = 7;
std::cout << sillySort(array, arraySize) << std::endl;
return 0;
}
That was an interesting problem!
Consider the second sample case: the 4-element array is 8124. (It was easier to solve for a 4-element array than a 7-element array; and your program didn't get the best answer on that one either.)
The correct answer of the best cost is 17. Here is a sequence of moves (and I'm sure it's unique, but haven't proved it) that will get you a sorted list with a cost of 17.
Swap 1 and 2. Cost is 3. New sequence is 8214.
Swap 1 and 4. Cost is 5. New sequence is 8241.
Swap 1 and 8. Cost is 9. New sequence is 1248 (sorted).
Total cost is 17.
Your program can't get there because it only swaps elements when they are in the wrong order. My first swap moved 1 to appear after 2, which changed them from the right order to the wrong order... but that move is on the way to the right, and minimal-cost, solution.
So the solution is to relax the assumption that you must only swap things that are out of order. (You'll also need to restructure your algorithm, since that assumption is currently the only thing that prevents infinite recursion.)