C++ check array for duplicates and replace them - c++

i have an array full of values, the array can not contain any duplicate values. for any duplicate value add one to the value. here is the code i have so far, but im still getting duplicates. (randArray is where the values are located).
for (int i = 0; i < sizeof(randArray) - 1; i++) {
for (int j = sizeof(randArray); j == 0; j--) {
if (randArray[i] == randArray[j]) {
randArray[i] == randArray[i] + 1;
}
}
}

You have a typo when incrementing a duplicate:
randArray[i] = randArray[i] + 1; // not ==
Also, the increment might create another duplicate. If it's with an item that comes afterwards there's no problem. But as the array is not sorted, you might not catch such a new duplicate of a value already passed.
Therefore you might need several passes:
bool wasaninc;
do {
wasaninc=false;
for ...
for ...
... // if there is an increment, set wasaninc to true
} while (wasaninc);

Change randArray[i] == randArray[i] + 1; to randArray[i] = randArray[i] + 1;
for (int i = 0; i < sizeof(randArray) - 1; i++) {
for (int j = sizeof(randArray); j == 0; j--) {
if (randArray[i] == randArray[j]) {
randArray[i] = randArray[i] + 1;
}
}
}

Your problem is due to sizeof(randArray). This method doesn't return the number of elements that are in the array.
For example:
int array[5] = { 1, 2, 3, 4, 5};
sizeof(array); // -> returns 20, because of 5 * 4 bytes (integer = 4 bytes)
Instead of using this method you should actually use the number of elements in the array. You declared the size of the array already in the beginning. So it is clear how many elements can be in the array.
Correct example:
int array[100] = {...};
for (int i = 0; i < 99; i++) {
for (int j = 0; j < 99; j++) {
if (array[i] == array[j]) {
// code for duplicates
}
}
}

#include <iostream>
#include <unistd.h>
#include <algorithm>
using namespace std;
int main()
{
int arr[8]={0,1,1};
int n = sizeof(arr) / sizeof(arr[0]);
cout<<n<<"\n";
/*Here we take two parameters, the beginning of the
array and the length n upto which we want the array to
be sorted*/
//sort(arr, arr + n);
for (int i=0;i<=n;i++){
cout<<arr[i]<<" ";
}
int result=0;
do{
for (int i=0;i<=n;i++){
for (int j =0;j<i;j++){
if(arr[j]==arr[i]){
srand(time(NULL)); // Seed the time
int finalNum = rand()%((10-1)+1); // Generate the number, assign to variable.
arr[i] = finalNum;
result = result + 1;
sleep(1);
i--;
}
}
}
}
while(result<=2);
n = sizeof(arr) / sizeof(arr[0]);
/*Here we take two parameters, the beginning of the
array and the length n upto which we want the array to
be sorted*/
//sort(arr, arr + n);
cout<<"\n";
for (int i=0;i<=n;i++){
cout<<arr[i]<<" ";
}
return 0;
}

(I'm assuming that randArray is a C-style array.) sizeof(randArray) does not return the number of elements in the array, it returns the number of bytes that randArray occupies.
Example (on wandbox):
int main()
{
int arr[] = {1, 2, 3, 4};
// Prints 16! (on my machine)
std::cout << sizeof(arr) << "\n";
}
The correct way of working with arrays in modern C++ is either using std::array or std::vector. They both provide a .size() method that returns the number of elements in the collection.
Your code is failing for these reasons:
sizeof does not return the number of elements in the array.
Incrementing a duplicate element by one does not guarantee that it will be unique.

Related

Removing odd numbers from an array

I am trying to remove odd numbers from an array, but I'm not allowed to create a new array to store the new values.
So, if I have arr[1,2,3,4,5,6,7,8,9]
then I need it to be arr[2,4,6,8] so that arr[0] will be 2 and not 1.
I can't seem to be able to drop the even numbers without creating a new array to store the values and then feed it back into the original array with the new values.
I have tried to make arr[i] = 0 if its an odd number but then I wasn't able to drop the 0 and replace it with the next even number.
So far, I have this:
void removeOdd(int arr[], int& arrSize){
int i, j = 0;
int temp;
int newArrSize;
for(i = 0, newArrSize = arrSize; i < arrSize; i++){
if(arr[i] % 2 != 0){
arr[i] = 0;
}
}
arrSize = newArrSize;
}
// Moves all even numbers into the beginning of the array in their original order
int removeOdd(int arr[], int arrSize) {
int curr = 0; // keep track of current position to insert next even number into
for (int i = 0; i < arrSize; ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
return curr;
}
int main() {
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int newSize = removeOdd(arr, 10);
for (int i = 0; i < newSize; ++i) {
std::cout << arr[i] << " ";
}
}
0 2 4 6 8
You might want to use std::vector:
void removeOdd(std::vector<int>& arr) {
int curr = 0;
for (int i = 0; i < (int)arr.size(); ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
arr.resize(curr);
}
int main() {
std::vector<int> arr = { 0,1,2,3,4,5,6,7,8,9 };
removeOdd(arr);
for (int number : arr) {
std::cout << number << " ";
}
}
Normally (unless this is homework of some sort), you should use the algorithms in the <algorithm> header.
Using std::remove_if with std::vector's erase member function, you will accomplish exactly what you want with less code:
std::vector<int> vec{ 1,2,3,4,5,6,7,8,10 };
vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](auto const& i) {
return i % 2 != 0;
}), std::end(vec));
Demo

removing and shifting duplicates in array c++

I am trying to delete any duplicates but not having much success..
void deleatingRepeatingElement (int myArrayLength, int myArray[])
{
for (int i = 1 ; i < myArrayLength; i++){
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i ; j++){
if (myArray[i] == myArray[j]){
myArray[j] = myArray[j + 1];
myArrayLength--;
}
}
}
}
I think there were two main mistakes:
You didn't shift all of the following items when deleting.
You didn't "reset" after deleting.
Here is annotated code that seems to work:
#include <iostream>
/* Remove element at given index from array
* Returns the new array length
* (Note that "int array[]" means exactly the same as "int *array",
* so some people would consider "int *array" better style)
*/
int arrayRemoveAt(int index, int array[], int arrayLength)
{
// Check whether index is in range
if (index < 0 || index >= arrayLength)
return arrayLength;
for (int i = index + 1; i < arrayLength; i++)
{
array[i - 1] = array[i];
}
return arrayLength - 1;
}
/*
* Returns the new length of the array
*/
int deleatingRepeatingElement(int myArrayLength, int myArray[])
{
for (int i = 1; i < myArrayLength; i++)
{
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i; j++)
{
if (myArray[i] == myArray[j])
{
myArrayLength = arrayRemoveAt(i, myArray, myArrayLength);
// After deleting an entry, we must "reset", because now the index i
// might point to another number, which may be a duplicate
// of a number even before the current j.
// The i-- is so that after i++, we will end up with the same i
i--;
break;
}
}
}
// Important: The caller needs this for looping over the array
return myArrayLength;
}
int main(int argc, char **argv)
{
int array[] = {5, 6, 2, 1, 2, 6, 6};
int newSize = deleatingRepeatingElement(7, array);
for (int i = 0; i < newSize; i++)
{
std::cout << array[i] << std::endl;
}
return 0;
}
If you use a static array (such as in my example, as opposed to a dynamic one), you may consider using std::array or a template construction as shown in https://stackoverflow.com/a/31346972/5420386.
Here is the solution to your problem:
#include <iostream>
#include <set>
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))
using namespace std;
int *deleteRepeatedElements(int myArray[], int arrayLength) {
set<int> setArray (myArray, myArray+arrayLength);
int setLength = setArray.size();
static int myPointer[4];
int i = 0;
for (set<int>::iterator it = setArray.begin(); it != setArray.end(); ++it) {
myPointer[i] = *it;
i++;
}
return myPointer;
}
int main() {
int myArray[6] = {5, 3, 5, 6, 2, 4};
int arrayLength = ARRAY_SIZE(myArray);
int* myPointer = deleteRepeatedElements(myArray, arrayLength);
int pointerLength = sizeof(myPointer)/sizeof(*myPointer);
for (int* i = &myPointer[0]; *myPointer != 0; i = ++myPointer) {
cout << *i << " ";
}
cout << '\n';
return 0;
}

How to generate all n-digit number in the n-digit-array way?

I know how to generate all n-digit number in the traditional number way,
for(long long number = pow(10, n-1); number < pow(10, n); number++) {
cout << number << endl;
}
for example,
for n = 5, it will generate 10000 to 99999;
However, since I will have to evaluate each number's digits, it is much convenient to construct the numbers in a digit array format in the first place.
for example, following code generate all 5-digit number in an array way:
for(int i = 1; i < 9; i++)
for(int j = 0; j < 9; j++)
for(int k = 0; k < 9; k++)
for(int l = 0; l < 9; l++)
for(int m = 0; m < 9; m++) {
//executed 9 * 10^4 = 90000 times
//construct my array instance with i, j, k, l, m
cout << i << j << k << l << m << endl;
}
Now the problem is: n is unknown. (for example, it could be 2, 3, 4, 5, 6..., 10)
Then how can I generate n-digit-array based on a number n?
For example, I want a piece of code like follows (any better ways than this one is highly appreciated):
for(int x = 0; x < n; x++) {
//each x is a layer of the loop ?!
.....
}
There is no reason to limit ourselves to the range 0 - 9 for each digit of the number.
For each numerical place, we'll represent a range:
std::pair<int,int> range;
Each loop in your example is iterating from the beginning of the range to the end of the range.
All the loops together are really just a series of ranges; each nested loop being responsible for the next digit of your generated number.
We can represent that, in the following way:
std::vector<std::pair<int, int>> ranges;
If you think about how nested for loops work, you can emulate the same functionality over the vector using two pointers. I've done that and wrapped the functionality into a class:
//header
class Range_Combinator {
public:
Range_Combinator(std::vector<std::pair<int, int>> const &ranges_in);
std::vector<int> Next();
std::vector<int> Current();
bool Done();
private:
bool Adjust();
void Reset_From_Current_Back(int from);
std::vector<std::pair<int, int>> ranges;
int current;
int last;
bool all_exausted;
std::vector<int> current_vals;
};
//source
Range_Combinator::Range_Combinator(
std::vector<std::pair<int, int>> const &ranges_in) {
ranges = ranges_in;
last = ranges.size() - 1;
current = last;
all_exausted = false;
for (auto it : ranges) {
current_vals.push_back(it.first);
}
}
std::vector<int> Range_Combinator::Next() {
all_exausted = Adjust();
return current_vals;
}
std::vector<int> Range_Combinator::Current() { return current_vals; }
bool Range_Combinator::Done() { return all_exausted; }
bool Range_Combinator::Adjust() {
if (current_vals[current] < ranges[current].second) {
current_vals[current]++;
} else {
while (current_vals[current] == ranges[current].second) {
current--;
}
if (current < 0) {
return true;
}
Reset_From_Current_Back(current + 1);
current_vals[current]++;
current = last;
}
return false;
}
void Range_Combinator::Reset_From_Current_Back(int from) {
for (int i = from; i <= last; ++i) {
current_vals[i] = ranges[i].first;
}
}
This is how you would use it:
//create range combinator
std::vector<std::pair<int,int>> ranges{{1,2},{3,4}};
Range_Combinator r(ranges);
//print each number
auto number = r.Current();
while (!r.Done()){
for (auto it: number) std::cout << it; std::cout << '\n';
number = r.Next();
}
//prints: 13
// 14
// 23
// 24
I don't know why you need that but you can try this:
size_t n = ; //whatever value
unsigned char* x = new unsigned char[n]();
x[0] = 1; //make it n-digit 10000...000
do
{
//process digits here
++x[n - 1];
for (size_t i = n; i > 1; --i)
{
if (x[i - 1] == 10)
{
x[i - 1] = 0;
++x[i - 2];
}
}
} while (x[0] < 10);
delete [] x;
You can even process not decimal numbers, just replace hard-coded 10 into appropriate number.
I suppose I could just write out the whole thing for you, but that would be no fun. Instead, I'll just outline the basic approach, and you can finish the answer yourself by filling in the blanks.
Consider an n-digit long number being represented this way:
struct digit {
struct digit *next;
int n; /* Digit 0-9 */
};
A single number represented, in this manner, can be printed out this way:
void print_digit(struct digit *p)
{
while (p)
{
std::cout << p->n;
p=p->next;
}
std::cout << std::endl;
}
Now, let's create a recursive loop, that iterates over all possible n-digit numbers:
void iterate(int ndigits)
{
for (int i=0; i<10; ++i)
{
if (ndigits > 1)
{
iterate(ndigits-1);
}
else
{ // This is the last digit
// Here be dragons
}
}
}
After a bit of thinking, you can see that if, for example, you call iterate(4), then when the "hear be dragons" part gets executed, this will be inside a four-deep nested iteration stack. There will be four level-deep for loops, nested within each other. And, with iterate(6), there will be six of them, and so on.
Now, consider the fact that the struct digit-based representation of n-digit numbers is also a stack, of sorts.
Therefore, the homework assignment here would be to use this recursive iteration to dynamically construct this linked list, on the stack, with the "here be dragons" part simply invoking print_digit() in order to print each number.
Hint: iterate() will need to have a few more parameters, that it will use appropriately, with a certain preset value for them, on the initial call to iterate().
A simple way without thinking of efficiency:
#include <cstdio>
int main(void) {
int n = 3; // the number of digits
long long start = 1;
int *array = new int[n];
for (int i = 1; i < n; i++) start *= 10;
for(long long x = start; x < start * 10; x++) { // not all 10-digit number will fit in 32-bit integer
// get each digits in decimal, lowest digit in array[0]
for (int i = 0, shift = 1; i < n; i++, shift *= 10) array[i] = (int)((x / shift) % 10);
// do some work with it (print it here)
for (int i = n - 1; i >= 0; i--) printf("%d", array[i]);
putchar('\n');
}
delete[] array;
return 0;
}

Prime Factoring, no IO

Dear StackOverflow community,
I am trying to write code that accepts a "primefactorized" array, each element originally describing their final multiplicational product.
The code I'm trying to write then reads this array and turns it to the exponentiation of prime numbers, each index of the array corresponding to the next prime number, and each element on the index the power to which it must be raised. I believe I have done so, but I cannot for some reason get my IO working. For some reason when I switched the inner for-loops last incrementation part to an "i++" instead of the correct "j++", it would display the loop.
Relevant snippet
// Next stage: Take the array and turn in into the form described earlier
for(unsigned int i = 0; i < sizeof(result); i++)
{
temppower = result[i];
tempcounter = 1; // counter to control the loop.
for(unsigned int j = 0; i < sizeof(result)-1; j++)
{
if(result[j]+1 == temppower)
{
tempcounter++;
result[j+1] = 0;
}
}
result[i] = tempcounter;
}
for(unsigned int i = 0; i < sizeof(result); i++)
{
cout << result[i] << " ";
}
cout << endl;
Full code
#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
#include "fact.h"
/** eartosthenes constructs an up-to-n primes array of length len .
* #param n call-by-value, top value for construction of primes.
* #param &len call-by-reference, the finished size of the array of primes.
* #return int* pointer to the first element of the array of primes.
* Description:
* The eartosthenes method of calculating primes are efficient for relative low primes (up to 10 million or so).
* You can read about the method at http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
* You can use wolfram-alpha https://www.wolframalpha.com/ and run Prime(start)...Prime(end) to get the primes
* between start and end, e.g. Prime(1)...Prime(10) yield {2,3,5,7,11,13,17,19,23,29}.
*/
int * eratosthenes(int n, int & len){
// computes all prime numbers up to n
// returns the prime numbers as an array
// the len parameter will be set to the length of the array
bool *isPrime=new bool [n+1]; // construct [n+1] booleans
len=0;
// initialize every value from 1..n to true.
for(int i=2; i<=n; i++){
isPrime[i]=true;
}
// now we'll start at 2, and for every number of multiplicity 2.
// e.g. 2*{1,2,3,4...n} is then set to false, as they are dividable by 2.
// then we increment to 3, during the same.
for(int i=2; i<=n; i++){
if(isPrime[i]){
len++; // for each such iteration, we increase our desired length.
for(int j=2*i; j<=n; j+=i){
isPrime[j]=false; // set every(n) multiplicity of 2 to false.
}
}
}
// having used erathosthenes formula, we now construct our array.
int *result=new int[len];
// now we need to return the primes-filled array.
for(int i=0, j=2; i<len; i++){
// if it's not a prime, then we spin the value up.
while(!isPrime[j]) j++;
// when the while-loop no longer hold, we'll have the iterations desired prime
// we then set it, and the for-loop will continue to the next.
result[i]=j++;
}
delete [] isPrime; // always delete what you have allocated with new.
// we say these allocation are on the heap or free store (c-syntax)
return result;
}
#include "fact.h"
factrep new_factrep()
{
factrep result;
result = new int[len];
return result;
}
factrep primfact(int n)
{
factrep result;
result = new int[len];
int m; // still to factorize number
int f; // current factor
int index = 0; // index of factrep array
int temppower = 0; // index for the power
int tempcounter = 0; // counter to help the power determine its size
m=n;
f=2;
// 0-initialize the result array
for(unsigned int i = 0; i < sizeof(result); i++)
{
result[i] = 0;
}
// continue until nothing to factorize
while(m != 1){
// while the factor divides m, go on
while(m % f == 0){
if(m!=1)
{
m=m/f;
result[index] = f;
index++;
}
else
{
result[index] = f;
break;
}
}
// increment factor
f++;
}
// Next stage: Take the array and turn in into the form described within
// the exercise handout,
for(unsigned int i = 0; i < sizeof(result); i++)
{
temppower = result[i];
tempcounter = 1; // counter to control the loop.
for(unsigned int j = 0; i < sizeof(result)-1; j++)
{
if(result[j]+1 == temppower)
{
tempcounter++;
result[j+1] = 0;
}
}
result[i] = tempcounter;
}
for(unsigned int i = 0; i < sizeof(result); i++)
{
cout << result[i] << " ";
}
cout << endl;
return result;
}
factrep mult(factrep f1, factrep f2)
{
factrep result;
result = new int[len];
for(int i = 0; i < len; i++)
{
result[i] = f1[i]+f2[i];
}
return result;
}
int getint(factrep f)
{
int result = 0;
// int *temparray = new int[len];
for(int i = 0; i < len; i++)
{
result *= pow(primes[i],f[i]);
}
return result;
}
// these are our global variables
// so in our header we called extern
// which basically tells c++, that we'll define them in another file.
int *primes;
int len;
int main(){
// construct our primes array with maximum integer value
primes=eratosthenes(sqrt(INT_MAX),len);
// len now contains the length of the primes.
// TEST VALUES
// these are our test values.
int n=60;
int m=25;
int l=640;
// first check for non-negative content
if ( n < 0 || m < 0 || l < 0){
cout << "values must be positive (n > 0)" << endl;
return 1;
}
// construct 3 prime-factorized arrays by the values (60,25,640)
factrep fn=primfact(n);
factrep fm=primfact(m);
factrep fl=primfact(l);
// Verify that these are indeed constructed with those values
cout << getint(fn) << " " << getint(fm) << " " << getint(fl) << endl;
// multiply: fn = fn*fm, fm = fl*fl, fl = fn*fm
// 1500 = 60*25, 409600 = 640*640, 614400000 = 1500*409600
fn=mult(fn,fm);
fm=mult(fl,fl);
fl=mult(fn,fm);
// Verify that our functions work as expected by printing out their values now.
cout << getint(fn) << " " << getint(fm) << " " << getint(fl) << endl;
/* Expected output:
60 25 640
1500 409600 614400000
*/
// and again, if we construct something on the heap/free-store we better delete it again
// otherwise we might have a memory-leak on our hands.
delete [] primes;
delete [] fn;
delete [] fm;
delete [] fl;
return 0;
}
Update
The error was pointed out to me: I had put an i variable reference within the inner-most loop instead of the j variable I was using. (facepalm).
In the meantime this realization quickly helped me to solve my original problem which I will paste below in case anyone might run into a similar problem (primes[] is an array of primes, one per element, established outside of the factrep functions)
for(unsigned int i = 0; i < sizeof(result); i++)
{
temppower = primes[i];
tempcounter = 0; // counter to control the loop.
for(unsigned int j = 0; j < sizeof(result); j++)
{
if(result[j] == temppower)
{
tempcounter++;
}
}
result[i] = tempcounter;
}
Line 116 : A loop is endless.
for(unsigned int j = 0; i < sizeof(result)-1; j++)
i never changes in the inner loop where j is increasing, thus preventing your program from advancing further and printing anything.

How does one rank an array (sort) by value? *With a twist*

I would like to sort an array in ascending order using C/C++. The outcome is an array containing element indexes. Each index is corespondent to the element location in the sorted array.
Example
Input: 1, 3, 4, 9, 6
Output: 1, 2, 3, 5, 4
Edit: I am using shell sort procedure. The duplicate value indexes are arbitrarily chosen based on which duplicate values are first in the original array.
Update:
Despite my best efforts, I haven't been able to implement a sorting algorithm for an array of pointers. The current example won't compile.
Could someone please tell me what's wrong?
I'd very much appreciate some help!
void SortArray(int ** pArray, int ArrayLength)
{
int i, j, flag = 1; // set flag to 1 to begin initial pass
int * temp; // holding variable orig with no *
for (i = 1; (i <= ArrayLength) && flag; i++)
{
flag = 0;
for (j = 0; j < (ArrayLength - 1); j++)
{
if (*pArray[j + 1] > *pArray[j]) // ascending order simply changes to <
{
&temp = &pArray[j]; // swap elements
&pArray[j] = &pArray[j + 1]; //the problem lies somewhere in here
&pArray[j + 1] = &temp;
flag = 1; // indicates that a swap occurred.
}
}
}
};
Since you're using C++, I would do it something like this. The SortIntPointers function can be any sort algorithm, the important part is that it sorts the array of pointers based on the int that they are pointing to. Once that is done, you can go through the array of pointers and assign their sorted index which will end up in the original position in the original array.
int* intArray; // set somewhere else
int arrayLen; // set somewhere else
int** pintArray = new int*[arrayLen];
for(int i = 0; i < arrayLen; ++i)
{
pintArray[i] = &intArray[i];
}
// This function sorts the pointers according to the values they
// point to. In effect, it sorts intArray without losing the positional
// information.
SortIntPointers(pintArray, arrayLen);
// Dereference the pointers and assign their sorted position.
for(int i = 0; i < arrayLen; ++i)
{
*pintArray[i] = i;
}
Hopefully that's clear enough.
Ok, here is my atempt in C++
#include <iostream>
#include <algorithm>
struct mycomparison
{
bool operator() (int* lhs, int* rhs) {return (*lhs) < (*rhs);}
};
int main(int argc, char* argv[])
{
int myarray[] = {1, 3, 6, 2, 4, 9, 5, 12, 10};
const size_t size = sizeof(myarray) / sizeof(myarray[0]);
int *arrayofpointers[size];
for(int i = 0; i < size; ++i)
{
arrayofpointers[i] = myarray + i;
}
std::sort(arrayofpointers, arrayofpointers + size, mycomparison());
for(int i = 0; i < size; ++i)
{
*arrayofpointers[i] = i + 1;
}
for(int i = 0; i < size; ++i)
{
std::cout << myarray[i] << " ";
}
std::cout << std::endl;
return 0;
}
create a new array with increasing values from 0 to n-1 (where n is the length of the array you want to sort). Then sort the new array based on the values in the old array indexed by the values in the new array.
For example, if you use bubble sort (easy to explain), then instead of comparing the values in the new array, you compare the values in the old array at the position indexed by a value in the new array:
function bubbleRank(A){
var B = new Array();
for(var i=0; i<A.length; i++){
B[i] = i;
}
do{
swapped = false;
for(var i=0; i<A.length; i++){
if(A[B[i]] > A[B[i+1]]){
var temp = B[i];
B[i] = B[i+1];
B[i+1] = temp;
swapped = true;
}
}
}while(swapped);
return B;
}
create a new Array and use bubble sort to rank the elements
int arr[n];
int rank[n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(arr[i]>arr[j])
rank[i]++;
The rank of each element will be rank[i]+1 to be in the order of 1,2,....n
Well, there's a trival n^2 solution.
In python:
newArray = sorted(oldArray)
blankArray = [0] * len(oldArray)
for i in xrange(len(newArray)):
dex = oldArray.index(newArray[i])
blankArray[dex] = i
Depending on how large your list is, this may work. If your list is very long, you'll need to do some strange parallel array sorting, which doesn't look like much fun and is a quick way to introduce extra bugs in your code.
Also note that the above code assumes unique values in oldArray. If that's not the case, you'll need to do some post processing to solve tied values.
Parallel sorting of vector using boost::lambda...
std::vector<int> intVector;
std::vector<int> rank;
// set up values according to your example...
intVector.push_back( 1 );
intVector.push_back( 3 );
intVector.push_back( 4 );
intVector.push_back( 9 );
intVector.push_back( 6 );
for( int i = 0; i < intVector.size(); ++i )
{
rank.push_back( i );
}
using namespace boost::lambda;
std::sort(
rank.begin(), rank.end(),
var( intVector )[ _1 ] < var( intVector )[ _2 ]
);
//... and because you wanted to replace the values of the original with
// their rank
intVector = rank;
Note: I used vectorS instead of arrays because it is clearer/easier, also, I used C-style indexing which starts counting from 0, not 1.
This is a solution in c language
#include <stdio.h>
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
/* Function to print an array */
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 98};
int arr_original[] = {64, 34, 25, 12, 22, 11, 98};
int rank[7];
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
//PLACE RANK
//look for location of number in original array
//place the location in rank array
int counter = 1;
for (int k = 0; k < n; k++){
for (int i = 0; i < n; i++){
printf("Checking..%d\n", i);
if (arr_original[i] == arr[k]){
rank[i] = counter;
counter++;
printf("Found..%d\n", i);
}
}
}
printf("Original array: \n");
printArray(arr_original, n);
printf("Rank array: \n");
printArray(rank, n);
return 0;
}