Zahlen fett darstellen

Hier noch eine Lösung, die die Zahlen zum ermitteln der Teilgleichehit auch als Zahlen ansieht und nicht als String. Bedingung ist, dass die Zahlen in einem Array stehen. Zahlen in ein Array zu packen sollte nicht das Problem sein. Zur Formatierung wird die Zahl allerdings wieder als String genutzt:
PHP:
<pre>
<?
    $aln=array(
        170958590,
        170958689,
        170958789);
    $max=max($aln);
    $nCount=ceil(log10($max));
    $matchingDigits=0;
    $isMatch=true;
    do {
        $mn=floor($max/pow(10,$nCount-$matchingDigits));
        $thisMatch=true;
        foreach($aln as $n) {
            $tmp = floor($n/pow(10,$nCount-$matchingDigits));
            $thisMatch = $thisMatch && ($mn==$tmp);
        }
        $isMatch = $isMatch && $thisMatch;
    } while ($isMatch && ++$matchingDigits<=$nCount);
    $matchingDigits--;
    foreach($aln as $n) {
        $s = str_pad ( $n, $nCount, ' ', STR_PAD_LEFT);
        $eq = subStr ($s,0,$matchingDigits);
        $ne = subStr ($s,$matchingDigits);
        echo "<b>".$eq."</b>".$ne."\n";
    }

?>
</pre>
Bei großen Datenmengen, ist die Regex-Variante von Sven vermutlich schneller.

Gruß hpvw
 
hpvw hat gesagt.:
Hier noch eine Lösung, die die Zahlen zum ermitteln der Teilgleichehit auch als Zahlen ansieht und nicht als String. Bedingung ist, dass die Zahlen in einem Array stehen. Zahlen in ein Array zu packen sollte nicht das Problem sein. Zur Formatierung wird die Zahl allerdings wieder als String genutzt:
PHP:
<pre>
<?
    $aln=array(
        170958590,
        170958689,
        170958789);
    $max=max($aln);
    $nCount=ceil(log10($max));
    $matchingDigits=0;
    $isMatch=true;
    do {
        $mn=floor($max/pow(10,$nCount-$matchingDigits));
        $thisMatch=true;
        foreach($aln as $n) {
            $tmp = floor($n/pow(10,$nCount-$matchingDigits));
            $thisMatch = $thisMatch && ($mn==$tmp);
        }
        $isMatch = $isMatch && $thisMatch;
    } while ($isMatch && ++$matchingDigits<=$nCount);
    $matchingDigits--;
    foreach($aln as $n) {
        $s = str_pad ( $n, $nCount, ' ', STR_PAD_LEFT);
        $eq = subStr ($s,0,$matchingDigits);
        $ne = subStr ($s,$matchingDigits);
        echo "<b>".$eq."</b>".$ne."\n";
    }

?>
</pre>
Bei großen Datenmengen, ist die Regex-Variante von Sven vermutlich schneller.

Gruß hpvw



Ihr wollt mich verarschen, oder ? ;-]
Sag bloss du verstehst den Code ;-)))

Ich probier mal

Danke danke danke
 
Sehe grad hier hat sich einiges getan :)

Mir ist auch grad der Kronleuchter mit den Zahlen aufgegangen.
Lösungsansatz wie von hpvw, allerdings nur für int, dafür weniger Code:
PHP:
$strArr = array('170958590','170958689','170958789');
$max = max($strArr);
$min = min($strArr);
$diff = $max-$min; 
$equiLen = strlen($max)-strlen($diff);
$equiStr = substr($max, 0, $equiLen);
foreach($strArr AS $zahl){
   echo str_replace($equiStr,"<b>".$equiStr."</b>",$zahl)."<br>";
}
 
Soapp hat gesagt.:
Ihr wollt mich verarschen, oder ? ;-]
Sag bloss du verstehst den Code ;-)))
Mein Mathelehrer hätte gesagt: "Simpelste Mathematik!" ... und alle hätten ihm einen Vogel gezeigt.
Ja, ich verstehe den Code, aber ich habe ihn auch geschrieben. Durch Sven's Code steige auch noch nicht durch. Ich kommentiere den Code noch mal, vielleicht ist es dann ja klarer (dabei ist mir aufgefallen, dass man ihn noch etwas vereinfachen konnte und mir ist ein Fehler aufgefallen):
PHP:
<pre>
<?
    //A Lot Numbers beinhaltet alle zu prüfenden Zahlen
    $aln=array(
        170958590,
        170958689,
        170958789);

    //ermittelt die größte der zu prüfenden Zahlen,
    //da man an ihr die maximale Anzahl Ziffern
    //ablesen kann
    $max=max($aln);
    
    //der aufgerundete Zehnerlogarithmus der
    //größten Zahl ermittelt, wie viele
    //Ziffern diese Zahlt hat
    $nCount=ceil(log10($max));
    
    //Hilfsvariable zum Zählen der gleichen
    //Anzahl Ziffern, beginnend am Anfang der Zahlen
    $matchingDigits=0;
    
    //Hilfsvariable, die false wird, wenn eine der
    //Zahlen an der aktuellen (siehe folgende Schleife)
    //Ziffer keine Übereinstimmung hat
    $isMatch=true;
    
    //Schleife, die $matchingDigits hochzählt,
    //solange noch alle bis hierhin betrachteten
    //Ziffern aller Zahlen gleich sind
    do {
        //berechnung der ersten "$matchingDigits" Ziffern
        //der maximalen Zahl
        //  pow(10,irgendwas entspricht 10 hoch irgendwas
        //  Es ist also das Gegenstück zum Logarithmus oben
        $mn=floor($max/pow(10,$nCount-$matchingDigits));
        
        //Alle Zahlen im Array prüfen
        foreach($aln as $n) {
            //berechnung der ersten "$matchingDigits" Ziffern
            //der bestimmten Zahl im Array
            $tmp = floor($n/pow(10,$nCount-$matchingDigits));
            
            //Am Ende steht der Vergleich mit den ersten
            //"$matchingDigits" Ziffern der maximalen Zahl
            //  ergibt dieser false, ist auch $isMatch false
            $isMatch = $isMatch && ($mn==$tmp);
        }
        //die Schleife wird nur fortgesetzt, wenn es
        //bis hierhin übereinstimmt und $matchingDigits
        //die Anzahl der Ziffern nicht überschreitet
    } while ($isMatch && $matchingDigits++<=$nCount);
    
    //da der erste Fehler in $matchingDigits mitgezählt wurde,
    //muss dies nun korrigiert werden.
    $matchingDigits--;
    
    //Die Ausgabe aller Zahlen im Array
    foreach($aln as $n) {
        //nun werden alle Zahlen zu einem gleich langen
        //String, entsprechend der Anzahl Ziffern der
        //größten Zahl gewandelt
        $s = str_pad ( $n, $nCount, ' ', STR_PAD_LEFT);
        
        //Als übereinstimmende Ziffern werden die ersten
        //$matchingDigits aus dem String kopiert
        $eq = subStr ($s,0,$matchingDigits);
        
        //Und als nicht übereinstimmende Ziffern der Rest
        $ne = subStr ($s,$matchingDigits);
        
        //nun nur noch die Ausgabe
        echo "<b>".$eq."</b>".$ne."\n";
    }

?>
</pre>
Gruß hpvw
 
Zuletzt bearbeitet:
hpvw hat gesagt.:
Durch Sven's Code steige auch noch nicht durch. Ich kommentiere den Code noch mal....


Dem will ich nicht nachstehen :-)
PHP:
function abfetten($str)
{ 
    //alle Zahlen in Array $arr vermerken
  preg_match_all('@\d+@', $str, $arr);
  
    //Output.... ist eigangs gleich input
  $out = $str;
  
    // wir nehmen die erste Zahl(String) und gehen sie 
    // Stück für Stück durch,
    // immer ein Zeichen mehr
  for($i = 1; $i < strlen($arr[0][0]); ++$i)
    {
        //der Suchausdruck aus dem  aktuellen Stück Zahl
      $pattern = '@\b('.substr($arr[0][0], 0, $i).')@';
        
        // hier wird die Gesamtanzahl der Zahlen mit der 
        // Anzahl der Elemente im Zahlenarray verglichen, 
        // welche mit dem Suchausdruck übereinstimmen
        // ...ist die Anzahl gleich, 
        // beginnen alle Zahlen mit dem Suchausdruck...dann...
      if(count(preg_grep($pattern, $arr[0])) == count($arr[0])) 
        {
            // Der entsprechende Teil der Zahlen 
            // im Eingangsstring wird ersetzt
          $out = preg_replace($pattern, "<b>\\1</b>", $str);
        }
    }
  return $out;
}
 
Die Idee von German finde ich sehr genial und habe mich gleich mal drüber hergemacht und den Code geändert (basierend auf Germans Code und gleich kommentiert):
PHP:
<pre>
<?
    //wieder das array
    $aln=array(
        170958590,
        170958689,
        170958789);
    //maximum ermitteln
    $max = max($aln);
    
    //minimum ermitteln
    $min = min($aln);
    
    //differenz ermitteln
    $diff = $max-$min;
    
    //Anzahl Ziffern von der Differenz von der Anzahl der Ziffern
    //des Maximums abziehen.
    //Dabei nimmt die 0 eine Sonderstellung ein:
    //  Ist sie der Maximalwert, sind alle Werte 0 (neg. Zahlen
    //  schließe ich aus) und sie entspricht beim Maximalwert
    //  einer Zahl mit einer Ziffer.
    //  Beim Differenzwert entspricht die 0 einer Zahl
    //  mit 0 Ziffern.
    $equiLen = (($max==0)?1:floor(log10($max) + 1))
            - (($diff==0)?0:floor(log10($diff) + 1));
            
    //Jetzt wieder nur die Teile mit substr herausholen
    //und ausgeben.
    $equiStr = substr($max, 0, $equiLen);
    foreach($aln AS $zahl){
        echo "<b>".$equiStr."</b>".substr($zahl,$equiLen)."\n";
    }
    
?>
</pre>

EDIT: @Sven habe ich Deine Funktion falsch angewendet? echo abfetten("101 101 101"); zeigt nicht alle Ziffern fett.
 
Zuletzt bearbeitet:
hpvw hat gesagt.:
Die Idee von German finde ich sehr genial ...
Danke für die Blumen (und das Kommentieren) ...
Aber so genial find ich die jetzt gar nicht mehr, sie setzt nämlich voraus, dass alle Zahlen gleich lang sind (was ja z.B. bei Telefonnebenstellen nicht zwingend der Fall ist)

Lösung:
PHP:
$strArr = array('1011','1012','101');
$max = max($strArr);
// Der kleinste Wert wird jetzt bis zur Länge des Größten mit Nullen gefüllt
$min = min($strArr).str_repeat("0", (strlen($max)-strlen(min($strArr))));
$diff = $max-$min;
// jetzt die Differenz 0 abfangen
$equiLen = ($diff==0) ? strlen($max) : strlen($max)-strlen($diff);
$equiStr = substr($max, 0, $equiLen);
foreach($strArr AS $zahl){
   echo str_replace($equiStr,"<b>".$equiStr."</b>",$zahl)."<br>";
}
Aber wirklich schlank ist das nicht mehr

@Soapp: Für was brauchst du das eigentlich?
 
German hat gesagt.:
Aber so genial find ich die jetzt gar nicht mehr, sie setzt nämlich voraus, dass alle Zahlen gleich lang sind (was ja z.B. bei Telefonnebenstellen nicht zwingend der Fall ist)
Das ist mir noch gar nicht aufgefallen. Bei meiner ersten Variante bin ich für den Fall noch von Rechtsbündigkeit ausgegangen, es also bei unterschiedlich langen Zahlen keine fetten Ziffern gibt. Bei dem ersten Code, den ich gepostet habe, funktioniert das auch in dem Sinne. Mittlerweile glaube ich aber, dass da auch noch einer von den vielen Spezialfällen nicht richtig funktionieren wird.
In dem Code, den ich aus Deinem gemacht habe, gibt es auch noch einige Fälle, die ich vorher nicht bedacht habe.

German hat gesagt.:
@Soapp: Für was brauchst du das eigentlich?
Eine sehr interessante Frage. Wurde Zeit, dass die mal gestellt wird.

Gruß hpvw
 
Vielleicht nicht gerade effizient, aber nur mal um zu zeigen, dass auch in PHP viele Wege nach Rom führen ;)

PHP:
<?php

$numArray = array(
	170958590,
	170958689,
	170958789,
	17095889,
	1709589,
);

$strArr = $numArray;

$numCount = count($numArray);

$lengthOfShortestNum = array_reduce(
	$numArray,
	create_function('$v,$w', 'return (strlen($w)<$v)?strlen($w):$v;'),
	100 // geschätzte Maximallänge der Nummern
);

$commonChars = $lengthOfShortestNum;

for ($i = 0; $i < $numCount; ++$i) {
	for ($j = 0; $j < $numCount; ++$j) {
		if ($i == $j) continue;
		while (strncmp($numArray[$i], $numArray[$j], $commonChars) != 0) {
			$commonChars--;
		}
	}
}

foreach ($numArray as $num) {
	echo '<b>'.substr($num, 0, $commonChars).'</b>'.substr($num, $commonChars);
	echo '<br />';
}

?>
Kommentare sind grad aus ;)
 
Zurück