IntArray.cpp

00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include "IntArray.h"
00019 #include "Error.h"
00020 #include "Hash.h"
00021 #include "Sort.h"
00022 
00023 #include <string.h>
00024 
00025 int IntArray::alloc = 4;
00026 
00027 IntArray::IntArray(int start_size)
00028 {
00029     count = start_size;
00030     size = (count + alloc) / alloc * alloc;
00031     items = new int [size];
00032 }
00033 
00034 IntArray::IntArray(const IntArray & source)
00035 {
00036     count = source.count;
00037     size = source.size;
00038     items = new int [size];
00039 
00040     for (int i = 0; i < count; i++)
00041         items[i] = source.items[i];
00042 }
00043 
00044 IntArray::~IntArray()
00045 {
00046     delete [] items;
00047 }
00048 
00049 void IntArray::Grow(int new_size)
00050 {
00051     if (new_size > size)
00052     {
00053         if ((new_size >> 1) >= size)
00054             size = (new_size + alloc) / alloc * alloc;
00055         else
00056         {
00057             size = alloc;
00058             while (size <= new_size)
00059                 size *= 2;
00060         }
00061 
00062         int * new_items = new int [size];
00063         for (int i = 0; i < count; i++)
00064             new_items[i] = items[i];
00065         delete [] items;
00066         items = new_items;
00067     }
00068 }
00069 
00070 int IntArray::Append(int value)
00071 {
00072     Grow(count + 1);
00073     items[count++] = value;
00074     return count;
00075 }
00076 
00077 int IntArray::Append(const IntArray & rhs)
00078 {
00079     Grow(count + rhs.count);
00080     for (int i = 0; i < rhs.count; i++)
00081         items[count + i] = rhs.items[i];
00082     count += rhs.count;
00083     return count;
00084 }
00085 
00086 void IntArray::Set(int value)
00087 {
00088     for (int i = 0; i < count; i++)
00089         items[i] = value;
00090 }
00091 
00092 void IntArray::SetSequence(int start, int increment)
00093 {
00094     for (int i = 0; i < count; i++, start += increment)
00095         items[i] = start;
00096 }
00097 
00098 int IntArray::Delete(int index)
00099 {
00100     count--;
00101     if (count - index)
00102         memmove(items + index, items + index + 1, sizeof(int) *(count - index));
00103     return count;
00104 }
00105 
00106 void IntArray::InsertAt(int index, int value)
00107 {
00108     Grow(count + 1);
00109     if (count - index)
00110         memmove(items + index + 1, items + index, sizeof(int) *(count - index));
00111     items[index] = value;
00112     count++;
00113 }
00114 
00115 IntArray & IntArray::operator = (const IntArray & rhs)
00116 {
00117     Grow(rhs.count);
00118     count = rhs.count;
00119     for (int i = 0; i < count; i++)
00120         items[i] = rhs.items[i];
00121     return *this;
00122 }
00123 
00124 int IntArray::Sum(int start, int end) const
00125 {
00126     int result = 0;
00127 
00128     for (int i = start; i <= end; i++)
00129         result += items[i];
00130 
00131     return result;
00132 }
00133 
00134 int IntArray::Max(int start, int end) const
00135 {
00136     if (start >= count) return 0;
00137 
00138     int result = items[start];
00139 
00140     for (int i = start + 1; i <= end; i++)
00141         if (result < items[i])
00142             result = items[i];
00143 
00144     return result;
00145 }
00146 
00147 int IntArray::Min(int start, int end) const
00148 {
00149     if (start >= count) return 0;
00150 
00151     int result = items[start];
00152 
00153     for (int i = start + 1; i <= end; i++)
00154         if (result > items[i])
00155             result = items[i];
00156 
00157     return result;
00158 }
00159 
00160 int IntArray::Find(int value) const
00161 {
00162     for (int i = 0; i < count; i++)
00163         if (value == items[i])
00164             return i;
00165     return -1;
00166 }
00167 
00168 int IntArray::BinarySearch(int value) const
00169 {
00170     int start = 0;
00171     int stop = count - 1;
00172 
00173     while (start <= stop)
00174     {
00175         int mid = (start + stop) / 2;
00176 
00177         if (items[mid] == value)
00178             return mid;
00179 
00180         if (items[mid] > value)
00181             stop = mid - 1;
00182         else
00183             start = mid + 1;
00184     }
00185 
00186     return -1;
00187 }
00188 
00189 void IntArray::Zero()
00190 {
00191     for (int i = 0; i < count; i++)
00192         items[i] = 0;
00193 }
00194 
00195 int IntArray::Compare(int * a, int * b)
00196 {
00197     return *a - *b;
00198 }
00199 
00200 void IntArray::Sort()
00201 {
00202     QuickSort(items, count, sizeof(int), COMPAREFUNC Compare);
00203 }
00204 
00205 void IntArray::Sort(IntArray & freeRider)
00206 {
00207     QuickSort2(items, freeRider.items, count, sizeof(int), COMPAREFUNC Compare);
00208 }
00209 
00210 
00211 void IntArray::Reverse()
00212 {
00213     for (int i = 0, j = count - 1; i < j; i++, j--)
00214         Swap(i, j);
00215 }
00216 
00217 int IntArray::CountIfGreater(int threshold) const
00218 {
00219     int result = 0;
00220 
00221     for (int i = 0; i < count; i++)
00222         if (items[i] > threshold)
00223             result++;
00224 
00225     return result;
00226 }
00227 
00228 int IntArray::CountIfGreaterOrEqual(int treshold) const
00229 {
00230     int result = 0;
00231 
00232     for (int i = 0; i < count; i++)
00233         if (items[i] >= treshold)
00234             result++;
00235 
00236     return result;
00237 }
00238 
00239 void IntArray::Add(int term)
00240 {
00241     for (int i = 0; i < count; i++)
00242         items[i] += term;
00243 }
00244 
00245 void IntArray::Multiply(int factor)
00246 {
00247     for (int i = 0; i < count; i++)
00248         items[i] *= factor;
00249 }
00250 
00251 void IntArray::Divide(int denominator)
00252 {
00253     for (int i = 0; i < count; i++)
00254         items[i] /= denominator;
00255 }
00256 
00257 void IntArray::Stack(const IntArray & a)
00258 {
00259     int end = count;
00260 
00261     Dimension(count + a.count);
00262 
00263     for (int i = 0; i < a.count; i++)
00264         items[i + end] = a[i];
00265 }
00266 
00267 bool IntArray::operator == (const IntArray & rhs) const
00268 {
00269     if (count != rhs.count)
00270         return false;
00271 
00272     for (int i = 0; i < rhs.count; i++)
00273         if (items[i] != rhs.items[i])
00274             return false;
00275 
00276     return true;
00277 }
00278 
00279 bool IntArray::operator != (const IntArray & rhs) const
00280 {
00281     return !(*this == rhs);
00282 }
00283 
00284 // Check if all values are in ascending or descending order
00285 //
00286 
00287 bool IntArray::isAscending()
00288 {
00289     for (int i = 1; i < count; i++)
00290         if (items[i] < items[i - 1])
00291             return false;
00292     return true;
00293 }
00294 
00295 bool IntArray::isDescending()
00296 {
00297     for (int i = 1; i < count; i++)
00298         if (items[i] > items[i - 1])
00299             return false;
00300     return true;
00301 }
00302 
00303 void IntArray::Add(const IntArray & v)
00304 {
00305     if (Length() != v.Length())
00306         error("IntArray::Add - vectors have different lengths\n"
00307               "IntArrays     - Left[%d] += Right[%d] ",
00308               Length(), v.Length());
00309 
00310     for (int i = 0; i < Length(); i++)
00311         items[i] += v[i];
00312 }
00313 
00314 int IntArray::InnerProduct(IntArray & v)
00315 {
00316     if (Length() != v.Length())
00317         error("IntArray::InnerProduct - vectors have different dimensions\n"
00318               "IntArrays              - Left[%d] * Right[%d] ",
00319               Length(), v.Length());
00320 
00321     int sum = 0;
00322     for (int i = 0; i < Length(); i++)
00323         sum += items[i] * v[i];
00324 
00325     return sum;
00326 }
00327 
00328 void IntArray::Swap(IntArray & rhs)
00329 {
00330     int * temp = rhs.items;
00331     rhs.items = items;
00332     items = temp;
00333 
00334     int swap = rhs.count;
00335     rhs.count = count;
00336     count = swap;
00337 
00338     swap = rhs.size;
00339     rhs.size = size;
00340     size = swap;
00341 }
00342 
00343 void IntArray::Print(FILE * output)
00344 {
00345     Print(output, "Array of Integers");
00346 }
00347 
00348 void IntArray::Print(FILE * output, const char * label)
00349 {
00350     fprintf(output, "%s [%d elements]: ", label, count);
00351 
00352     for (int i = 0; i < count; i++)
00353         fprintf(output, "%d ", items[i]);
00354 
00355     fprintf(output, "\n");
00356 }
00357 
00358 void IntArray::PushIfNew(int value)
00359 {
00360     for (int i = 0; i < count; i++)
00361         if (items[i] == value)
00362             return;
00363 
00364     Push(value);
00365 }
00366 
00367 int IntArray::Product()
00368 {
00369     int product = 1;
00370 
00371     for (int i = 0; i < count; i++)
00372         product *= items[i];
00373 
00374     return product;
00375 }
00376 
00377 double IntArray::DoubleProduct()
00378 {
00379     double product = 1.0;
00380 
00381     for (int i = 0; i < count; i++)
00382         product *= items[i];
00383 
00384     return product;
00385 }
00386 
00387 int IntArray::Hash(int initval)
00388 {
00389     return hash((unsigned char *) items, sizeof(int) * count, initval);
00390 }
Generated on Wed Nov 17 15:38:29 2010 for StatGen Software by  doxygen 1.6.3