Laden...

Str2Int - Auf wieviel Arten kommen wir zum Ergebnis

Erstellt von smilebey vor 17 Jahren Letzter Beitrag vor 17 Jahren 16.237 Views
smilebey Themenstarter:in
32 Beiträge seit 2007
vor 17 Jahren
Str2Int - Auf wieviel Arten kommen wir zum Ergebnis

Hallo,
Starte mal dieses Thema zum Spaß um zu sehen auf wieviel Arten die ganze Community einen String in ein Integer umwandeln kann.
Ich fange mal an:

int i = Int32.Parse(myString);
Console.WriteLine("Mess with the best, die like the rest.");
K
124 Beiträge seit 2006
vor 17 Jahren

int i = Convert.ToInt32(myString);

wobei myString natürlich nur numerische Zeichen enthalten darf

kaloon

S
50 Beiträge seit 2006
vor 17 Jahren
int i = (int)myString;

Jeder fängt mal klein an!

B
67 Beiträge seit 2007
vor 17 Jahren

int zahl = 0;
int multiplikator = 1;
for (int i = myString.Length-1; i >= 0; i-- )
{
    zahl += Int32.Parse(myString.Substring(i,1)) * multiplikator;
    multiplikator *=10;
}

😁

D
386 Beiträge seit 2007
vor 17 Jahren

int result = 0;
for (int i=0; i<myString.Length; i++) {
  int m = 0;
  switch (myString[i]) {
    case '1': m++; break;
    case '2': m++; goto case '1';
    case '3': m++; goto case '2';
    case '4': m++; goto case '3';
    case '5': m++; goto case '4';
    case '6': m++; goto case '5';
    case '7': m++; goto case '6';
    case '8': m++; goto case '7';
    case '9': m++; goto case '8';
  }
  result += m * (int)Math.Pow(10, (myString.Length-i-1));
}

So?

Pound for pound, plutonium is about as toxic as caffeine when eaten.

B
67 Beiträge seit 2007
vor 17 Jahren

auch sehr schön 😁

D
386 Beiträge seit 2007
vor 17 Jahren

Kein Programm ist komplett ohne Rekursion..


private int CharToDigit(char c) {
  if (c == '0') {
    return 0;
  } else {
    return 1+CharToDigit((char)(c-1));
  }
}

....

int result = 0;
for (int i=0; i<myString.Length; i++) {
  int m = charToDigit(myString[i]);        
  result += m * (int)Math.Pow(10, (myString.Length-i-1));
}

Edit: Tippfehler

Pound for pound, plutonium is about as toxic as caffeine when eaten.

2.921 Beiträge seit 2005
vor 17 Jahren

            DynamicMethod m = new DynamicMethod("ConvertToInt", typeof(int), new Type[] { }, typeof(string), false);
            MethodInfo methodInfo = m.GetBaseDefinition();
            ILGenerator ilGenerator = m.GetILGenerator();
            ilGenerator.Emit(OpCodes.Ldstr, "596");  //hier die Zahl ersetzen
            ilGenerator.Emit(OpCodes.Stloc_0);
            ilGenerator.Emit(OpCodes.Ldloc_0);
            ilGenerator.EmitCall(OpCodes.Call, methodInfo, null);
            ilGenerator.Emit(OpCodes.Stloc_1);
            ilGenerator.Emit(OpCodes.Ret);

Der Rest fehlt zwar drum rum, aber es funktioniert.

Einfach die 596 durch die gewünschte Zahl ersetzen

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

189 Beiträge seit 2006
vor 17 Jahren

Original von dr4g0n76

  
            DynamicMethod m = new DynamicMethod("ConvertToInt", typeof(int), new Type[] { }, typeof(string), false);  
            MethodInfo methodInfo = m.GetBaseDefinition();  
            ILGenerator ilGenerator = m.GetILGenerator();  
            ilGenerator.Emit(OpCodes.Ldstr, "596");  //hier die Zahl ersetzen  
            ilGenerator.Emit(OpCodes.Stloc_0);  
            ilGenerator.Emit(OpCodes.Ldloc_0);  
            ilGenerator.EmitCall(OpCodes.Call, methodInfo, null);  
            ilGenerator.Emit(OpCodes.Stloc_1);  
            ilGenerator.Emit(OpCodes.Ret);  
  

Wer brauch schon nen Obfuscator 😄?

knub

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo zusammen,

so viele Lösungen und kein Int32.TryParse dabei. 🙂

herbivore

PS: mit int i = (int)myString; geht es übrigens nicht.

T
98 Beiträge seit 2007
vor 17 Jahren

Bei dezimal Zahlen:

string zahlString = "19201";
int i = Convert.ToInt32(zahlString,10)

bei Hex:

string hexString ="0F";
int i = Convert.ToInt32(hexString,16);

und Bits

string bitString = "011";
int i = Convert.ToInt32(bitString,2)

wobei Int32.TryParse natürlich nicht fehlen sollte, aber bin grad zu faul das noch zu ergänzen 🙂 Noch zu Faul war und nun ergänzt habe: 13:50 Heute

Nachtrag, wobei ich
System.Globalization.NumberStyles.Float
in diesem Zusammenhang als echt nützlich sehe ...


string intString = "1234";
int i;
if (Int32.TryParse(intString, out i))
  richTextBox1.AppendText(i.ToString()+"\n");

string doubleStr = "10.023";
double result;
if (Double.TryParse(doubleStr, out result))
  richTextBox1.AppendText(result.ToString()+"\n");

oder die etws feinere Art:
string doubleS = "10.023";
double d;
if (Double.TryParse(doubleS, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out d))
    richTextBox1.AppendText(d.ToString()+"\n");

string hStr = "0f";
int h;
if (Int32.TryParse(hStr, System.Globalization.NumberStyles.HexNumber, System.Globalization.NumberFormatInfo.InvariantInfo, out h))
  richTextBox1.AppendText(h.ToString() + "\n");

string tString = "1,000";
if (Int32.TryParse(tString,System.Globalization.NumberStyles.AllowThousands,System.Globalization.NumberFormatInfo.InvariantInfo, out i))
  richTextBox1.AppendText(i.ToString()+"\n");

usw. einzig kann ich einen bitString = "011" mit Int32.TryParse in diesem Sinn noch nicht bearbeiten, aber vielleicht weiss jemand Abhilfe?

S
8.746 Beiträge seit 2005
vor 17 Jahren

Ich finde ja, DarKlajid ist uns noch eine echt rekursive Lösung schuldig.... 🙂

B
1.529 Beiträge seit 2006
vor 17 Jahren

Ich beanspruche hiermit den Erfolg, die wahrscheinlich langsamste Methode gefunden zu haben:

public int Str2Int( string mystring )
{
   string iString = myString.Trim();
   int i = int.MinValue;
   try
   {
      while (i.ToString() != iString)
         checked(i++);
   }
   catch(OverflowException ex)
   {
      throw new FormatException();
   }
   return i;
}

EDIT: checked hinzugefügt.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo svenson,

du meinst vermutlich sowas:


public static int Str2Int (String str)
{
   if (str == "") { return 0; }
   return Str2Int (str.Substring (0, str.Length-1)) * 10
        + str [str.Length-1] - '0';
}

herbivore

PS: Nur für positive Zahlen und ohne Fehlerbehandlung.

S
8.746 Beiträge seit 2005
vor 17 Jahren

Original von Borg
Ich beanspruche hiermit den Erfolg, die wahrscheinlich langsamste Methode gefunden zu haben:

Soso, wieder rumprotzen.

🙂

T
512 Beiträge seit 2006
vor 17 Jahren
public static int Str2Int( string text, params char[] digits )
{
    int digitValue;
    int result = 0;
    int b = digits.Length;

    Dictionary<char,int> digitMap = new Dictionary<char,int>( digits.Length );

    for( int i = 0; i < digits.Length; ++i )
    {
        digitMap[digits[i]] = i;
    }

    for( int i = 0; i < text.Length; ++i )
    {
        if( !digitMap.TryGetValue( text[i], out digitValue ) )
            throw new FormatException();

        result = result*b + digitValue;
    }
    return result;
}

Aufruf z.B:

Binär:
Str2Int( "10110", '0', '1' )

Dezimal:
Str2Int( "1234", '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' )

😁

Da fällt mir gerade noch eine ein, mit der ich Borgs Lösung im Worst-Case noch schlage:

public static int Str2Int( string text )
{
    Random rand = new Random();
    int result = 0;
    while( result.ToString() != text )
    {
        result = rand.Next( int.MinValue, int.MaxValue );
    }
    return result;
}

e.f.q.

Aus Falschem folgt Beliebiges

T
98 Beiträge seit 2007
vor 17 Jahren

Jo, Traumzauberbaum!

In Sache, wie geht es am Kompliziertesten, schlägt dich vielleicht nur noch dr4g0n76. Dickes Gratz!!!
Aber mal im Ernst, es wäre vielleicht nützlicher die diversen, Parameter der TryParse Funktion zu erläutern und anhand diverser Beispiel auch Strings die in speziellem Format vorliegen, wie zB, dass von mir erwähnte "1,000", den Nutzern des Forums einiges Wissen auf den Weg zu geben. Inwiefern man über die Parameter:
System.Globalization.NumberStyles."AllowThousands" usw, es gibt ja ne Liste von Parametern sowie:
System.Globalization.NumberFormatInfo.InvariantInfo
Strings umwandelt, wäre auch für mich eine intressante, und damit aufschlussreiche Sache.

B
1.529 Beiträge seit 2006
vor 17 Jahren

Da fällt mir gerade noch eine ein, mit der ich Borgs Lösung im Worst-Case noch schlage:

Ok, damit liegt man zeitlicher wohl noch schlechter.
Allerdings: Deine Lösung führt im Gegensatz zu meiner nicht garantiert zu einer Lösung (wenn es eine gibt).
Es ist sogar möglich, dass der Algorithmus unendlich lange läuft, ohne die Lösung zu finden. Inwiefern man dann noch von einem Algorithmus sprechen kann, ist fraglich...

D
386 Beiträge seit 2007
vor 17 Jahren

Ich liebe den Thread, auch wenn es albern wird. s/auch wenn/weil/ ..

Credits an Borg fuer die Idee, wenn auch von ihm wohl nicht gewollt 😉



public static void StringToCharsEx(string s) {      
  if (s.Length > 1) {
    try {
      StringToCharsEx(s.Substring(0, s.Length-1));
    } catch (FormatException fe) {
      throw new FormatException(s[s.Length-1].ToString(), fe);
    }
  } else {
    throw new FormatException(s);
  }      
}

// Code zum "Umwandeln"

int result = 0;
try {
  StringToCharsEx(myString);
} catch (FormatException fe) {        
  int resultBase = 0;
  Exception ex = fe;
  do {
    result += (int)(ex.Message[0]-48) * (int)Math.Pow(10, resultBase++);
  } while ((ex = ex.InnerException) != null);     
}

Edit: Credit where credit is due.

Pound for pound, plutonium is about as toxic as caffeine when eaten.

2.921 Beiträge seit 2005
vor 17 Jahren

Soll ich jetzt vielleicht noch die Methode mit einem zur Laufzeit kompilierten Script einbringen oder schnallt ihr dann alle völlig ab? 😁

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

T
98 Beiträge seit 2007
vor 17 Jahren

jo mach das dr4g0n76,
du bist hier eh der König 🙂

verbeug
TEry

2.921 Beiträge seit 2005
vor 17 Jahren

hier noch eine:


     public int StringToInt(string sString)
        {
            int nResult = 0;
            int nExponent = 0;
            int nMultiplicator = 1;
            nExponent = sString.Length-1;
            foreach (char chChar in sString)
            {
                nResult += (chChar - 48)*(int)Math.Pow(5,nExponent)*nMultiplicator << nExponent--;
            }
            return nResult;
        }        

EDIT: natürlich auch nicht für negative Zahlen geeignet.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

2.921 Beiträge seit 2005
vor 17 Jahren

Hier noch eine mit Reflection und gleichzeitiger Benutzung von XML zur Konvertierung:


public class Form1 : Form
{
        public string sTest = "4095";
        public Form1()
        {
            int n1 = StringToInt("sTest"); //edit: hier auszulesendes Field angeben
        }

        private int StringToInt(string sFieldName)
        {
            FieldInfo info = this.GetType().GetField(sFieldName);
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml("<Node>" + info.GetValue(this) + "</Node>");
            MessageBox.Show(xDoc.InnerXml);
            XmlNodeReader xmlNodeReader = new XmlNodeReader(xDoc);
            xmlNodeReader.Read();
            xmlNodeReader.Read();
            return (int)xmlNodeReader.ReadContentAsInt();
        }
}

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

T
98 Beiträge seit 2007
vor 17 Jahren

Könne man mit Regex nicht noch überprüfen ob der String konvertierbar ist, der sich da gern: simsalabim in eine Zahl umwandeln lassen will?
Langsam bekomme ich aber Kopfschmerzen von diesem Thread 🙂 Mitunter bin ich der Einzige der eine vernünftige Lösung gefunden hat, und ihr albert nur rum. Spass hat auch seine Grenzen! Och ich glaub ich brauch ein starkes Getränk. Oder eine Tablette. Langsam sind die Grenzen zwischen Vernunft und Wahnsinn zu weit auseinandergeklafft. Aber hinter jedem Vernunftswessen oder zuinnerst, lauert ja auch ein wenig Wahnsinn. Von welcher Art auch immer dieser sei...

*kaffeschlürf*

ps: wenn der String in Form von
s = "tausendsiebhunderdreiundvierzig" vorliegt, wird es natürlich wirklich schwer 🙂
vorallem wenn noch kleine Rechtschreibefehler drin sind ... hehe

822 Beiträge seit 2005
vor 17 Jahren

Eine etwas effektivere Methode als die von Borg:


int StringToInt(string str)
        {
            int wert = 0;
            while ((wert.ToString() != str) && (wert < int.MaxValue))
                wert++;
            return wert;
        }

Sollte sie jemandem zu effektiv sein:


static int StringToInt(string str)
        {
            int wert = 0;
            while ((wert.ToString() != str) && (wert < int.MaxValue))
{
Thread.Sleep(new Random().Next(50,1000));
                wert++;
            return wert;}
        }

😁 😁 😁

smilebey Themenstarter:in
32 Beiträge seit 2007
vor 17 Jahren

Original von TEry
Langsam sind die Grenzen zwischen Vernunft und Wahnsinn zu weit auseinandergeklafft. Aber hinter jedem Vernunftswessen oder zuinnerst, lauert ja auch ein wenig Wahnsinn. Von welcher Art auch immer dieser sei...

*kaffeschlürf*

Naja man behauptete dass Albert Einstein auch wahnsinnig war...

Console.WriteLine("Mess with the best, die like the rest.");
2.921 Beiträge seit 2005
vor 17 Jahren

Und hier noch das kompilierte Script:


      public int StringToInt(string sString)
        {
            string sName = "CConvert";

            string sSource =
                    @"
                    using Rekursion;
                    using System;
                    using System.Windows.Forms;
                    namespace MyProgram
                    {
                        public class {1} : IScript
                        {
                            public object Evaluate()
                            {
                                return {0};
                            }
                        }
                    }";

            sSource = sSource.Replace("{0}", sString);
            sSource = sSource.Replace("{1}", sName);

            CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider();
            ICodeCompiler compiler = csharpCodeProvider.CreateCompiler();
            CompilerParameters compilerParameters = new CompilerParameters();

            compilerParameters.GenerateInMemory = true;
            compilerParameters.ReferencedAssemblies.AddRange(new string[] { Application.StartupPath, "mscorlib.dll", "system.dll", "System.Windows.Forms.dll" });

            CompilerResults compilerResults = compiler.CompileAssemblyFromSource(compilerParameters, sSource);
            IScript script = compilerResults.CompiledAssembly.CreateInstance("MyProgram." + sName) as IScript;
            compilerResults = compilerResults;

            return (int)script.Evaluate();
        }

Diesmal ungetestet.

edit: Hierbei ist eigentlich auch der Witz, dass so gesehen, eigentlich gar keine Konvertierung erfolgt.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

T
98 Beiträge seit 2007
vor 17 Jahren

Also wenn der Script von dr4g0n76 funktioniert, müsste man ihn schon zu den wahnsinnigen Genies zählen. Im Sinn von Einstein. Nur stellt sich dennoch die Sinnfrage. Ergibt es Sinn über eine Funktion, die es schon längstens gibt, und über deren Anwendbarkeit in den verschiedensten Formalitäten, sprich, in welcher Form liegt die Zahl als String vor, und darauf wollte herbievore auch mal aus, und das mit Recht! Siehe meinen bescheidenen Beitrag. Sprich in dieser Anwendbarkeit noch grösste Unwissenheit oder bescheidenes "Nicht zu Papier gebracht", vorliegt. Werden hier Lösungen offeriert, die keinen praktikablen Nutzen versprechen und eher die Genialität ihrer Erfinder offenlegt. Es sei denn einer hier, der mir sagen könnte, wie ich einen aus BitStrings "00100101" bestehenden String über TryParse, zu Papier, sprich Integer bringe. Dann würde ich auch gern verzeihen, was sich an Auswüchsen in diesem Thread breit und lang schlägt. Gewiss ihr seid alle in eurer Art genial. Aber schnelle Lösungen? Ne, das habt ihr nicht auf Lager. Ihr könnt die Rechenarbeit ja auch über ein uraltes Modem an einen C64er schicken und ihn alle Stunden nach dem nächsten Bit abfragen. Langsamer gehts immer. Nur das man so kompliziert kann, wusste ich echt nicht! Dennoch, ich muss schon echt staunen, was ihr so auf dem Kasten habt!!!

Ende der Anklage.

T
512 Beiträge seit 2006
vor 17 Jahren

Binäre Suche:


public static int Str2Int( string text )
{
	int sign = text.StartsWith( "-" ) ? -1 : 1;

	text = text.TrimStart( '-', '0' );

	double max = Math.Pow( 10, text.Length ) - 1.0;

	uint upperBound = max > int.MaxValue ? (uint)int.MaxValue + 1 : (uint)max;
	uint lowerBound = (uint)Math.Pow( 10, text.Length - 1 );

	uint pivot;
	int compare;

	checked
	{
		while( lowerBound <= upperBound )
		{
			pivot = (upperBound>>1) + (lowerBound>>1) + (1&upperBound&lowerBound);
			compare = pivot.ToString().CompareTo( text );
			if( compare < 0 )
			{
				lowerBound = pivot + 1;
			}
			else if( compare > 0 )
			{
				upperBound = pivot - 1;
			}
			else
			{
				unchecked
				{
					return (int)pivot < 0 ? (int)pivot : (int)pivot * sign;
				}
			}
		}
	}

	throw new FormatException();
}

Und hier noch die CodeDom Variante von dr4g0n76 Ansatz:


private static void Eval()
{
	string text = (string)AppDomain.CurrentDomain.GetData( "text" );
	CodeTypeDeclaration typeDecl = new CodeTypeDeclaration();
	typeDecl.Name = "Eval";

	CodeMemberMethod methodDecl = new CodeMemberMethod();
	methodDecl.Name = "GetHashCode";
	methodDecl.Attributes = MemberAttributes.Public|MemberAttributes.Override;
	methodDecl.Statements.Add( new CodeMethodReturnStatement( new CodeSnippetExpression( text ) ) );
	methodDecl.ReturnType = new CodeTypeReference( typeof( int ) );

	typeDecl.Members.Add( methodDecl );

	CodeNamespace ns = new CodeNamespace( "Generated" );
	ns.Types.Add( typeDecl );

	CodeCompileUnit unit = new CodeCompileUnit();
	unit.Namespaces.Add( ns );

	CompilerParameters parameters = new CompilerParameters();
	parameters.GenerateInMemory = true;
	parameters.GenerateExecutable = false;

	Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
	CompilerResults result = provider.CompileAssemblyFromDom( parameters, unit );

	if( result.Errors.HasErrors )
	{
		string s = "";
		foreach( CompilerError error in result.Errors )
			s += error.ErrorText;
		throw new FormatException();
	}

	Type t = result.CompiledAssembly.GetType( "Generated.Eval" );
	
	AppDomain.CurrentDomain.SetData( "value", Activator.CreateInstance( t ).GetHashCode() );
}

public static int Str2Int( string text )
{
	AppDomain evalDomain = AppDomain.CreateDomain( "EvalDomain" );

	evalDomain.SetData( "text", text );

	evalDomain.DoCallBack( Eval );

	int result = (int)evalDomain.GetData( "value" );

	AppDomain.Unload( evalDomain );

	return result;
}

@TEry

Wenn du eine ernsthafte Lösung willst, dann wär der Thread in 2 Zeilen zuende:

int.Parse
RTFM

Ich denke auch wenn das Ziel hier eher trivial gibt, kann man doch viel aus den Lösungswegen lernen.

e.f.q.

Aus Falschem folgt Beliebiges

2.921 Beiträge seit 2005
vor 17 Jahren

@TEry: Wenn man so etwas vom Zaun bricht wie diesen Thread, ist es doch ganz interessant zu sehen, welche Lösungen die einzelnen Leute erarbeiten.

Vor allem glaube ich kaum, dass hier jemand die Lösungen nachgeschaut hat, sondern alle selber erarbeitet sind.

Übrigens mit ganz kleinen Änderungen läuft mein Script tatsächlich durch.

Damit darf ich mich jetzt laut Dir auch wahnsinniges Genie nennen. 😁

EDIT: übrigens es wäre auch möglich mit PSharp noch eine wahnsinnigere Lösung zu machen.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

T
98 Beiträge seit 2007
vor 17 Jahren

jo schon dr4g0n76,
aber irgendwie bin ich ein wenig entäuscht, das zB. niemand Regex verwendet hat für die Typenprüfung. Auch das nichtandwenden der differsen Parse( String, NumberStyles, usw ...
für was ist den NumberStyles überhaupt vorhanden, wenn es keinen Sinn ergibt?

Ich finde ja die Lösungen manchmal echt "haarsträubend", manche genial. Aber hin und wieder hätte ich auch gern mal auf einen brauchbaren Happen gehofft.

Ich hoffe du verstehst meine Ansichten auch
Gruss und bleibt weiterhin wie ihr seid
// ich sag nicht mehr genial, sonst bricht hier noch der Grössenwahn aus 🙂)
TEry

2.921 Beiträge seit 2005
vor 17 Jahren

lol @TEry.

Alles klar. 🙂

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

D
386 Beiträge seit 2007
vor 17 Jahren

Weil Regex nicht die goldene Antwort auf alles sind. Und da sie dem Problem ueberhaupt nicht helfen koennen (immerhin konvertieren sie nix), kann man durch den Einbau von derartigen Expressions nur die Loesungen die hier stehen verschlimmbessern. Da lernst du auch nicht mehr von.
Ansonsten beginnt der Thread mit "Auf wieviel Arten..".. Da braucht es viele Beispiele.

Pound for pound, plutonium is about as toxic as caffeine when eaten.

T
512 Beiträge seit 2006
vor 17 Jahren

Naja Regex hilft schonmal ein paar auszusieben, die nicht konvertiert werden können. Und man kann damit auch negative Zahlen erkennen.

Einen Kurzen hab ich noch, dann reichts aber für heute:


public static int Str2Int( string text )
{
	using( DataTable t = new DataTable() )
	{
		return (int)t.Compute( text, null );
	}
}

e.f.q.

Aus Falschem folgt Beliebiges

T
98 Beiträge seit 2007
vor 17 Jahren

Ich kann mich durchaus irren in der Annahme DarKlajid,

war bescheidener Ansicht, das über Regex ein schwerlich lesbarer Zahlencode, in passible Form gebracht werden könnten. Gebe jedoch gern meinen Irrtum zu.

Beharre ja auch nicht auf Regex, sondern frage mich ernsthaft, wofür Parse Parameter anbietet, die niemand braucht. Wahrscheinlich geben NumberStyles ja auch keinen Sinn. Nur frag ich mich, warum sie den noch integriert sind. Wahrscheinlich um der alten Tage willen und um der Erinnerung 🙂

Das es viele Beispiele gibt zu so einem Thread ist mir ja klar. Nur das man zum Absurden sich neigt ein warnehmbares Faktum, dass ich zu nennen wagte und hoffte, jemand hätte noch ein ernsthafte Lösungen die er auch gern vorzeigen würde. Ob aus dem Lehrbuch oder aus dem Hirn raus, ist mir eigentlich Wurst. Nur denke ich es hat wenig Sinn: Das Wasser fliesst aus vollen Rohren, nicht aufzuhalten seine Macht:

nur irrt ihr von dem Wege, und sag ichs: Ihr geht falsch, so mehrt ihr nurmehr eure Zauber.

Gruss vom Dichter, der ich gern geworden wäre
TEry

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo TEry,

sondern frage mich ernsthaft, wofür Parse Parameter anbietet, die niemand braucht.

schau einfach in die Doku. Da ist alles sehr ausführlich und mit Beispielen beschrieben. Was will man mehr?

herbivore

T
512 Beiträge seit 2006
vor 17 Jahren

Ach verdammt, hier noch die gewünschte Variante mit Regex:


public static int Str2Int( string text )
{
	const string pattern = @"(0)|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(.)";

	int result = 0;
	int sign = 1;
	if( text.StartsWith( "-" ) )
	{
		text = text.Substring( 1 );
		sign = -1;
	}

	checked
	{
		MatchEvaluator eval = delegate( Match m )
		{
			for( int i = 1; i <= 10; ++i )
			{
				if( m.Groups[i].Success )
				{
					result *= 10;
					result += (i-1)*sign;
					return "";
				}
			}
			throw new FormatException();
		};
	
		Regex.Replace( text, pattern, eval );
	}

	return result;
}

e.f.q.

Aus Falschem folgt Beliebiges

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Traumzauberbaum,

Mist, ich hatte gerade damit angefangen. Du warst leider schneller. 😦

herbivore

D
386 Beiträge seit 2007
vor 17 Jahren

Original von Traumzauberbaum
Ach verdammt, hier noch die gewünschte Variante mit Regex:

  
const string pattern = @"(0)|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(.)";  
  

Ich hoffe dieses Pattern war absichtlich krude gewaehlt um in den WTF Kontext dieses Threads zu passen. Ansonsten waere die allein jetzt schon lustig..
Jedenfalls - auch damit lernt TEry keine regexp Hintergruende. 😉

Pound for pound, plutonium is about as toxic as caffeine when eaten.

T
512 Beiträge seit 2006
vor 17 Jahren

Was ist denn an dem Pattern schlecht?
Dann kann ich aus dem Index der Gruppe auf den gematchten Inhalt schließen 😉

Hab mich eben an nem genetischen Algorithmus versucht:


private static Random rand = new Random();

private static double Fitness( int guess, string text )
{
	string guessText = guess.ToString( "d10" );

	if( guessText.Length > text.Length )
		text = new string( '0', guessText.Length - text.Length ) + text;
	
	int matches = 0;
	for( int i = 0; i < text.Length; ++i )
	{
		if( guessText[i] == text[i] )
		{
			++matches;
		}
	}

	double fitness = (double)matches / (double)text.Length;

	return fitness;
}

private static int Reproduce( int a, int b )
{
	int bigger = Math.Max( a, b );
	int smaller = Math.Min( a, b );

	int result = 0;

	while( bigger != 0 )
	{
		result *= 10;

		switch( rand.Next( 0, 5 ) )
		{
			case 0:
			case 1:
				result += bigger%10;
				break;

			case 2:
			case 3:
				result += smaller%10;
				break;

			default:
				result += rand.Next( 0, 10 );
				break;
		}

		bigger /= 10;
		smaller /= 10;
	}
	return result;
}

public static int Str2Int( string text )
{
	int[] generation = new int[4096];
	double[] fitness = new double[generation.Length];

	for( int i = 0; i < generation.Length; ++i )
	{
		generation[i] = rand.Next( -1, int.MaxValue ) + 1;
		fitness[i] = Fitness( generation[i], text );
	}

	List<int> newGeneration = new List<int>( generation.Length );
	double h;
	int a, b;

	for( int i = 0; i < 1000; ++i )
	{
		Array.Sort( fitness, generation );
		if( fitness[generation.Length - 1] == 1.0 )
			return generation[generation.Length - 1];

		for( int k = 1; k < generation.Length / 4; ++k )
			newGeneration.Add( generation[generation.Length-k] );
		
		while( newGeneration.Count < generation.Length )
		{
			h = rand.NextDouble();
			h *= h;
			h = Math.Round( h * (generation.Length - 1) ) + 1.0;
			a = generation[generation.Length - (int)h];

			h = rand.NextDouble();
			h *= h;
			h = Math.Round( h * (generation.Length - 1) ) + 1.0;
			b = generation[generation.Length - (int)h];

			newGeneration.Add( Reproduce( a, b ) );
		}

		generation = newGeneration.ToArray();
		newGeneration.Clear();
		for( int k = 0; k < generation.Length; ++k )
			fitness[k] = Fitness( generation[k], text );
	}

	return generation[generation.Length - 1];
}

Ich hab nicht wirklich Ahnung davon. Wäre also nett wenn jemand kommentieren könnte, ob das überhaupt etwas GA ähnliches ist 😉

Erstaunlicherweise funktioniert das sogar recht gut. Für positive Zahlen wohlgemerkt.

EDIT: Noch einen Fehler behoben, jetzt überleben die Besten 😉

e.f.q.

Aus Falschem folgt Beliebiges

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Traumzauberbaum,

ich habe es mir nur grob angeguckt. Grundsätzlich passt das schon. Allerdings fehlt ein wichtiges Element, nämlich die Mutationsrate.

Jedes Individuum sollte einen Wert haben, der angibt, wie groß die Mutationswahrscheinlichkeit ist. Die Mutationswahrscheinlichkeit sollte Teil des Gens sein und somit selbst der Mutation unterliegen. Dadurch wird die Mutationswahrscheinlichkeit selbst automatisch optimiert und das ist der Gag.

Wenn ein Individuum weit vom Optimum entfernt ist, ist die Wahrscheinlichkeit, dass ein stark mutierter Nachkomme wesentlich fitter ist größer, als wenn das Individuum schon nahe am Optimum ist. Bei Individuen, die nah am Optimum sind, ist bei einer hohen Mutationswahrscheinlichkeit, die Wahrscheinlichkeit groß ist, dass entferne Nachkommen deutlich weniger fit sind.

Dadurch, dass man die Mutationswahrscheinlichkeit zum Teil des Gens macht, wird sie auf einen für den jeweiligen Abstand günstigen Wert optimiert. Dadurch erreicht man, dass die Nachkommen große Schnitte machen, wenn sie weit vom Ziel entfernt sind und kleine, wenn sie dem Ziel nahe sind.

Dadurch wird der Optimierungsprozess in der Regel nicht nur deutlich(!) beschleunigt, sondern das Optimum wird auch stabiler erreicht.

Das alles gilt im Allgemeinen für große Suchräume mit vielen Dimensionen. Ob es im speziellen Fall mit dem kleinen Suchraum und den wenigen Dimensionen auch gilt, müsste man ausprobieren.

herbivore

T
512 Beiträge seit 2006
vor 17 Jahren

Gut, ich wollte mir auch nicht zu viel Gedanken machen.
Hab eben grob die zwei Prinzipien eingebaut: Selektion und Kombination

Da mir für die Selektion auf die schnelle nichts cleveres eingefallen ist, hab ich einfach über das quadrat der Zufallszahl eine simple Verteilung genommen, die eher die "guten" Werte nimmt, aber auch mal bei den schlechten zuschlagen kann.
In die Reproduktion hab ich dann noch Mutation eingebaut (das bei default), um Pech bei der Initialisierung etwas zu kompensieren.

In den meisten Fällen klappts, manchmal kommt aber auch nichts gutes raus. War ja zu erwarten. Aber ich bin froh, dass es so weit wenigstens etwas funktioniert 😉

e.f.q.

Aus Falschem folgt Beliebiges

T
98 Beiträge seit 2007
vor 17 Jahren

Eigentlich dachte ich Regex zu verwenden um gewissen nicht in ein Integer-Wert passenden Strings wie zb. 4'000.00 oder 4-000-.00 zu bereinigen. Das in der Regex - Methode dann gleich noch eine Umwandlung stattfindet, ist allenfals lustig, oder kurios. Dazu bieten sich, nach der einer gewissen Bereinigung eines unleserlichen, oder schwer formatierten Strings, die Int.TryParse Mehode an, die über ihre verschiedenen Parameter, noch restliche Möglichkeiten durchgeht um den vielleicht immer noch unleserlichen String, doch noch in einen Integer zu klemptnern. Das ist zwar nicht gerade einfach, aber ich würde mal sagen, machbar. Wenn wir einfach mit Try Catch = geht nicht arbeiten, mag das zwar die billigste Lösung sein, aber ich denke ein Program sollte seinen Nutzer immer etwas entgegenkommen, indem es seine Eingabefehler nicht einfach mit einer Schellte: Sie haben einen ungültigen Wert eingegeben, sondern mit stillem Schweigen zu korrigieren versucht. Natürlich ratsam, dem Benutzer am Ende mitzuteilen:

Ich konne aus ihrer Eingabe, die sie echt undeutlich formuliert haben, die Zahl 4000.0 als Gleitkommazahl oder 4000 als Ganzzahl herauslesen. Welche Möglichkeit ist denn nun richtig? 4000.00 4000 oder wollen sie die Zahl neu und diesmal korrekt eingeben?
ps. wenn sie in Zukunft ihre Zahlen derart schwammig formulieren, könnten sie mir dann vielleicht ein Muster als Standard empfehlen, mit dem ich ihre Gekripsel ohne Nachfragen, verarbeiten und eintragen kann?

Nehmen wir mal der Benutzer tipt e10 ein. Aus der Tatsache, das e, keine Zahl ist, kann man schliessen, dass es sich um einen Tipfehler handelt. Da in der Nähe der Taste e die 3 und die 4 sind, heisst die Zahl also entweder 310 oder 410. Wobei aus der Nähe von 3 zu 1, mit 75% Wahrscheinlichkeit eine 3 richtig ist. Müsste das Program folgern können: Ich habe 310 erfasst, fals sie das Bestätigen drücken sie die Enter Taste, fals es sich um die Zahl 410 handelt, die "j" oder "J" Taste, und eine andere um ihre Eingabe zu wiederholen.

Also ist folgerichtig, das ein Program welches Strings in Integer umwandelt, aus der Nähe von gewissen Tasten zu Andern eine Wahrscheinlichkeit erstellt, um so eine möglichst schnelle Verarbeitung zu gewährleisten.

Ich würde also Vorschlagen: Erst die überprüfung der eingegebenen Zahlen und Buchstaben. Dann die Berichtigung. Danach die Bereinigung durch Regex und am Ende das Durchkämmen aller TryParse( unglücklicherString, mitEtlichenParameter
-> die verschiedenen Resultate an den Benutzer. Und wenn kein Resultat in Sicht:
Bitte geben Sie den Wert korrekt ein: ich kann ihr Gekribsel nicht lesen! Und glauben sie mir, ich hab mir alle Mühe dabei gegeben.

D
386 Beiträge seit 2007
vor 17 Jahren

Aehm - nein.
Erstens vergisst du mal wieder verschiedene Locales..
10'000 voellig korrekt in der Schweiz. 10.000 ist bei uns eine 5 stellige Ganzzahl und in den USA eine 10. 2,5 ist hier die Haelfte von 5 und wird in den USA ggf. als 2500 gelesen.
Eine Regexp hat hier immer noch keine Berechtigung.
Diese "Der Computer versucht meine Eingaben zu interpretieren" Idee finde ich reichlich pervers und daneben, ob ohne Nachfragen (lustig, wenn mein Onlinebanking raten wuerde was fuer Zahlen ich gemeint hab) oder mit.
Zu letzterem faellt wuerde ich, frei nach der wohl verhasstesten Pseudo-Computerhilfe folgendes schreiben wollen:

Zitat Clippy:
Es sieht so aus als wuerdest du zuviel Energie auf die falsche Sache verwenden. Moechtest du:

[ ] eine Liste der lokalen Sportvereine
[ ] ein World of Warcraft Abo kaufen
[ ] einen Assistenten fuer Singleboersen starten

?

Sorry, couldn't resist. Und der Thread ist halt, unabhaengig von einigen fehlgeleiteten Versuchen, m.E. nach immer noch in keinster Weise ernst gemeint oder ernst zu nehmen..

Pound for pound, plutonium is about as toxic as caffeine when eaten.

T
98 Beiträge seit 2007
vor 17 Jahren

Ich versteh jetzt nicht ganz. In der menschlichen Kommunikation gibt es ja auch Gelegenheiten, wegen greizten Stimmbändern, Restalk oder Müdigkeit, dass sich die Aussprache einer gewissen Zahl etwas schwammig anhört. Dann fragen wir doch auch: Du hast 200 gesagt, oder, wenn man aus einer Annäherung an das undeutlich Ausgesprochene eine Zahl heraushört. Damit macht man es dem undeutlichen Redner ja auch leichter, indem man die nächste Möglichkeit erwähnt.
So muss er nicht nochmals den ganzen Satz wiederholens sonder lediglich "Ja" sagen. Wieso ein Computer von der Nähe der Tasten zu Zahlen und der Angleichung an Regeln nicht in etwa, rückfragen könnte finde ich gar nicht so übel.
Wohl ist es ein Luxus, des Programmes. Aber ich dachte immer, das Programm sei für die Menschen gemacht. Doch die Programierer sind derart egozentrisch, das sie für ihr Program da sind und nie an die Benutzer denken, deren solches Entgegenkommen sicher äusserst wohl ankäme. Ein Programierer arbeite im Prinzip so sehr auf's Program fixiert, das er den Mensch, der es bedient in den Hintergrund rückt in der Art:
Na entweder der trifft nun die rechten Tasten, oder der kommt ne Flut von MessageBoxes entgegengeschleudert nach dem Moto, nicht mit mir!

ps. pervers ist hier nun wirklich übertrieben. Schliesslich gibt es auch Textverarbeitungsprograme die Fehler während des Eintippens korrigieren können!

Gruss TEry

S
8.746 Beiträge seit 2005
vor 17 Jahren

Original von herbivore
Dadurch wird die Mutationswahrscheinlichkeit selbst automatisch optimiert und das ist der Gag.

Schlag mich tot, aber ist der Hauptgrund für dieses Vorgehen nicht das Überwinden lokaler Maxima? Ist die Mutationsrate fest, kann es schnell passieren, dass die gesamte Population an solche Dingern kleben bleibt. Die anderen von dir beschriebenen Vorteile existieren natürlich auch.

D
386 Beiträge seit 2007
vor 17 Jahren

Original von TEry
ps. pervers ist hier nun wirklich übertrieben. Schliesslich gibt es auch Textverarbeitungsprograme die Fehler während des Eintippens korrigieren können!

Pervers ist immer ein subjektives Attribut und natuerlich gebe ich nur meine eigene Meinung wieder, ohne Anspruch auf allgemeine Gueltigkeit. Das von dir hier angesprochene "Feature" (ich nehme an du meinst z.B. die Office Autokorrektur und vergleichbares) qualifiziert sich in meiner kleinen Welt durchaus fuer das Woertchen pervers, ja.
Aber da wir mehr und mehr von der lustigen Ausgangsfragestellung abkommen ziehe ich mich mit diesem Beitrag aus dem Thread zurueck.. 😉

Pound for pound, plutonium is about as toxic as caffeine when eaten.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo svenson,

lokale Maxima kann man auch dadurch überspringen, dass man die Mutationsrate groß genug wählt, sie muss nicht variabel sein. Im Gegenteil, durch die "Optimierung" der Mutationswahrscheinlichleit bliebt man eher an den lokalen Maxima hängen, weil sich die Mutationswahrscheinlichleit in der Nähe von (lokalen) Maxima meist verringert.

Hallo TEry,

(Auto)Korrektur bei Zahlen ist quatsch. Bei deinem e10 könnte auch 10^10 (1e10) gemeint sein. Wenn du mit der Nähe von Tasten argumentierst, dann kann man auch sagen, dass mit 146 auch 156 gemeint sein könnte, weil neben der 5 die 4 und 6 liegt, auf die man gerutscht sein kann, wobei die 4 wahrscheinlicher ist, weil man ja von der 1 kommt. Also stellt das Programm bei der Eingabe von 146 die Frage, ob damit vielleicht 156 gemeint sein könnte? Wohl kaum. Andersherum heißt das aber, dass ein Benutzer bei Zahleneingaben sowieso genau hingucken muss, damit er keinen Mist eingibt, weil eben der Computer kaum in der Lage ist zu entscheiden, ob eine gewünschte Zahl korrekt eingegeben wurde. Wenn er das aber tut, muss man keinen Aufwand in eine sowieso nicht praktikable (Auto)Korrektur stecken.

herbivore

T
98 Beiträge seit 2007
vor 17 Jahren

Ok ich geb nach. Ich könnte zwar noch Einwände erheben, aber gegen die Vernunft Einwände zu erheben, ist immer ein schwer Ding. Nur auf die parameter poche ich. Auch wenn das eine Spassbremse bedeutet 🙁 Aber bei allem Unfug, der in diesem Thread an Unarten, wie man einen String in einen Integer umwandeln kann, dürfte doch ein wenig ernsthafte Suche nach Lösungen erlaubt sein. Wenn nicht, bin ich hier wirklich am falschen Ort 🙁 Und verzieh mich schmollend zurück.

Glück auf Euch Allen
TEry

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo TEry,

ernsthafte Lösungen wurde doch - gerade am Anfang - genannt. Meine persönliche Meinung ist, wo immer es geht TryParse einsetzen.

herbivore