Visual C++ Merge Sort - arrays

I'm trying to figure out why the following code does not do a merge sort. The code compiles fine and there are no runtime errors. SortCollection method just returns an unsorted array. No compile errors and no run time errors, just returns an unsorted array. Any pointers would be greatly appreaciated.
#include "stdafx.h"
#include <deque>
#include <climits>
#include <stdio.h>
using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;
generic <typename T> where T: IComparable<T>
ref class MergeSort
{
public:
// constructor
MergeSort(){}
// SortCollection() method
array<T>^ SortCollection(array<T>^ inputArray)
{
int n = inputArray->Length;
if (n <= 1)
{
return inputArray;
}
array<T>^ array1 = gcnew array<T>(inputArray->Length / 2);
array<T>^ array2 = gcnew array<T>(inputArray->Length - array1->Length);
int array1Count = 0;
int array2Count = 0;
for (int i = 0; i < n; i++)
{
if (i < n / 2)
{
array1[array1Count] = inputArray[i];
array1Count++;
}
else
{
array2[array2Count] = inputArray[i];
array2Count++;
}
}
SortCollection(array1);
SortCollection(array2);
array<T>^ newArray = gcnew array<T>(inputArray->Length);
delete inputArray;
return Merge(newArray, array1, array2);
}
array<T>^ Merge(array<T>^ targetArray, array<T>^ array1, array<T>^ array2)
{
int n1 = array1->Length;
int n2 = array2->Length;
int x1 = 0;
int x2 = 0;
int counter = 0;
while (x1 < n1 && x2 < n2)
{
if (array1[x1]->CompareTo(array2[x2]) < 0)
{
targetArray[counter] = array1[x1];
x1 ++;
counter++;
}
else
{
targetArray[counter] = array2[x2];
x2 ++;
counter++;
}
}
while (x1 < n1)
{
targetArray[counter] = array1[x1];
counter ++;
x1 ++;
}
while (x2 < n2)
{
targetArray[counter] = array2[x2];
counter ++;
x2 ++;
}
return targetArray;
}
};

Hmm... but what are you printing/testing? The original array or what Sort return?
Anyway, try this:
SortCollection(array1);
SortCollection(array2);
// array<T>^ newArray = gcnew array<T>(inputArray->Length);
// delete inputArray; ---> "reuse" the input array
return Merge(inputArray, array1, array2);
EDIT:
I’m sure you know this, but you just need to paid more attention to it.
A „Normal“ function take arguments and return a result, without changing the arguments:
Y=f(x);
You expect x to be as previous, and the result in y. These are the good function. But some function will change the argument. Sometime it is evident, like in
Destroy(x);
but oft is not very evident, like in
y=sort(x);
Passing x “by value” is a guaranty not to be change, but if the function take a kind of reference (like type^ x) it have direct access to the original variable and can change its contents. This duality is what you have (in SortCollection and in Merge). You need to decide, and “document” what your function return and how modify the arguments it take.
In one version (with delete) you modify the argument deleting it!!! This is normally not a good idea and has to be very good documented. And the sorted array is passed as a “return value” (a sort of reference too, really). This version modifies the argument but the result is in the return (and that is what you need to use/test/print).
The version without the delete modifies the argument, by putting the sorted array in it. In this case it could be perfectly what you want. Anyway – document it! It returns a reference to the sorted array too, -to the argument. It is done for convenience, but can be exclude for better readability, and “return” just void.
A third variant could be, not modify the argument, and return the sorted array.

Here you have a problem:
SortCollection(array1); // array1 is deleted??
SortCollection(array2); // you dont use any result from here?
array<T>^ newArray = gcnew array<T>(inputArray->Length);
delete inputArray; // sort, deleted input array !
return Merge(newArray, array1, array2);
Is here correct??
array1=SortCollection(array1);
array2=SortCollection(array2);
array<T>^ newArray = gcnew array<T>(inputArray->Length);
delete inputArray;
return Merge(newArray, array1, array2);

Related

cocos2dx : Change Array to Vector

I need to change Array to Vector as it is being depracted in cocos2dx.
Earlier it was running but after deprecation its giving error.
As I am quite new to cocos2dx I am not able to resolve this issue.
Here is my code:
int BaseScene::generateRandom()
{
//int rn = arc4random()%6+1;
int rn = rand() % 6 + 1;
Array * balls = (Array*)this->getChildren();
Array * ballsTypeLeft = Array::create();
// if(balls->count() <= 7)
{
for (int j=0; j<balls->count(); j++)
{
Node * a = (Node*)balls->objectAtIndex(j);
if(a->getTag() >= Tag_Ball_Start)
{
Ball * currentBall = (Ball*)balls->objectAtIndex(j);
bool alreadyHas = false;
for(int k=0;k<ballsTypeLeft->count();k++)
{
if(strcmp(((String*)ballsTypeLeft->objectAtIndex(k))->getCString(), (String::createWithFormat("%d",currentBall->type))->getCString()) == 0)
{
alreadyHas = true;
}
}
if(alreadyHas)
{
}
else
{
ballsTypeLeft->addObject(String::createWithFormat("%d",currentBall->type));
}
}
}
}
// CCLog("%d",ballsTypeLeft->count());
if(ballsTypeLeft->count() <=2)
{
// int tmp = arc4random()%ballsTypeLeft->count();
int tmp = rand() % ballsTypeLeft->count();
return ((String*)ballsTypeLeft->objectAtIndex(tmp))->intValue();
}
return rn;
}
How can I make this method working?
Please convert this method using Vector.
Thanks
To change cocos2d::Array to cocos2d::Vector, you must first understand it. cocos2d::Vector is implemented to mimick std::vector. std::vector is part of the STL in c++. cocos2d::Vector is built specifically to handle cocos2d::Ref. Whenever you add a Ref type to Vector it automatically retained and then released on cleanup.
Now to change Array to Vector in your code:
Store children this way:
Vector <Node*> balls = this->getChildren();
Access ball at index i this way:
Ball* ball = (Ball*)balls.at (i);
Add elements to vector this way:
balls.pushBack (myNewBall);
EDIT -
From what I understand, you want to get a random ball from the scene/layer. You can perform this by simply returning the Ball object:
Ball* BaseScene::generateRandom()
{
Vector <Node*> nodeList = this->getChildren();
Vector <Ball*> ballList;
for (int i = 0; i<nodeList.size(); i++)
{
if (ball->getTag() >= Tag_Ball_Start)
{
Ball * ball = (Ball*)nodeList.at(i);
ballList.pushBack(ball);
}
}
if (ballList.size() > 0)
{
return ballList[rand() % ballList.size()];
}
return nullptr;
}
If there is no ball it will return NULL which you can check when you call the function. The code you have linked below seems to make use of Arrays outside the function. You need to make the changes to accommodate that. I suggest studying the documentation for Vector.

Merging two arraylists without creating third one

Here is one task, i was trying to solve. You must write the function
void merge(ArrayList a, ArrayList b) {
// code
}
The function recieves two ArrayLists with equal size as input parameters [a1, a2, ..., an], [b1, b2, ..., bn]. The execution result is the 1st ArrayList must contain elements of both lists, and they alternate consistently ([a1, b1, a2, b2, ..., an, bn]) Please read the bold text twice =)
Code must work as efficiently as possible.
Here is my solution
public static void merge(ArrayList a, ArrayList b) {
ArrayList result = new ArrayList();
int i = 0;
Iterator iter1 = a.iterator();
Iterator iter2 = b.iterator();
while ((iter1.hasNext() || iter2.hasNext()) && i < (a.size() + b.size())) {
if (i % 2 ==0) {
result.add(iter1.next());
} else {
result.add(iter2.next());
}
i++;
}
a = result;
}
I know it's not perfect at all. But I can't understand how to merge in the 1st list without creating tmp list.
Thanks in advance for taking part.
Double ArrayList a's size. Set last two elements of a to the last element of the old a and the last element of b. Keep going, backing up each time, until you reach the beginnings of a and b. You have to do it from the rear because otherwise you will write over the original a's values.
In the end i got this:
public static void merge(ArrayList<Integer> arr1, ArrayList<Integer> arr2) {
int indexForArr1 = arr1.size() - 1;
int oldSize = arr1.size();
int newSize = arr1.size() + arr2.size();
/*
decided not to create new arraylist with new size but just to fill up old one with nulls
*/
fillWithNulls(arr1, newSize);
for(int i = (newSize-1); i >= 0; i--) {
if (i%2 != 0) {
int indexForArr2 = i%oldSize;
arr1.set(i,arr2.get(indexForArr2));
oldSize--; // we reduce the size because we don't need tha last element any more
} else {
arr1.set(i, arr1.get(indexForArr1));
indexForArr1--;
}
}
}
private static void fillWithNulls(ArrayList<Integer> array, int newSize) {
int delta = newSize - array.size();
for(int i = 0; i < delta; i++) {
array.add(null);
}
}
Thanks John again for bright idea!

How to find which value is closest to a number in C?

I have the following code in C:
#define CONST 1200
int a = 900;
int b = 1050;
int c = 1400;
if (A_CLOSEST_TO_CONST) {
// do something
}
What is a convenient way to check whether if a is the closest value to CONST among a,b and c ?
Edit:
It doesn't matter if I have 3 variables or an array like this (it could be more than 3 elements):
int values[3] = {900, 1050, 1400};
This works for three variables:
if (abs(a - CONST) <= abs(b - CONST) && abs(a - CONST) <= abs(c - CONST)) {
// a is the closest
}
This works with an array of one or more elements, where n is the number of elements:
int is_first_closest(int values[], int n) {
int dist = abs(values[0] - CONST);
for (int i = 1; i < n; ++i) {
if (abs(values[i] - CONST) < dist) {
return 0;
}
}
return 1;
}
See it working online: ideone
Compare the absolute value of (a-CONST), (b-CONST) and (c-CONST). Whichever absolute value is lowest, that one is closest.
Here is a generalized method. The min_element() function takes an int array, array size, and pointer to a comparison function. The comparison predicate returns true if the first values is less than the second value. A function that just returned a < b would find the smallest element in the array. The pinouchon() comparison predicate performs your closeness comparison.
#include <stdio.h>
#include <stdlib.h>
#define CONST 1200
int pinouchon(int a, int b)
{
return abs(a - CONST) < abs(b - CONST);
}
int min_element(const int *arr, int size, int(*pred)(int, int))
{
int i, found = arr[0];
for (i = 1; i < size; ++i)
{
if (pred(arr[i], found)) found = arr[i];
}
return found;
}
int main()
{
int values[3] = {900, 1050, 1400};
printf("%d\n", min_element(values, 3, pinouchon));
return 0;
}
I m adding something in Mark Byres code.....
int is_first_closest(int values[]) {
int dist = abs(values[0] - CONST),closest; //calculaing first difference
int size = sizeof( values ) //calculating the size of array
for (int i = 1; i < size; ++i) {
if (abs(values[i] - CONST) < dist) { //checking for closest value
dist=abs(values[i] - CONST); //saving closest value in dist
closest=i; //saving the position of the closest value
}
}
return values[i];
}
This function will take an array of integers and return the number which is closest to the CONST.
You need to compare your constant to every element. (works well for 3 elements but it's a very bad solution for bigger elementcount, in which case i suggest using some sort of divide and conquer method). After you compare it, take their differences, the lowest difference is the one that the const is closest to)
This answer is a reaction to your edit of the original question and your comment.
(Notice that to determine the end of array we could use different approaches, the one i shall use in this particular scenario is the simplest one.)
// I think you need to include math.h for abs() or just implement it yourself.
// The code doesn't deal with duplicates.
// Haven't tried it so there might be a bug lurking somewhere in it.
const int ArraySize = <your array size>;
const int YourConstant = <your constant>;
int values[ArraySize] = { ... <your numbers> ... };
int tempMinimum = abs(YourArray[0] - YourConstant); // The simplest way
for (int i = 1; i < ArraySize; i++) { // Begin with iteration i = 1 since you have your 0th difference computed already.
if (abs(YourArray[i] - YourConstant) < tempMinumum) {
tempMinumum = abs(YourArray[i] - YourConstant);
}
}
// Crude linear approach, not the most efficient.
For a large sorted set, you should be able to use a binary search to find the two numbers which (modulo edge cases) border the number, one of those has to be the closest.
So you would be able to achieve O(Log n) performance instead of O(n).
pseudocode:
closest_value := NULL
closest_distance := MAX_NUMBER
for(value_in_list)
distance := abs(value_in_list - CONST)
if (distance < closest_distance)
closest_value := value_in_list
closest_distance := distance
print closest_value, closest_distance

Cartesian Product of multiple array

I think it is basically an easy problem, but I'm stuck. My brain is blocked by this problem, so I hope you can help me.
I have 2 to N arrays of integers, like
{1,2,3,4,5}
{1,2,3,4,5,6}
{1,3,5}
.....
Now i want to have a list containing arrays of int[N] with every posibillity like
{1,1,1}
{1,1,3}
{1,1,5}
{1,2,1}
....
{1,3,1}
....
{2,1,1}
{2,1,3}
....
{5,6,5}
so there are 6*5*3 (90) elements in it.
Is there a simple algorithm to do it? I think the language didn't matter but I prefer Java.
Thx for the help!
I add a valid answer with the implementation in java for the next guy, who has the same problem. I also do it generic so u can have any CartesianProduct on any Object, not just ints:
public class Product {
#SuppressWarnings("unchecked")
public static <T> List<T[]> getCartesianProduct(T[]... objects){
List<T[]> ret = null;
if (objects != null){
//saves length from first dimension. its the size of T[] of the returned list
int len = objects.length;
//saves all lengthes from second dimension
int[] lenghtes = new int[len];
// arrayIndex
int array = 0;
// saves the sum of returned T[]'s
int lenSum = 1;
for (T[] t: objects){
lenSum *= t.length;
lenghtes[array++] = t.length;
}
//initalize the List with the correct lenght to avoid internal array-copies
ret = new ArrayList<T[]>(lenSum);
//reusable class for instatiation of T[]
Class<T> clazz = (Class<T>) objects[0][0].getClass();
T[] tArray;
//values stores arrayIndexes to get correct values from objects
int[] values = new int[len];
for (int i = 0; i < lenSum; i++){
tArray = (T[])Array.newInstance(clazz, len);
for (int j = 0; j < len; j++){
tArray[j] = objects[j][values[j]];
}
ret.add(tArray);
//value counting:
//increment first value
values[0]++;
for (int v = 0; v < len; v++){
//check if values[v] doesn't exceed array length
if (values[v] == lenghtes[v]){
//set it to null and increment the next one, if not the last
values[v] = 0;
if (v+1 < len){
values[v+1]++;
}
}
}
}
}
return ret;
}
}
As i understand what you want, you need to get all permutations.
Use recursive algorithm, detailed here.
As I see this should work fine:
concatMap (λa -> concatMap (λb -> concatMap (λc -> (a,b,c)) L3) L2) L1
where concatMap(called SelectMany in C#) is defined as
concatMap f l = concat (map f l).
and map maps a function over a list
and concat(sometimes called flatten) takes a List of List and turns it into a flat List

Generating All Permutations of Character Combinations when # of arrays and length of each array are unknown

I'm not sure how to ask my question in a succinct way, so I'll start with examples and expand from there. I am working with VBA, but I think this problem is non language specific and would only require a bright mind that can provide a pseudo code framework. Thanks in advance for the help!
Example:
I have 3 Character Arrays Like So:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
I would like to generate ALL possible permutations of the character arrays like so:
XA1
XA2
XA3
XA4
XB1
XB2
XB3
XB4
YA1
YA2
.
.
.
ZB3
ZB4
This can be easily solved using 3 while loops or for loops. My question is how do I solve for this if the # of arrays is unknown and the length of each array is unknown?
So as an example with 4 character arrays:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
Arr_4 = [a,b]
I would need to generate:
XA1a
XA1b
XA2a
XA2b
XA3a
XA3b
XA4a
XA4b
.
.
.
ZB4a
ZB4b
So the Generalized Example would be:
Arr_1 = [...]
Arr_2 = [...]
Arr_3 = [...]
.
.
.
Arr_x = [...]
Is there a way to structure a function that will generate an unknown number of loops and loop through the length of each array to generate the permutations? Or maybe there's a better way to think about the problem?
Thanks Everyone!
Recursive solution
This is actually the easiest, most straightforward solution. The following is in Java, but it should be instructive:
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
recurse("", arrs, 0);
}
static void recurse (String s, Object[][] arrs, int k) {
if (k == arrs.length) {
System.out.println(s);
} else {
for (Object o : arrs[k]) {
recurse(s + o, arrs, k + 1);
}
}
}
}
(see full output)
Note: Java arrays are 0-based, so k goes from 0..arrs.length-1 during the recursion, until k == arrs.length when it's the end of recursion.
Non-recursive solution
It's also possible to write a non-recursive solution, but frankly this is less intuitive. This is actually very similar to base conversion, e.g. from decimal to hexadecimal; it's a generalized form where each position have their own set of values.
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
int N = 1;
for (Object[] arr : arrs) {
N = N * arr.length;
}
for (int v = 0; v < N; v++) {
System.out.println(decode(arrs, v));
}
}
static String decode(Object[][] arrs, int v) {
String s = "";
for (Object[] arr : arrs) {
int M = arr.length;
s = s + arr[v % M];
v = v / M;
}
return s;
}
}
(see full output)
This produces the tuplets in a different order. If you want to generate them in the same order as the recursive solution, then you iterate through arrs "backward" during decode as follows:
static String decode(Object[][] arrs, int v) {
String s = "";
for (int i = arrs.length - 1; i >= 0; i--) {
int Ni = arrs[i].length;
s = arrs[i][v % Ni] + s;
v = v / Ni;
}
return s;
}
(see full output)
Thanks to #polygenelubricants for the excellent solution.
Here is the Javascript equivalent:
var a=['0'];
var b=['Auto', 'Home'];
var c=['Good'];
var d=['Tommy', 'Hilfiger', '*'];
var attrs = [a, b, c, d];
function recurse (s, attrs, k) {
if(k==attrs.length) {
console.log(s);
} else {
for(var i=0; i<attrs[k].length;i++) {
recurse(s+attrs[k][i], attrs, k+1);
}
}
}
recurse('', attrs, 0);
EDIT: Here's a ruby solution. Its pretty much the same as my other solution below, but assumes your input character arrays are words: So you can type:
% perm.rb ruby is cool
~/bin/perm.rb
#!/usr/bin/env ruby
def perm(args)
peg = Hash[args.collect {|v| [v,0]}]
nperms= 1
args.each { |a| nperms *= a.length }
perms = Array.new(nperms, "")
nperms.times do |p|
args.each { |a| perms[p] += a[peg[a]] }
args.each do |a|
peg[a] += 1
break if peg[a] < a.length
peg[a] = 0
end
end
perms
end
puts perm ARGV
OLD - I have a script to do this in MEL, (Maya's Embedded Language) - I'll try to translate to something C like, but don't expect it to run without a bit of fixing;) It works in Maya though.
First - throw all the arrays together in one long array with delimiters. (I'll leave that to you - because in my system it rips the values out of a UI). So, this means the delimiters will be taking up extra slots: To use your sample data above:
string delimitedArray[] = {"X","Y","Z","|","A","B","|","1","2","3","4","|"};
Of course you can concatenate as many arrays as you like.
string[] getPerms( string delimitedArray[]) {
string result[];
string delimiter("|");
string compactArray[]; // will be the same as delimitedArray, but without the "|" delimiters
int arraySizes[]; // will hold number of vals for each array
int offsets[]; // offsets will holds the indices where each new array starts.
int counters[]; // the values that will increment in the following loops, like pegs in each array
int nPemutations = 1;
int arrSize, offset, nArrays;
// do a prepass to find some information about the structure, and to build the compact array
for (s in delimitedArray) {
if (s == delimiter) {
nPemutations *= arrSize; // arrSize will have been counting elements
arraySizes[nArrays] = arrSize;
counters[nArrays] = 0; // reset the counter
nArrays ++; // nArrays goes up every time we find a new array
offsets.append(offset - arrSize) ; //its here, at the end of an array that we store the offset of this array
arrSize=0;
} else { // its one of the elements, not a delimiter
compactArray.append(s);
arrSize++;
offset++;
}
}
// put a bail out here if you like
if( nPemutations > 256) error("too many permutations " + nPemutations+". max is 256");
// now figure out the permutations
for (p=0;p<nPemutations;p++) {
string perm ="";
// In each array at the position of that array's counter
for (i=0;i<nArrays ;i++) {
int delimitedArrayIndex = counters[i] + offsets[i] ;
// build the string
perm += (compactArray[delimitedArrayIndex]);
}
result.append(perm);
// the interesting bit
// increment the array counters, but in fact the program
// will only get to increment a counter if the previous counter
// reached the end of its array, otherwise we break
for (i = 0; i < nArrays; ++i) {
counters[i] += 1;
if (counters[i] < arraySizes[i])
break;
counters[i] = 0;
}
}
return result;
}
If I understand the question correctly, I think you could put all your arrays into another array, thereby creating a jagged array.
Then, loop through all the arrays in your jagged array creating all the permutations you need.
Does that make sense?
it sounds like you've almost got it figured out already.
What if you put in there one more array, call it, say ArrayHolder , that holds all of your unknown number of arrays of unknown length. Then, you just need another loop, no?

Resources