// StringBuilder_Demo.cpp: Hauptprojektdatei.

#include "stdafx.h"

using namespace System;
using namespace System::Text;

// Funktion zum Erzeugen von anzahl Strings, deren Länge zwischen
// min und max liegt.
// String-Implementierung
array<String^>^ GeneriereStrings_v1(int anzahl, int min, int max) 
{
   Random^ gen = gcnew Random();
   array<String^>^ strings = nullptr;

   if(min > max || anzahl <= 0) // nichts zu tun
      return strings;

   strings = gcnew array<String^>(anzahl);

   for(int i = 0; i < anzahl; i++) 
   {
      // Länge des nächsten Strings zufällig wählen
      int laenge = gen->Next(min, max+1);

      String^ s = "";
      int zaehler = 0;

      while(zaehler < laenge) 
      {
         // Bereichsgrenzen: von A = 65 bis z = 122
         // Bereich 91-96 sind Sonderzeichen -> überspringen
         int zeichencode = gen->Next(65, 122 + 1);

         if(zeichencode >= 91 && zeichencode <= 96)
            continue;
         else
            zaehler++;

         s = s + Char(zeichencode); 
      } 

      strings[i] = s;
   }

   return strings; 
}


// Funktion zum Erzeugen von anzahl Strings, deren Länge zwischen
// min und max liegt.
// StringBuilder-Implementierung
array<String^>^ GeneriereStrings_v2(int anzahl, int min, int max) 
{
   Random^ gen = gcnew Random();
   array<String^>^ strings = nullptr;

   if(min > max || anzahl <= 0) // nichts zu tun
      return strings;

   strings = gcnew array<String^>(anzahl);

   for(int i = 0; i < anzahl; i++) 
   {
      // Länge des nächsten Strings zufällig wählen
      int laenge = gen->Next(min, max+1);

      StringBuilder^ sb = gcnew StringBuilder("");
      int zaehler = 0;

      while(zaehler < laenge) 
      {
         // Bereichsgrenzen: von A = 65 bis z = 122
         // Bereich 91-96 sind Sonderzeichen -> überspringen
         int zeichencode = gen->Next(65, 122 + 1);

         if(zeichencode >= 91 && zeichencode <= 96)
            continue;
         else
            zaehler++;

         sb->Append(Char(zeichencode)); 
      } 

      strings[i] = sb->ToString();
   }

   return strings; 
}


// Funktion zum Erzeugen von anzahl Strings, deren Länge zwischen
// min und max liegt.
// StringBuilder-Implementierung mit Kapazitätsvorgabe
array<String^>^ GeneriereStrings_v3(int anzahl, int min, int max) 
{
   Random^ gen = gcnew Random();
   array<String^>^ strings = nullptr;

   if(min > max || anzahl <= 0) // nichts zu tun
      return strings;

   strings = gcnew array<String^>(anzahl);

   for(int i = 0; i < anzahl; i++) 
   {
      // Länge des nächsten Strings zufällig wählen
      int laenge = gen->Next(min, max+1);

      StringBuilder^ sb = gcnew StringBuilder("", (max-min)/2 + min);
      int zaehler = 0;

      while(zaehler < laenge) 
      {
         // Bereichsgrenzen: von A = 65 bis z = 122
         // Bereich 91-96 sind Sonderzeichen -> überspringen
         int zeichencode = gen->Next(65, 122 + 1);

         if(zeichencode >= 91 && zeichencode <= 96)
            continue;
         else
            zaehler++;

         sb->Append(zeichencode); 
      } 

      strings[i] = sb->ToString();
   }

   return strings; 
}


int main(array<System::String ^> ^args)
{
   array<String^>^ strings;
   long start, end;

   // Laufzeittest mit String-Version
   for (int m = 1; m <= 3; m++)
   {
      // Erste Zeitnahme
      start = (long) DateTime::Now.Ticks;

      for (int n = 0; n < 10000; n++)
       strings = GeneriereStrings_v1(10, 0, 15);

      // Zweite Zeitnahme und Auswertung
      end = (long) DateTime::Now.Ticks;
      Console::WriteLine(" String-Version, verbrauchte Zeit in Millisekunden: {0}",
                        (end - start)/10000);
   }

   // Laufzeittest mit StringBuilder-Version
   for (int m = 1; m <= 3; m++)
   {
      // Erste Zeitnahme
      start = (long) DateTime::Now.Ticks;

      for (int n = 0; n < 10000; n++)
       strings = GeneriereStrings_v2(10, 0, 15);

      // Zweite Zeitnahme und Auswertung
      end = (long) DateTime::Now.Ticks;
      Console::WriteLine(" StringBuilder-Version, verbrauchte Zeit in Millisekunden: {0}",
                        (end - start)/10000);
   }

   // Laufzeittest mit StringBuilder-Version und Kapazitätsvorgabe
   for (int m = 1; m <= 3; m++)
   {
      // Erste Zeitnahme
      start = (long) DateTime::Now.Ticks;

      for (int n = 0; n < 10000; n++)
       strings = GeneriereStrings_v3(10, 0, 15);

      // Zweite Zeitnahme und Auswertung
      end = (long) DateTime::Now.Ticks;
      Console::WriteLine(" StringBuilder-Version (mit Kapazität), verbrauchte Zeit in Millisekunden: {0}",
                        (end - start)/10000);
   }


   Console::ReadLine();
   return 0;
}
