Tuesday, July 16, 2013

Arrays and Indexers in C++/CLI



Today's post is about Arrays and Indexers in C++/CLI. Here below you will find a very easy to follow program, that demonstrate arrays and indexer, by implementing some simple tasks that will make you grasp the idea of those 2 features real quick. The main goal of this post, is not really teaching arrays because, come on, you probably already know "all" about them, in fact, it is more to show you how you do that in C++/CLI, in this case, compared to all other 22 languages on future posts, which essentially, is the real aim behind this blog.

By the way, if you missed my most recent post, "New Series - Arrays and Indexers", check it out. It has more details about the following program, and a bunch of definitions for the concepts used on this, and the following, posts. Or you can check my previous posts about arrays in C#, VB.NET and Oxygene just to compare.

I encourage you to copy the code below and try it yourself, normally, all programs you find in this blog are source code complete, just paste it on your IDE and run it.

Last thing. There is room for improvement of the code, using generics is one example, but Generics, Collections, lambdas, etc. will have their own "series" of posts.

// CppArrays.cpp : main project file.

#include "stdafx.h"

using namespace System;

namespace CppArrays {

    static array<wchar_t>^ ReverseChar(array<wchar_t>^ arr) {
        array<wchar_t>^ reversed = gcnew array<wchar_t>(arr->Length);
        for (int i = 0, j = arr->Length - 1; j >= 0; i++, j--) {
            reversed[i] = arr[i];
        }
        return reversed;
    }

    static array<int>^ BubbleSortInt(array<int>^ arr)  {  
        int swap = 0;  
        for (int i = arr->Length - 1; i > 0; i--) {  
            for (int j = 0; j < i; j++) {  
                if (arr[j] > arr[j + 1]) {  
                    swap = arr[j];  
                    arr[j] = arr[j + 1];  
                    arr[j + 1] = swap;  
                }  
            }  
        }  
        return arr;  
    }  

    static array<String^>^ BubbleSortString(array<String^>^ arr) {  
        String^ swap = L"";  
        for (int i = arr->Length - 1; i > 0; i--) {  
            for (int j = 0; j < i; j++) {  
                if (arr[j][0] > arr[j + 1][0]) {  
                    swap = arr[j];  
                    arr[j] = arr[j + 1];  
                    arr[j + 1] = swap;  
                }  
            }  
        }  
        return arr;  
    }  

    static array<int, 2>^ TransposeMatrix(array<int, 2>^ m) {  
        /* Transposing a Matrix 2,3  
            *  
            * A =  [6  4 24]T [ 6  1]  
            *      [1 -9  8]  [ 4 -9] 
            *                 [24  8] 
        */  
        array<int, 2>^ transposed = gcnew array<int, 2>(m->GetUpperBound(1) + 1,  
                                                        m->GetUpperBound(0) + 1);  
        for (int i = 0; i < m->GetUpperBound(0) + 1; i++) {  
            for (int j = 0; j < m->GetUpperBound(1) + 1; j++) {  
                transposed[j, i] = m[i, j];  
            }  
        }  
        return transposed;  
    }  

    static void UpperCaseRandomArray(array<array<String^>^>^ arr) {  
        Random^ r = gcnew Random();
        int i = r->Next(0, arr->Length - 1);  
        for (int j = 0; j <= arr[i]->Length - 1; j++)  
            arr[i][j] = arr[i][j]->ToUpper();  
    }  

    static void PrintArrayChar(array<wchar_t>^ arr) {  
        Console::WriteLine(L"\nPrint Array Content {0}",  
            arr->GetType()->Name->Replace(L"]", arr->Length.ToString() + L"]"));  
  
        for (int i = 0; i <= arr->Length - 1; i++)  
            Console::WriteLine(L" array [{0,2}] = {1,2} ", i, arr[i]);  
    }  

    static void PrintArrayInt(array<int>^ arr) {  
        Console::WriteLine(L"\nPrint Array Content {0}",  
            arr->GetType()->Name->Replace(L"]", arr->Length.ToString() + L"]"));  
  
        for (int i = 0; i <= arr->Length - 1; i++)  
            Console::WriteLine(L" array [{0,2}] = {1,2} ", i, arr[i]);  
    }  

    static void PrintArrayString(array<String^>^ arr) {  
        Console::WriteLine(L"\nPrint Array Content {0}",  
            arr->GetType()->Name->Replace(L"]", arr->Length.ToString() + L"]"));  
  
        for (int i = 0; i <= arr->Length - 1; i++)  
            Console::WriteLine(L" array [{0,2}] = {1,2} ", i, arr[i]);  
    }  
  
    static void PrintMatrix(array<int, 2>^ m) {  
        Console::WriteLine(L"\nPrint Matrix Content {0}[{1},{2}]",  
            m->GetType()->Name->Replace(L"[,]", L""),  
            (m->GetUpperBound(0) + 1).ToString(),  
            (m->GetUpperBound(1) + 1).ToString());  
  
        for (int i = 0; i <= m->GetUpperBound(0); i++)  
            for (int j = 0; j <= m->GetUpperBound(1); j++)  
                Console::WriteLine(L" array [{0,2},{1,2}] = {2,2} ", i, j, m[i, j]);  
    }  

    static void GraphJaggedArray(array<array<String^>^>^ arr) {  
        /* When using Arrays, we can use foreach instead of for:  
            *  
            * for (int i = 0; i <= arr.Length - 1; i++) 
            *   for (int j = 0; j <= arr.Length - 1; j++)                 
            *  
        */  
        Console::WriteLine(L"\nPrint Text Content {0}", arr->GetType()->Name);  
        int lineCount = 1;  
        for each (array<String^>^ s in arr) {  
            Console::Write(L"Line{0,2}|", lineCount);  
            for each(String^ w in s) {  
                Console::Write(L"{0,3}", L'*');  
            }  
            Console::WriteLine(L" ({0})", s->Length);  
            lineCount++;  
        }  
    }  

    static void PrintJaggedArray(array<array<String^>^>^ arr) {  
        System::Text::StringBuilder^ line;  
        Console::WriteLine(L"\nPrint Jagged Array Content {0}", arr->GetType()->Name);  
        for (int i = 0; i <= arr->Length - 1; i++) {  
            line = gcnew System::Text::StringBuilder();  
            for (int j = 0; j <= arr[i]->Length - 1; j++)  
                line->Append(L" " + arr[i][j]);  
            if (line->ToString() == line->ToString()->ToUpper())  
                line->Append(L" <-- [UPPERCASED]");  
            Console::WriteLine(line);  
        }  
    }  

    static void PrintCommonArrayExceptions(array<array<String^>^>^ arr) {  
        try {  
            arr[100][100] = L"hola";  
        }  
        catch (Exception^ ex) {  
            Console::WriteLine(L"\nException: \n{0}\n{1}", 
                               ex->GetType()->Name, ex->Message);  
        }  
    }  

    static void PrintTitle(String ^message) {
        Console::WriteLine();
        Console::WriteLine(L"======================================================");  
        Console::WriteLine(L"{0,10}", message);  
        Console::WriteLine(L"======================================================");  
    }

    ref class Alphabet {        
    private:
        // Array Field  
        array<wchar_t>^ letters;  
    public:
        // Indexer Get/Set Property   
        property wchar_t default[int] {
            wchar_t get(int index) { return letters[index]; }
            void set(int index, wchar_t value) { letters[index] = Char::ToUpper(value);}
        }
        // Read-Only Property
        property int Length {
            int get() { return this->letters->Length; }
        }        
        // Constructors  
        Alphabet(int size) {  
            this->letters = gcnew array<wchar_t>(size);  
        }  
        Alphabet(String^ list) {  
            this->letters = list->ToUpper()->ToCharArray();  
        }    
        Alphabet(array<wchar_t>^ list) {  
            this->letters = list;  
        }  
        // Overridden Method
        virtual String^ ToString() override {
            return String::Join(L",", gcnew String(this->letters));
        }
        // Method  
        array<wchar_t>^ Slice(int start, int length) {  
            array<wchar_t>^ result = gcnew array<wchar_t>(length);  
            for (int i = 0, j = start; i < length; i++, j++) {  
                result[i] = this[j];  
            }  
            return result;  
        }  
    };
};

using namespace CppArrays;

int main(array<System::String ^> ^args)
{
    // Single-dimensional Array(s)  
    PrintTitle(L"Reverse Array Elements");  
  
    // Declare and Initialize Array of Chars  
    array<wchar_t>^ letters = gcnew array<wchar_t>(5);  
    letters[0] = L'A';  
    letters[1] = L'E';  
    letters[2] = L'I';  
    letters[3] = L'O';  
    letters[4] = L'U';  
  
    PrintArrayChar(letters);  
    array<wchar_t>^ inverse_letters = ReverseChar(letters);  
    PrintArrayChar(inverse_letters);  
  
    PrintTitle(L"Sort Integer Array Elements");  
  
    // Declare and Initialize Array of Integers   
    array<int>^ numbers = { 10, 8, 3, 1, 5 };  
    PrintArrayInt(numbers);  
    array<int>^ ordered_numbers = BubbleSortInt(numbers);  
    PrintArrayInt(ordered_numbers);  
  
    PrintTitle(L"Sort String Array Elements");  

    // Declare and Initialize and Array of Strings  
    array<String^>^ names = gcnew array<String^> {                       
            L"Damian",   
            L"Rogelio",  
            L"Carlos",   
            L"Luis",                       
            L"Daniel"  
        };  
    PrintArrayString(names);  
    array<String^>^ ordered_names = BubbleSortString(names);  
    PrintArrayString(ordered_names);  
  
    // Multi-dimensional Array (Matrix row,column)  
  
    PrintTitle(L"Transpose Matrix");  
  
    /* Matrix row=2,col=3 
        * A =  [6  4 24] 
        *      [1 -9  8] 
    */  
    array<int, 2>^ matrix = gcnew array<int, 2>(2, 3) {{ 6, 4, 24 },   
                                                       { 1, -9, 8 }};  
    PrintMatrix(matrix);  
    array<int, 2>^ transposed_matrix = TransposeMatrix(matrix);  
    PrintMatrix(transposed_matrix);  
  
    // Jagged Array (Array-of-Arrays)  
  
    PrintTitle(L"Upper Case Random Array & Graph Number of Elements");  
      
    /*              
    * Creating an array of string arrays using the String.Split method 
    * instead of initializing it manually as follows: 
    *  
    * array<array<String^>^>^ text = gcnew array<array<String^>^> {  
    *      gcnew array<String^> { "word1", "word2", "wordN" },
    *      gcnew array<String^> { "word1", "word2", "wordM" },  
    *      ... 
    *      }; 
    *  
    * Text extract from: "El ingenioso hidalgo don Quijote de la Mancha" 
    *  
    */  
    array<array<String^>^>^ text = {   
    (gcnew String(L"Hoy es el día más hermoso de nuestra vida, querido Sancho;"))->Split(L' '),  
    (gcnew String(L"los obstáculos más grandes, nuestras propias indecisiones;"))->Split(L' '),  
    (gcnew String(L"nuestro enemigo más fuerte, miedo al poderoso y nosotros mismos;"))->Split(' '),  
    (gcnew String(L"la cosa más fácil, equivocarnos;"))->Split(' '),  
    (gcnew String(L"la más destructiva, la mentira y el egoísmo;"))->Split(' '),  
    (gcnew String(L"la peor derrota, el desaliento;"))->Split(' '),  
    (gcnew String(L"los defectos más peligrosos, la soberbia y el rencor;"))->Split(' '),  
    (gcnew String(L"las sensaciones más gratas, la buena conciencia..."))->Split(' ')   
    };  
    PrintJaggedArray(text);  
    UpperCaseRandomArray(text);  
    PrintJaggedArray(text);  
    GraphJaggedArray(text);  
  
    // Array Exceptions  
  
    PrintTitle(L"Common Array Exceptions");  
  
    PrintCommonArrayExceptions(nullptr);  
    PrintCommonArrayExceptions(text);  
  
    // Accessing Class Array Elements through Indexer  
  
    PrintTitle(L"Alphabets");  
  
    Alphabet^ vowels = gcnew Alphabet(5);
    vowels[0] = L'a';  
    vowels[1] = L'e';  
    vowels[2] = L'i';  
    vowels[3] = L'o';  
    vowels[4] = L'u';  
    
    Console::WriteLine(L"\nVowels = {{{0}}}",  
        String::Join(L",", vowels[0], vowels[1], vowels[2], vowels[3], vowels[4]));  
  
    Alphabet^ en = gcnew Alphabet(L"abcdefghijklmnopqrstuvwxyz");  
    Console::WriteLine(L"English Alphabet = {{{0}}}", en);  
  
    Console::WriteLine(L"Alphabet Extract en[9..19] = {{{0}}}",   
                    gcnew Alphabet(en->Slice(9, 10)));  
  
    String^ word1 = String::Join(L"", en[6], en[14], en[14], en[3]);  
    String^ word2 = String::Join(L"", en[1], en[24], en[4]);  
    String^ word3 = String::Join(L"", en[4], en[21], en[4], en[17],  
                                    en[24], en[14], en[13], en[4]);  
  
    Console::WriteLine(L"\n{0} {1}, {2}!\n", word1, word2, word3);  


    return 0;
}


The output:






















































































Voilà, that's it. Next post in the following days.

1 comment: