tags:

views:

168

answers:

4

I have two string arrays

string[] input; //user input could be any size
string[] output; //a copy of user input but, should not be larger than 50

if input length <= 50, then output is an exact copy of input.

if input array length > 50 then it will copy only 50 elements from input

It must have the first and last element from input and select the rest evenly; it's not just simply taking the first or last 50 elements.

What's the most efficient way to do this?

UPDATE say input[] has 98 elements. then you would take the first and last elements and then divide the rest by 2 to get 50 elements

98-2=96
96/2=48

2+48=50
+2  A: 

Something like:

public static T[] CopyEvenly<T>(T[] from, int size)
{
    if (from.Length <= size)
    {
        return (T[]) from.Clone();
    }
    T[] ret = new T[size];
    for (int i=0; i < size; i++)
    {
        ret[i] = from[(i * (from.Length + size - 1)) / size];
    }
    return ret;
}

This will fail if you get to the stage where the multiplication overflows an int, admittedly.

Jon Skeet
what is T[]i've never seen it before
T represents generics, which allows the method to be used with different types. So you could pass in an array of strings, ints, etc. For more info do a search on "Generics." Here's the MSDN link: http://msdn.microsoft.com/en-us/library/512aeb7t.aspx
Ahmad Mageed
so is T[] itself a class? or a keyword
T[] is an array of Ts, just like string[] is an array of strings. If you want a string-specific version, just replace "T" with "string" everywhere in the method and remove the <T> bit in the declaration.
Jon Skeet
+2  A: 
for (float i = 0, int count = 0; count < 50; i+= arraySize / 50.0f, count++)
{
output[count] = input[(int)i];
}
McWafflestix
I didn't know you could define multiple variables within the "for" like that.
Greg
Shouldn't it be count < 50 (or i < input.length)
Matthew Flaschen
Edited to fix loop invariant to "count < 50".
McWafflestix
wouldn't this fail when arraySize < 50, resulting in duplicate entries? For example, if arraySize = 15, the increment is 0.3. So (int)0.3, (int)0.6, and (int)0.9 would all result in 0, which means that output[0-2] all have input[0]. Right?
Erich Mirabal
@Erich: yes, this assumes you've already checked that the size is greater than your target count.
McWafflestix
OK. I didn't want to assume any pre-conditions in your code. Nothing was stated about those things, so figure better to point them out since decon2 might not realize that.
Erich Mirabal
A: 

I think you have an approximation problem dealing with int divisions, try to keep it in doubles till you get the index:

static T[] CopyEvenly<T>(T[] source, int size)
{
    if (size >= source.Length)
        // or copy it to a new one if you prefer
        return source;

    T[] ret = new T[size];
    // keep everything in doubles
    double factor = (double)(source.Length - 1) / (double)(size - 1);
    for (int i = 0; i < ret.Length; i++)
    {
        // cast to int just now
        int inputIndex = (int)((double)i * factor);

        ret[i] = source[inputIndex];
    }
    return ret;
}

I hope I understood your answer correctly.

Maghis
A: 

This may be way off, but I thought it would be fun to try. Hope I don't make things more confusing.

static T[] CopyEvenly<T>(T[] srcArray, int size)
{
   int factor=srcArray.Length/size; //this will be the "step" size
   T[] retArray=new T[size];

   int counter = 0;

   //add element 0 and every [factor]'ith element until 1 less than size
   while (counter < size - 1 && counter<srcArray.Length)
   {
      retArray[counter] = srcArray[counter * factor];
      counter++;
   }

   //add the last element
   retArray[size] = srcArray[srcArray.Length - 1];

   return retArray;
}
dsrekab